1 PACKAGE BODY QRM_PA_AGGREGATION_P AS
2 /* $Header: qrmpaggb.pls 120.13 2005/09/20 11:49:16 csutaria ship $ */
3
4
5 /***************************************************************
6 This procedure determines the underlying currency of the report:
7 IF v_amount EXIST
8 IF already 1 underlying Ccy
9 IF Deals Ccy
10 Use Deals Ccy
11 IF SOB Ccy
12 Use SOB Ccy
13 IF Reporting Ccy
14 Use Rerportin Ccy
15 ELSIF Ccy is one of the aggregate attributes
16 IF Deals Ccy
17 Use Deals Ccy
18 IF SOB Ccy
19 Use SOB Ccy
20 IF Reporting Ccy
21 Use Rerportin Ccy
22 --make sure the aggregate level above the Ccy agg.
23 --cannot be Totaled
24 ELSE
25 Use Reporting Ccy
26
27 It finds the ccy aggregate lowest level and the underlying ccy.
28 It also determines the suffix '_USD' or '_SOB' to be appended
29 onto the columns names.
30 In addition, it calculates the currency multiplier in the case
31 of Reporting Ccy other than USD is used.
32 ***************************************************************/
33 PROCEDURE get_underlying_currency(p_name VARCHAR2,
34 p_ref_date DATE,
35 p_style VARCHAR2,
36 p_md_set_code VARCHAR2,
37 p_currency_source VARCHAR2,
38 p_curr_reporting VARCHAR2,
39 p_amount SYSTEM.QRM_VARCHAR_TABLE,
40 p_agg IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
41 p_ccy_aggregate IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
42 p_type IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
43 p_order IN OUT NOCOPY XTR_MD_NUM_TABLE,
44 p_ccy_suffix OUT NOCOPY VARCHAR2,
45 p_ccy_multiplier OUT NOCOPY NUMBER,
46 p_ccy_agg_flag OUT NOCOPY NUMBER,
47 p_underlying_ccy OUT NOCOPY VARCHAR2,
48 p_ccy_case_flag OUT NOCOPY NUMBER,
49 p_measure VARCHAR2,
50 p_ccy_agg_level OUT NOCOPY NUMBER,
51 --only necessary for style='T'
52 p_table_col_curr IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
53 p_agg_col_curr IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
54 p_sensitivity SYSTEM.QRM_VARCHAR_TABLE)
55 IS
56
57 v_amount_type BOOLEAN;
58 v_uniform_ccy BOOLEAN := TRUE;
59 v_count NUMBER;
60 v_meas_temp VARCHAR2(240);
61 v_temp VARCHAR2(30);
62 v_deal_currency_col VARCHAR2(30);
63 i NUMBER(5) := 0;
64 j NUMBER(5);
65 v_count_sens NUMBER;
66 v_underlying_ccy_sens VARCHAR2(30);
67
68 CURSOR check_deal_ccy IS
69 SELECT DISTINCT dc.deal_ccy
70 --or reval_ccy for FX??
71 --Felicia will copy reval_ccy to currency for FX
72 --02/05/2002
73 FROM qrm_deal_calculations dc, qrm_deals_analyses da
74 WHERE da.analysis_name=p_name
75 AND da.deal_calc_id=dc.deal_calc_id;
76 CURSOR check_sob_ccy IS
77 SELECT DISTINCT dc.sob_ccy
78 FROM qrm_deal_calculations dc, qrm_deals_analyses da
79 WHERE da.analysis_name=p_name
80 AND da.deal_calc_id=dc.deal_calc_id;
81 CURSOR check_base_ccy IS
82 SELECT DISTINCT v.base_ccy
83 FROM qrm_deal_calculations dc, qrm_deals_analyses da,
84 qrm_current_deals_v v
85 WHERE da.analysis_name=p_name
86 AND da.deal_calc_id=dc.deal_calc_id
87 AND v.deal_no=dc.deal_no
88 AND v.transaction_no=dc.transaction_no;
89 CURSOR check_contra_ccy IS
90 SELECT DISTINCT v.contra_ccy
91 FROM qrm_deal_calculations dc, qrm_deals_analyses da,
92 qrm_current_deals_v v
93 WHERE da.analysis_name=p_name
94 AND da.deal_calc_id=dc.deal_calc_id
95 AND v.deal_no=dc.deal_no
96 AND v.transaction_no=dc.transaction_no;
97 CURSOR check_buy_ccy IS
98 SELECT DISTINCT v.buy_ccy
99 FROM qrm_deal_calculations dc, qrm_deals_analyses da,
100 qrm_current_deals_v v
101 WHERE da.analysis_name=p_name
102 AND da.deal_calc_id=dc.deal_calc_id
103 AND dc.deal_no=v.deal_no
104 AND dc.transaction_no=v.transaction_no;
105 CURSOR check_sell_ccy IS
106 SELECT DISTINCT v.sell_ccy
107 FROM qrm_deal_calculations dc, qrm_deals_analyses da,
108 qrm_current_deals_v v
109 WHERE da.analysis_name=p_name
110 AND da.deal_calc_id=dc.deal_calc_id
111 AND dc.deal_no=v.deal_no
112 AND dc.transaction_no=v.transaction_no;
113 CURSOR check_foreign_ccy IS
114 SELECT DISTINCT v.foreign_ccy
115 FROM qrm_deal_calculations dc, qrm_deals_analyses da,
116 qrm_current_deals_v v
117 WHERE da.analysis_name=p_name
118 AND da.deal_calc_id=dc.deal_calc_id
119 AND dc.deal_no=v.deal_no
120 AND dc.transaction_no=v.transaction_no;
121 CURSOR check_domestic_ccy IS
122 SELECT DISTINCT v.domestic_ccy
123 FROM qrm_deal_calculations dc, qrm_deals_analyses da,
124 qrm_current_deals_v v
125 WHERE da.analysis_name=p_name
126 AND da.deal_calc_id=dc.deal_calc_id
127 AND dc.deal_no=v.deal_no
128 AND dc.transaction_no=v.transaction_no;
129 CURSOR check_sensitivity_ccy IS
130 SELECT DISTINCT v.sensitivity_ccy
131 FROM qrm_deal_calculations dc, qrm_deals_analyses da,
132 qrm_current_deals_v v
133 WHERE da.analysis_name=p_name
134 AND da.deal_calc_id=dc.deal_calc_id
135 AND dc.deal_no=v.deal_no
136 AND dc.transaction_no=v.transaction_no;
137 CURSOR get_deal_currency_col IS
138 SELECT deal_currency_col FROM qrm_ana_atts_lookups
139 WHERE attribute_name=v_meas_temp;
140
141 BEGIN
142 IF (g_proc_level>=g_debug_level) THEN
143 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.GET_UNDERLYING_CCY');
144 END IF;
145 ------------------CURRENCY LOGIC-----------------------
146 --for sensitivity can only be averaged/summed if the underlying
147 --sensitivity_ccy is uniform
148 --check only if Currency Source is not Deal Currency, coz. for
149 --Deal Currency the checking is done in the loop below.
150 IF p_style='T' AND p_currency_source<>'D' THEN
151 OPEN check_sensitivity_ccy;
152 LOOP
153 FETCH check_sensitivity_ccy INTO v_underlying_ccy_sens;
154 EXIT WHEN check_sensitivity_ccy%ROWCOUNT>2 OR check_sensitivity_ccy%NOTFOUND;
155 END LOOP;
156 v_count_sens := check_sensitivity_ccy%ROWCOUNT;
157 CLOSE check_sensitivity_ccy;
158 END IF;
159
160 --Assumption: AMOUNT type is the only measure that
161 --can only be converted to different area
162 --get the underlying currency
163 IF p_currency_source='D' THEN --Deal ccy
164 IF p_style IN('X','C') THEN
165 j := 1;
166 ELSE --style='A','T'
167 j := p_agg.COUNT;
168 END IF;
169 FOR i IN 1..j LOOP
170 IF p_style='A' THEN
171 IF p_amount(i)='Y' THEN
172 v_amount_type := TRUE;
173 v_meas_temp := p_agg(i);
174 ELSE
175 v_amount_type := FALSE;
176 END IF;
177 ELSIF p_style='T' THEN
178 v_amount_type := TRUE;
179 v_meas_temp := p_agg(i);
180 ELSE --style C,X, the check was done earlier
181 v_amount_type := TRUE;
182 v_meas_temp := p_measure;
183 END IF;
184 IF v_amount_type THEN
185 --get the deal_currency_col from qrm_ana_atts_lookups
186 OPEN get_deal_currency_col;
187 FETCH get_deal_currency_col INTO v_deal_currency_col;
188 CLOSE get_deal_currency_col;
189 IF v_deal_currency_col='BASE_CCY' THEN
190 --check for uniform deal ccy
191 OPEN check_base_ccy;
192 LOOP
193 FETCH check_base_ccy INTO p_underlying_ccy;
194 EXIT WHEN check_base_ccy%ROWCOUNT>2 OR check_base_ccy%NOTFOUND;
195 END LOOP;
196 v_count := check_base_ccy%ROWCOUNT;
197 CLOSE check_base_ccy;
198 ELSIF v_deal_currency_col='CONTRA_CCY' THEN
199 --check for uniform deal ccy
200 OPEN check_contra_ccy;
201 LOOP
202 FETCH check_contra_ccy INTO p_underlying_ccy;
203 EXIT WHEN check_contra_ccy%ROWCOUNT>2 OR check_contra_ccy%NOTFOUND;
204 END LOOP;
205 v_count := check_contra_ccy%ROWCOUNT;
206 CLOSE check_contra_ccy;
207 ELSIF v_deal_currency_col='BUY_CCY' THEN
208 --check for uniform deal ccy
209 OPEN check_buy_ccy;
210 LOOP
211 FETCH check_buy_ccy INTO p_underlying_ccy;
212 EXIT WHEN check_buy_ccy%ROWCOUNT>2 OR check_buy_ccy%NOTFOUND;
213 END LOOP;
214 v_count := check_buy_ccy%ROWCOUNT;
215 CLOSE check_buy_ccy;
216 ELSIF v_deal_currency_col='SELL_CCY' THEN
217 --check for uniform deal ccy
218 OPEN check_sell_ccy;
219 LOOP
220 FETCH check_sell_ccy INTO p_underlying_ccy;
221 EXIT WHEN check_sell_ccy%ROWCOUNT>2 OR check_sell_ccy%NOTFOUND;
222 END LOOP;
223 v_count := check_sell_ccy%ROWCOUNT;
224 CLOSE check_sell_ccy;
225 ELSIF v_deal_currency_col='FOREIGN_CCY' THEN
226 --check for uniform deal ccy
227 OPEN check_foreign_ccy;
228 LOOP
229 FETCH check_foreign_ccy INTO p_underlying_ccy;
230 EXIT WHEN check_foreign_ccy%ROWCOUNT>2 OR check_foreign_ccy%NOTFOUND;
231 END LOOP;
232 v_count := check_foreign_ccy%ROWCOUNT;
233 CLOSE check_foreign_ccy;
234 ELSIF v_deal_currency_col='DOMESTIC_CCY' THEN
235 --check for uniform deal ccy
236 OPEN check_domestic_ccy;
237 LOOP
238 FETCH check_domestic_ccy INTO p_underlying_ccy;
239 EXIT WHEN check_domestic_ccy%ROWCOUNT>2 OR check_domestic_ccy%NOTFOUND;
240 END LOOP;
241 v_count := check_domestic_ccy%ROWCOUNT;
242 CLOSE check_domestic_ccy;
243 ELSIF v_deal_currency_col='SENSITIVITY_CCY' THEN
244 --check for uniform sensitivity ccy
245 OPEN check_sensitivity_ccy;
246 LOOP
247 FETCH check_sensitivity_ccy INTO p_underlying_ccy;
248 EXIT WHEN check_sensitivity_ccy%ROWCOUNT>2 OR check_sensitivity_ccy%NOTFOUND;
249 END LOOP;
250 v_count := check_sensitivity_ccy%ROWCOUNT;
251 CLOSE check_sensitivity_ccy;
252 ELSE
253 --check for uniform deal ccy
254 OPEN check_deal_ccy;
255 LOOP
256 FETCH check_deal_ccy INTO p_underlying_ccy;
257 EXIT WHEN check_deal_ccy%ROWCOUNT>2 OR check_deal_ccy%NOTFOUND;
258 END LOOP;
259 v_count := check_deal_ccy%ROWCOUNT;
260 CLOSE check_deal_ccy;
261 END IF;
262 END IF;
263 IF p_style='A' THEN
264 --check whether 1 ccy/column
265 IF v_count>1 THEN
266 p_ccy_case_flag := 0;
267 p_underlying_ccy := NULL;
268 EXIT;
269 ELSE --put the underlying currency into the array
270 p_agg_col_curr.EXTEND;
271 p_agg_col_curr(i) := p_underlying_ccy;
272 END IF;
273 --check whether 1 underlying ccy
274 IF i>1 THEN
275 IF v_temp<>p_underlying_ccy THEN
276 v_uniform_ccy := FALSE;
277 END IF;
278 END IF;
279 v_temp := p_underlying_ccy;
280 --For Table style try to either fill in the v_table_col_curr
281 --or append the suffix to p_agg.
282 --Unlike style='A', Table style determine currency per column basis
283 ELSIF p_style='T' THEN
284 --check whether 1 ccy for the particular column
285 IF v_count>1 THEN
286 IF p_sensitivity(i)='N' THEN
287 --revert to Reporting Currency
288 p_agg(i) := p_agg(i)||'_USD';
289 --leave p_table_col_curr NULL,necessary for Spot Rate
290 --validations
291 ELSE
292 --NULL for sensitivity
293 p_agg(i) := NULL;
294 END IF;
295 ELSE --use the currency
296 p_table_col_curr(i) := p_underlying_ccy;
297 END IF;
298 END IF;
299 END LOOP;
300 --determine v_ccy_case_flag
301 IF p_style='A' THEN
302 IF p_ccy_case_flag IS NULL THEN
303 IF v_uniform_ccy THEN
304 p_ccy_case_flag := 1;--1 ccy
305 ELSE
306 p_ccy_case_flag := 2;--1 ccy/col
307 p_underlying_ccy := NULL;
308 END IF;
309 END IF;
310 ELSIF p_style IN ('C','X') THEN
311 IF v_count=1 THEN
312 p_ccy_case_flag := 1;--1 ccy
313 ELSE
314 p_ccy_case_flag := 0;-->1 ccy
315 p_underlying_ccy := NULL;
316 END IF;
317 END IF;
318 ELSIF p_currency_source='B' THEN
319 --check for uniform deal ccy
320 OPEN check_sob_ccy;
321 LOOP
322 FETCH check_sob_ccy INTO p_underlying_ccy;
323 EXIT WHEN check_sob_ccy%ROWCOUNT>2 OR check_sob_ccy%NOTFOUND;
324 END LOOP;
325 v_count := check_sob_ccy%ROWCOUNT;
326 CLOSE check_sob_ccy;
327 --For Table style try to either fill in the v_table_col_curr
328 --or append the suffix to p_agg.
329 --Unlike style='A', Table style determine currency per column basis
330 IF p_style='T' THEN
331 IF v_count=1 THEN --use SOB
332 p_ccy_suffix := '_SOB';
333 ELSE --use Reporting Currency
334 p_ccy_suffix := '_USD';
335 p_underlying_ccy := NULL;
336 END IF;
337 FOR i IN 1..p_agg.COUNT LOOP
338 IF p_sensitivity(i)='N' THEN
339 p_agg(i) := p_agg(i)||p_ccy_suffix;
340 p_table_col_curr(i) := p_underlying_ccy;
341 ELSE --sensitivity
342 IF v_count_sens>1 THEN --NULL's the p_agg(i)
343 p_agg(i) := NULL;
344 ELSE --use the currency
345 p_table_col_curr(i) := v_underlying_ccy_sens;
346 END IF;
347 END IF;
348 END LOOP;
349 ELSE --style='A','C','X'
350 IF v_count=1 THEN
351 p_ccy_case_flag := 1;
352 ELSE
353 p_ccy_case_flag := 0;
354 p_underlying_ccy := NULL;
355 END IF;
356 END IF;
357 ELSIF p_style='T' THEN --p_currency_source='R'
358 --Append Reporting Currency suffix to the p_agg
359 FOR i IN 1..p_agg.COUNT LOOP
360 IF p_sensitivity(i) = 'N' THEN
361 p_agg(i) := p_agg(i)||'_USD';
362 ELSE --sensitivity
363 IF v_count_sens>1 THEN --NULL's the p_agg(i)
364 p_agg(i) := NULL;
365 ELSE --use the currency
366 p_table_col_curr(i) := v_underlying_ccy_sens;
367 END IF;
368 END IF;
369 END LOOP;
370 END IF;
371
372 --determine p_ccy_agg_flag only necessary when >1 ccy and style<>'T'
373 --and ccy pref<>'R'
374 IF p_style<>'T' THEN
375 IF (p_ccy_case_flag<>1 AND p_currency_source<>'R') THEN
376 FOR i IN REVERSE 1..p_agg.COUNT LOOP
377 IF p_currency_source='D' THEN
378 --1 ccy/col will have p_ccy_agg_flag=0
379 --make sure only the underlying ccy is considered
380 --i.e. BUY_AMOUNT only consider BUY_CCY
381 IF p_ccy_case_flag<>2 AND p_ccy_aggregate(i)='Y'
382 AND p_agg(i)=v_deal_currency_col THEN
383 p_ccy_agg_level := p_order(i);
384 IF p_type(i)='R' THEN
385 p_ccy_agg_flag := 1;
386 p_ccy_agg_level := i;
387 EXIT;
388 ELSE --p_type(i)='C'
389 p_ccy_agg_flag := 2;
390 p_ccy_agg_level := i;
391 EXIT;
392 END IF;
393 ELSE
394 IF i=1 THEN --last interation
395 p_ccy_agg_flag := 0;
396 p_ccy_agg_level := 0;
397 END IF;
398 END IF;
399 ELSE --p_currency_source='B'
400 IF p_agg(i)='COMPANY_CODE' THEN
401 p_ccy_agg_level := p_order(i);
402 IF p_type(i)='R' THEN
403 p_ccy_agg_flag := 1;
404 p_ccy_agg_level := i;
405 EXIT;
406 ELSE --p_type(i)='C'
407 p_ccy_agg_flag := 2;
408 p_ccy_agg_level := i;
409 EXIT;
410 END IF;
411 ELSE
412 IF i=1 THEN --last iteration
413 p_ccy_agg_flag := 0;
414 p_ccy_agg_level := 0;
415 END IF;
416 END IF;
417 END IF;
418 END LOOP;
419 END IF;
420
421 --determine p_ccy_suffix=ccy pref used
422 --not necessary for Table style
423 IF (p_ccy_case_flag=0 AND p_ccy_agg_flag=0) OR p_currency_source='R' THEN
424 --revert to reporting ccy
425 p_ccy_suffix := '_USD';
426 p_underlying_ccy := p_curr_reporting;
427 ELSE --no need to revert to reporting ccy
428 IF p_currency_source='B' THEN --ccy pref=SOB
429 p_ccy_suffix := '_SOB';
430 END IF;
431 END IF;
432 END IF; --p_style<>'T'
433
434 --Find multiplier
435 IF p_curr_reporting<>'USD' THEN
436 p_ccy_multiplier := get_fx_rate(p_md_set_code,
437 p_ref_date,
438 'USD',
439 p_curr_reporting,
440 'M');
441 END IF;
442 ------------------END OF CURRENCY LOGIC----------------
443 IF (g_proc_level>=g_debug_level) THEN
444 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.GET_UNDERLYING_CCY');
445 END IF;
446 END get_underlying_currency;
447
448
449
450 /***************************************************************
451 This procedure appends suffix '_USD' or '_SOB' to the actual
452 column name to be used in the dynamic SQL.
453 ***************************************************************/
454 PROCEDURE get_actual_column_name(p_name VARCHAR2,
455 p_amount SYSTEM.QRM_VARCHAR_TABLE,
456 p_agg IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
457 p_actual_agg IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
458 p_nom_fl IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
459 p_denom_fl IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
460 p_actual_agg_usd IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
461 p_nom_fl_usd IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
462 p_denom_fl_usd IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
463 p_ccy_suffix VARCHAR2,
464 p_ccy_multiplier NUMBER,
465 p_need_usd_arr BOOLEAN,
466 p_origin IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
467 p_origin_usd IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
468 p_num_denom_origin IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
469 p_num_denom_origin_usd IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
470 p_type IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
471 p_sensitivity SYSTEM.QRM_VARCHAR_TABLE)
472 IS
473
474 i NUMBER(5);
475 v_col_name VARCHAR2(200);
476
477 CURSOR get_nom_denom IS
478 SELECT numerator,denominator,num_denom_origin
479 FROM qrm_ana_atts_lookups
480 WHERE attribute_name=v_col_name;
481 CURSOR get_origin IS
482 SELECT origin FROM qrm_ana_atts_lookups
483 WHERE attribute_name=v_col_name;
484 v_deal_type_arr SYSTEM.QRM_VARCHAR_table;
485 v_market_type_arr SYSTEM.QRM_VARCHAR_table;
486 v_count NUMBER;
487
488 BEGIN
489 IF (g_proc_level>=g_debug_level) THEN
490 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.GET_ACT_COL_NAME');
491 END IF;
492
493 p_actual_agg.EXTEND(p_agg.COUNT);
494 ----------This is for the Total ccy conversion purpose
495 --check whether we need USD ccy on backup
496 IF p_need_usd_arr THEN
497 p_actual_agg_usd.EXTEND(p_agg.COUNT);
498 p_nom_fl_usd.EXTEND(p_agg.COUNT);
499 p_denom_fl_usd.EXTEND(p_agg.COUNT);
500 p_origin_usd.EXTEND(p_agg.COUNT);
501 p_num_denom_origin_usd.EXTEND(p_agg.COUNT);
502 END IF;
503 IF (g_proc_level>=g_debug_level) THEN
504 xtr_risk_debug_pkg.dlog('get_actual_column_name: ' || 'p_nom_fl_usd.COUNT',p_nom_fl_usd.COUNT);
505 END IF;
506 ----------End This is for the Total ccy conversion purpose
507 --update col. name based on the currency conversion
508 FOR i IN 1..p_agg.COUNT LOOP
509 --Only Measure can be appended with _USD and _SOB for curr. consistency
510 --but cannot be sensitivity
511 IF p_type(i)='M' AND p_sensitivity(i)='N' THEN
512 IF p_ccy_suffix IS NOT NULL THEN
513 --need to modify p_nom_fl and p_denom_fl
514 v_col_name := p_agg(i)||p_ccy_suffix;
515 OPEN get_nom_denom;
516 FETCH get_nom_denom INTO p_nom_fl(i),p_denom_fl(i),p_num_denom_origin(i);
517 CLOSE get_nom_denom;
518 --p_nom_fl and p_denom_fl are already updated above
519 --modify the origin, bec. origin may not be the same
520 OPEN get_origin;
521 FETCH get_origin INTO p_origin(i);
522 CLOSE get_origin;
523 --need to modify the actual column name
524 --can only add ccy multiplier for amount type
525 IF p_ccy_suffix='_USD' AND p_ccy_multiplier IS NOT NULL
526 AND p_amount(i)='Y' THEN
527 --append ccy suffix and multiplier to the act. col. names
528
529 --WDK: The following code breaks NLS
530 --p_actual_agg(i) := p_agg(i)||p_ccy_suffix||'*'||TO_CHAR(p_ccy_multiplier);
531 --p_nom_fl(i) := p_nom_fl(i)||'*'||TO_CHAR(p_ccy_multiplier);
532
533 --WDK: NLS fix
534 p_actual_agg(i) := p_agg(i)||p_ccy_suffix||'*TO_NUMBER('''||TO_CHAR(p_ccy_multiplier)||''')';
535 p_nom_fl(i) := p_nom_fl(i)||'*TO_NUMBER('''||TO_CHAR(p_ccy_multiplier)||''')';
536 ELSE
537 p_actual_agg(i) := p_agg(i)||p_ccy_suffix;
538 END IF;
539 ELSE
540 p_actual_agg(i) := p_agg(i);
541 END IF;
542 ----------This is for the Total ccy conversion purpose
543 --check whether we need USD ccy on backup
544 IF p_need_usd_arr THEN
545 v_col_name := p_agg(i)||'_USD';
546 OPEN get_nom_denom;
547 FETCH get_nom_denom INTO p_nom_fl_usd(i),p_denom_fl_usd(i),p_num_denom_origin_usd(i);
548 CLOSE get_nom_denom;
549 --p_nom_fl and p_denom_fl are already updated above
550 --modify the origin, bec. origin may not be the same
551 OPEN get_origin;
552 FETCH get_origin INTO p_origin_usd(i);
553 CLOSE get_origin;
554 --need to modify the usd column name
555 --can only add ccy multiplier for amount type
556 IF p_ccy_multiplier IS NOT NULL AND p_amount(i)='Y' THEN
557 --append ccy suffix and multiplier to the act. col. names
558 --WDK: The following code breaks NLS
559 --p_actual_agg_usd(i) := p_agg(i)||'_USD*'||TO_CHAR(p_ccy_multiplier);
560 --p_nom_fl_usd(i) := p_nom_fl(i)||'*'||TO_CHAR(p_ccy_multiplier);
561 --WDK: NLS fix
562 p_actual_agg_usd(i) := p_agg(i)||'_USD*TO_NUMBER('''||TO_CHAR(p_ccy_multiplier)||''')';
563 p_nom_fl_usd(i) := p_nom_fl(i)||'*TO_NUMBER('''||TO_CHAR(p_ccy_multiplier)||''')';
564 --p_ccy_multiplier is not necessary for denom
565 p_denom_fl_usd(i) := p_denom_fl(i);
566 ELSE
567 p_actual_agg_usd(i) := p_agg(i)||'_USD';
568 --p_nom_fl and p_denom_fl are already updated above
569 END IF;
570 END IF;
571 ----------End This is for the Total ccy conversion purpose
572 ELSE
573 p_actual_agg(i) := p_agg(i);
574 END IF;
575 END LOOP;
576
577 -----------Testing
578 FOR i IN 1..p_actual_agg.COUNT LOOP
579 IF (g_proc_level>=g_debug_level) THEN
580 xtr_risk_debug_pkg.dlog('get_actual_column_name: ' || 'p_actual_agg(i)',i||':'||p_actual_agg(i));
581 END IF;
582 IF p_need_usd_arr THEN
583 IF (g_proc_level>=g_debug_level) THEN
584 xtr_risk_debug_pkg.dlog('get_actual_column_name: ' || 'p_nom_fl_usd(i)',i||':'||p_nom_fl_usd(i));
585 END IF;
586 END IF;
587 END LOOP;
588 -----------End Testing
589 IF (g_proc_level>=g_debug_level) THEN
590 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.GET_ACT_COL_NAME');
591 END IF;
592 END get_actual_column_name;
593
594
595
596 /***************************************************************
597 This procedure calculate the currency multipliers if there are
598 > 1 underlying currencies across the column aggregates.
599 The currency multipliers will then saved into an array that is
600 identical to the array used when inserting measures into
601 QRM_SAVED_ANALYSES_ROW.
602 Please refer to Bug 2566711.
603 ***************************************************************/
604 PROCEDURE get_col_ccy_multp(p_col_ccy_multp IN OUT NOCOPY XTR_MD_NUM_TABLE,
605 p_a1 IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
606 p_default_ccy VARCHAR2,
607 p_row_agg_no NUMBER,
608 p_max_col_no NUMBER,
609 p_md_set_code VARCHAR2,
610 p_ref_date DATE)
611 IS
612
613 v_prev_ccy gl_sets_of_books.currency_code%TYPE;
614 v_ccy gl_sets_of_books.currency_code%TYPE;
615 v_fx_rate NUMBER;
616
617 CURSOR get_sob_ccy (p_company_code VARCHAR2) IS
618 SELECT sob.currency_code
619 FROM gl_sets_of_books sob, xtr_party_info pinfo
620 WHERE pinfo.party_code = p_company_code AND
621 pinfo.set_of_books_id = sob.set_of_books_id;
622
623 BEGIN
624 IF (g_proc_level>=g_debug_level) THEN
625 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.GET_COL_CCY_MULTP');
626 xtr_risk_debug_pkg.dlog('get_col_ccy_multp: ' || 'p_currency_source',p_default_ccy);
627 END IF;
628
629 p_col_ccy_multp.EXTEND(p_max_col_no);
630
631 FOR i IN p_row_agg_no+1..p_a1.COUNT-1 LOOP
632 IF p_default_ccy='D' THEN --Deal ccy
633 --do some checks for optimization
634 IF p_a1(i) IS NOT NULL THEN
635 --Additional check for optimization
636 IF i>1 and p_a1(i)=p_a1(i-1) THEN
637 p_col_ccy_multp(i-p_row_agg_no) := v_fx_rate;
638 ELSE
639 v_fx_rate := get_fx_rate(p_md_set_code,
640 p_ref_date,
641 p_a1(i),
642 'USD',
643 'M');
644 p_col_ccy_multp(i-p_row_agg_no) := v_fx_rate;
645 END IF;
646 END IF;
647 ELSIF p_default_ccy='B' THEN --SOB ccy
648 --do some checks for optimization
649 IF p_a1(i) IS NOT NULL THEN
650 --Additional check for optimization
651 IF i>1 and p_a1(i)=p_a1(i-1) THEN
652 p_col_ccy_multp(i-p_row_agg_no) := v_fx_rate;
653 ELSE
654 OPEN get_sob_ccy(p_a1(i));
655 FETCH get_sob_ccy INTO v_ccy;
656 CLOSE get_sob_ccy;
657 --Additional check for optimization
658 IF v_ccy=v_prev_ccy THEN
659 p_col_ccy_multp(i-p_row_agg_no) := v_fx_rate;
660 ELSE
661 v_fx_rate := get_fx_rate(p_md_set_code,
662 p_ref_date,
663 p_a1(i),
664 'USD',
665 'M');
666 p_col_ccy_multp(i-p_row_agg_no) := v_fx_rate;
667 v_prev_ccy := v_ccy;
668 END IF;
669 END IF;
670 END IF;
671 END IF;
672 IF (g_proc_level>=g_debug_level) THEN
673 xtr_risk_debug_pkg.dlog('get_col_ccy_multp: ' || 'i:p_a1',i||':'||p_a1(i));
674 xtr_risk_debug_pkg.dlog('get_col_ccy_multp: ' || 'v_fx_rate',v_fx_rate);
675 xtr_risk_debug_pkg.dlog('i:p_col_ccy_multp',i||':'||p_col_ccy_multp(i-p_row_agg_no));
676 END IF;
677 END LOOP;
678
679 IF (g_proc_level>=g_debug_level) THEN
680 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.GET_COL_CCY_MULTP');
681 END IF;
682 END get_col_ccy_multp;
683
684
685
686 /***************************************************************
687 This function updates the columns' totals in the case of Crosstab
688 style with different underlying currencies for different columns.
689 Please refer to Bug 2566711.
690 ***************************************************************/
691 FUNCTION calc_col_total(p_col_ccy_multp IN OUT NOCOPY XTR_MD_NUM_TABLE,
692 p_measure IN OUT NOCOPY XTR_MD_NUM_TABLE,
693 p_max_col_no NUMBER,
694 p_ccy_case_flag NUMBER,
695 p_ccy_agg_flag NUMBER,
696 p_max_col_agg_level NUMBER)
697 RETURN NUMBER IS
698
699 v_total NUMBER := 0;
700 v_temp_meas XTR_MD_NUM_TABLE := XTR_MD_NUM_TABLE();
701 v_null BOOLEAN := TRUE;
702
703 BEGIN
704
705 v_temp_meas.EXTEND(p_measure.COUNT);
706
707 --do simple stuffs for 1 level column aggregate
708 IF p_max_col_agg_level=1 THEN
709 --only need to do extra if columns has different currencies
710 IF p_ccy_case_flag=0 and p_ccy_agg_flag=2 and p_max_col_no-1>1 THEN
711 FOR i IN 1..p_measure.COUNT-1 LOOP
712 IF p_measure(i) IS NOT NULL and p_col_ccy_multp(i) is not null
713 THEN
714 v_total := v_total + p_measure(i)*p_col_ccy_multp(i);
715 v_null := FALSE;
716 END IF;
717 END LOOP;
718 END IF;
719 ELSE
720 NULL;
721 --put in similar totaling logic to the one for
722 --QRM_SAVED_ANALYSES_ROW
723 END IF;
724
725 IF v_null THEN
726 v_total := NULL;
727 END IF;
728
729 RETURN v_total;
730
731 END calc_col_total;
732
733
734
735 /***************************************************************
736 This procedure insert 1 row at a time to qrm_saved_analyses_row
737 called when looping through the main cursor. Cannot do bulk insert
738 without initializing 100 arrays, thus, static insert per row basis
739 is the next viable option.
740 ***************************************************************/
741 FUNCTION insert_row(sh IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
742 sm IN OUT NOCOPY XTR_MD_NUM_TABLE,
743 p_row_agg_no NUMBER,
744 p_max_col_no NUMBER,
745 p_name VARCHAR2,
746 p_row NUMBER,
747 p_type NUMBER,
748 p_hidden VARCHAR2,
749 p_tot_currency VARCHAR2,
750 p_style VARCHAR2,
751 p_ref_date DATE,
752 p_ccy_case_flag NUMBER,
753 p_ccy_agg_flag NUMBER,
754 p_col_ccy_multp IN OUT NOCOPY XTR_MD_NUM_TABLE)
755 RETURN BOOLEAN IS
756
757 v_tot_currency VARCHAR2(20);
758 v_tot_currency_label VARCHAR2(25);
759 v_null BOOLEAN := TRUE;
760 -----Testing purposes
761 v_test VARCHAR2(4096); --WDK: this limit increased
762 -----End
763
764 BEGIN
765
766 IF (g_proc_level>=g_debug_level) THEN
767 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.INSERT_ROW');
768 END IF;
769
770 ---------Should be removed if multiple level columns is implemented
771 --If multiple col level is implemented, replace this with
772 --a function that transfer the value of the 'sm' array to a new array
773 --while inserting and calculating Total whenever necessary.
774 --Equivalent to the process for the row.
775 --calculate end column total
776 sm(p_max_col_no) := 0;
777 IF p_style<>'A' THEN
778
779 ----Start Bug 2566711
780 IF p_style='C' and p_ccy_case_flag=0 and p_ccy_agg_flag=2
781 and p_max_col_no-1>1 THEN
782 sm(p_max_col_no) := calc_col_total(p_col_ccy_multp,
783 sm,
784 p_max_col_no,
785 p_ccy_case_flag,
786 p_ccy_agg_flag,
787 1);
788 IF sm(p_max_col_no) IS NULL THEN
789 v_null := TRUE;
790 ELSE
791 v_null := FALSE;
792 END IF;
793 ----End Bug 2566711
794
795 ELSE
796 FOR i IN 1..p_max_col_no-1 LOOP
797 IF sm(i) IS NOT NULL THEN
798 sm(p_max_col_no):=sm(p_max_col_no)+sm(i);
799 v_null := FALSE;
800 END IF;
801 END LOOP;
802 END IF;
803 ELSE -- style=A cannot TOTAL at the end
804 sm(p_max_col_no) := NULL;
805 END IF;
806 --if all columns are null then make TOTAL null
807 IF v_null THEN
808 sm(p_max_col_no) := NULL;
809 END IF;
810 -------------------------------------------------------------------
811
812 ------------------Testing purpose
813 FOR j IN 1..p_row_agg_no+p_max_col_no LOOP
814 --WDK: v_test is only 4096 characters big. if bigger than that then do not want
815 --to error out, so dump contents and continue
816 IF (length(v_test)>4000) THEN
817 IF (g_proc_level>=g_debug_level) THEN
818 xtr_risk_debug_pkg.dlog('insert_row: ' || '',p_row||':'||v_test);
819 END IF;
820 v_test:='';
821 END IF;
822 IF j <= p_row_agg_no THEN
823 v_test := v_test||':'||sh(j);
824 ELSE
825 v_test := v_test||':'||sm(j-p_row_agg_no);
826 END IF;
827 END LOOP;
828 IF (g_proc_level>=g_debug_level) THEN
829 xtr_risk_debug_pkg.dlog('insert_row: ' || '',p_row||':'||v_test);
830 END IF;
831 ------------------End Testing purpose
832
833 --format the tot, ccy to be append-ready (for now formatting is done in SQL)
834 IF p_tot_currency IS NOT NULL THEN
835 v_tot_currency_label := ' ('||p_tot_currency||')';
836 v_tot_currency := p_tot_currency;
837 END IF;
838
839 IF p_row_agg_no<=5 AND p_max_col_no<=20 THEN
840 IF sh.COUNT<5 THEN
841 sh.EXTEND(5-p_row_agg_no);
842 END IF;
843 IF sm.COUNT<20 THEN
844 sm.EXTEND(20-p_max_col_no);
845 END IF;
846 INSERT INTO qrm_saved_analyses_row(analysis_name,seq_no,type,hidden,
847 tot_currency,tot_currency_label,a1,a2,a3,a4,a5,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,
848 m16,m17,m18,m19,m20,created_by,creation_date,last_updated_by,last_update_date,
849 last_update_login)
850 VALUES(p_name,p_row,p_type,p_hidden,v_tot_currency,v_tot_currency_label,
851 sh(1),sh(2),sh(3),sh(4),
852 sh(5),sm(1),sm(2),sm(3),sm(4),sm(5),sm(6),sm(7),sm(8),sm(9),sm(10),sm(11),
853 sm(12),sm(13),sm(14),sm(15),sm(16),sm(17),sm(18),sm(19),sm(20),
854 FND_GLOBAL.user_id,p_ref_date,FND_GLOBAL.user_id,p_ref_date,
855 FND_GLOBAL.login_id);
856
857 ELSIF p_row_agg_no<=10 AND p_max_col_no<=50 THEN
858 IF sh.COUNT<10 THEN
859 sh.EXTEND(10-p_row_agg_no);
860 END IF;
861 IF sm.COUNT<50 THEN
862 sm.EXTEND(50-p_max_col_no);
863 END IF;
864 INSERT INTO qrm_saved_analyses_row(analysis_name,seq_no,type,hidden,
865 tot_currency,tot_currency_label,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,m1,m2,m3,m4,
866 m5,m6,m7,m8,m9,m10,m11,
867 m12,m13,m14,m15,m16,m17,m18,m19,m20,m21,m22,m23,m24,m25,m26,m27,m28,m29,m30,
868 m31,m32,m33,m34,m35,m36,m37,m38,m39,m40,m41,m42,m43,m44,m45,m46,m47,m48,m49,
869 m50,created_by,creation_date,last_updated_by,last_update_date,
870 last_update_login)
871 VALUES(p_name,p_row,p_type,p_hidden,v_tot_currency,v_tot_currency_label,
872 sh(1),sh(2),sh(3),sh(4),
873 sh(5),sh(6),sh(7),sh(8),sh(9),sh(10),sm(1),sm(2),sm(3),sm(4),sm(5),sm(6),sm(7),
874 sm(8),sm(9),sm(10),sm(11),sm(12),sm(13),sm(14),sm(15),sm(16),sm(17),sm(18),
875 sm(19),sm(20),sm(21),sm(22),sm(23),sm(24),sm(25),sm(26),sm(27),sm(28),sm(29),
876 sm(30),sm(31),sm(32),sm(33),sm(34),sm(35),sm(36),sm(37),sm(38),sm(39),sm(40),
877 sm(41),sm(42),sm(43),sm(44),sm(45),sm(46),sm(47),sm(48),sm(49),sm(50),
878 FND_GLOBAL.user_id,p_ref_date,FND_GLOBAL.user_id,p_ref_date,
879 FND_GLOBAL.login_id);
880
881 ELSE --p_row_agg_no<=16 AND p_max_col_no<=100
882 IF sh.COUNT<16 THEN
883 sh.EXTEND(16-p_row_agg_no);
884 END IF;
885 IF sm.COUNT<100 THEN
886 sm.EXTEND(100-p_max_col_no);
887 END IF;
888 INSERT INTO qrm_saved_analyses_row(analysis_name,seq_no,type,hidden,
889 tot_currency,tot_currency_label,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,
890 a14,a15,a16,m1,m2,m3,
891 m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,m18,m19,m20,m21,m22,m23,m24,
892 m25,m26,m27,m28,m29,m30,m31,m32,m33,m34,m35,m36,m37,m38,m39,m40,m41,m42,m43,
893 m44,m45,m46,m47,m48,m49,m50,m51,m52,m53,m54,m55,m56,m57,m58,m59,m60,m61,m62,
894 m63,m64,m65,m66,m67,m68,m69,m70,m71,m72,m73,m74,m75,m76,m77,m78,m79,m80,m81,
895 m82,m83,m84,m85,m86,m87,m88,m89,m90,m91,m92,m93,m94,m95,m96,m97,m98,m99,m100,
896 created_by,creation_date,last_updated_by,last_update_date,last_update_login)
897 VALUES(p_name,p_row,p_type,p_hidden,v_tot_currency,v_tot_currency_label,
898 sh(1),sh(2),sh(3),sh(4),
899 sh(5),sh(6),sh(7),sh(8),sh(9),sh(10),sh(11),sh(12),sh(13),sh(14),sh(15),sh(16),
900 sm(1),sm(2),sm(3),sm(4),sm(5),sm(6),sm(7),sm(8),sm(9),sm(10),sm(11),sm(12),
901 sm(13),sm(14),sm(15),sm(16),sm(17),sm(18),sm(19),sm(20),sm(21),sm(22),sm(23),
902 sm(24),sm(25),sm(26),sm(27),sm(28),sm(29),sm(30),sm(31),sm(32),sm(33),sm(34),
903 sm(35),sm(36),sm(37),sm(38),sm(39),sm(40),sm(41),sm(42),sm(43),sm(44),sm(45),
904 sm(46),sm(47),sm(48),sm(49),sm(50),sm(51),sm(52),sm(53),sm(54),sm(55),sm(56),
905 sm(57),sm(58),sm(59),sm(60),sm(61),sm(62),sm(63),sm(64),sm(65),sm(66),sm(67),
906 sm(68),sm(69),sm(70),sm(71),sm(72),sm(73),sm(74),sm(75),sm(76),sm(77),sm(78),
907 sm(79),sm(80),sm(81),sm(82),sm(83),sm(84),sm(85),sm(86),sm(87),sm(88),sm(89),
908 sm(90),sm(91),sm(92),sm(93),sm(94),sm(95),sm(96),sm(97),sm(98),sm(99),sm(100),
909 FND_GLOBAL.user_id,p_ref_date,FND_GLOBAL.user_id,p_ref_date,
910 FND_GLOBAL.login_id);
911 END IF;
912
913 IF (g_event_level>=g_debug_level) THEN --bug 3236479
914 XTR_RISK_DEBUG_PKG.dlog('DML','Inserted into QRM_SAVED_ANALYSES_ROW',
915 'QRM_PA_AGGREGATION_P.INSERT_ROW',g_event_level);
916 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.INSERT_ROW');
917 END IF;
918
919 RETURN TRUE;
920 EXCEPTION
921 WHEN OTHERS THEN
922 IF (g_ERROR_level>=g_debug_level) THEN
923 xtr_risk_debug_pkg.dlog('EXCEPTION','UNEXPECTED',
924 'QRM_PA_AGGREGATION_P.INSERT_ROW',G_ERROR_LEVEL);
925 END IF;
926 RETURN FALSE;
927 END insert_row;
928
929
930
931 /***************************************************************
932 This procedure constructs dynamic SQL statement that does the
933 aggregation.
934 ***************************************************************/
935 PROCEDURE create_cursor (p_name VARCHAR2,
936 p_style VARCHAR2,
937 p_analysis_type VARCHAR2,
938 p_agg IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
939 p_type IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
940 p_nom IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
941 p_denom IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
942 p_tot_avg SYSTEM.QRM_VARCHAR_TABLE,
943 p_sql OUT NOCOPY VARCHAR2,
944 p_sql_col OUT NOCOPY VARCHAR2,
945 p_row_agg_no OUT NOCOPY NUMBER,
946 p_measure_no IN OUT NOCOPY NUMBER,
947 p_origin IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
948 p_tb_calc_used IN OUT NOCOPY BOOLEAN,
949 p_tb_calc_used_col IN OUT NOCOPY BOOLEAN,
950 p_need_usd_arr BOOLEAN,
951 p_ccy_suffix VARCHAR2,
952 p_ccy_multiplier NUMBER,
953 p_amount SYSTEM.QRM_VARCHAR_TABLE,
954 p_table_col_curr IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
955 p_num_denom_origin IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
956 p_curr_reporting VARCHAR2,
957 p_sensitivity SYSTEM.QRM_VARCHAR_TABLE) IS
958
959 --IMPORTANT: v_act_agg include multiplier
960 v_act_agg SYSTEM.QRM_VARCHAR240_TABLE := SYSTEM.QRM_VARCHAR240_TABLE();
961 v_agg_usd SYSTEM.QRM_VARCHAR240_TABLE := SYSTEM.QRM_VARCHAR240_TABLE();
962 v_origin_usd SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
963 v_nom_fl_usd SYSTEM.QRM_VARCHAR240_TABLE := SYSTEM.QRM_VARCHAR240_TABLE();
964 v_denom_fl_usd SYSTEM.QRM_VARCHAR240_TABLE := SYSTEM.QRM_VARCHAR240_TABLE();
965 v_num_denom_origin_usd SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
966 v_from VARCHAR2(100):=' FROM qrm_deal_calculations dc,qrm_deals_analyses da,qrm_current_deals_v v';
967 v_where VARCHAR2(255):=' WHERE da.deal_calc_id=dc.deal_calc_id AND da.analysis_name=:analysis_name AND dc.deal_no=v.deal_no AND dc.transaction_no=v.transaction_no';
968 i NUMBER(5);
969 j NUMBER(5);
970 v_aggregate_level NUMBER(5);
971 --whether qrm_saved_analyses_col is used or not
972 v_col_used BOOLEAN := FALSE;
973 --whether qrm_deal_calculations is used or not for p_sql_col
974 v_table_used_col BOOLEAN := FALSE;
975 v_origin VARCHAR2(1);
976 v_col_name VARCHAR2(200);
977 --Special indicators to treat DEAL_SUBTYPE
978 v_deal_subtype BOOLEAN := FALSE;
979 v_deal_subtype_col BOOLEAN := FALSE;
980 v_where_col VARCHAR2(255);
981
982 BEGIN
983 IF (g_proc_level>=g_debug_level) THEN
984 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.CREATE_CURSOR');
985 END IF;
986
987 --call get_actual_column_name proc
988 IF p_style<>'T' THEN
989 get_actual_column_name(p_name,p_amount,p_agg,v_act_agg,
990 p_nom,p_denom,v_agg_usd,
991 v_nom_fl_usd,v_denom_fl_usd,p_ccy_suffix,
992 p_ccy_multiplier,p_need_usd_arr,p_origin,v_origin_usd,
993 p_num_denom_origin,v_num_denom_origin_usd,
994 p_type, p_sensitivity);
995 ELSE
996 --for style='T', the p_agg already contains the actual att. name
997 --hence just need to append ccy multiplier and copy them to v_act_agg
998 v_act_agg.EXTEND(p_agg.COUNT);
999 FOR i IN 1..p_agg.COUNT LOOP
1000 --NULL in p_table_col_curr means that it 's converted to
1001 --Reporting Currency.
1002 --Those are the one that we need to attach multiplier on.
1003 v_act_agg(i) := p_agg(i);
1004 IF p_table_col_curr(i) IS NULL THEN
1005 --NULL means value is converted to reporting currency
1006 p_table_col_curr(i) := p_curr_reporting;
1007 IF (g_proc_level>=g_debug_level) THEN
1008 xtr_risk_debug_pkg.dlog('create_cursor: ' || 'p_ccy_multiplier',p_ccy_multiplier);
1009 END IF;
1010 --ccy multiplier only applicable to amount type
1011 IF p_ccy_multiplier IS NOT NULL AND p_amount(i)='Y' THEN
1012 v_act_agg(i) := v_act_agg(i)||'*TO_NUMBER('''||p_ccy_multiplier||''')';
1013 p_nom(i) := p_nom(i)||'*TO_NUMBER('''||p_ccy_multiplier||''')';
1014 END IF;
1015 END IF;
1016 END LOOP;
1017 END IF;
1018 -----------Testing
1019 FOR i IN 1..v_act_agg.COUNT LOOP
1020 IF (g_proc_level>=g_debug_level) THEN
1021 xtr_risk_debug_pkg.dlog('create_cursor: ' || 'v_act_agg(i)',i||':'||v_act_agg(i));
1022 END IF;
1023 END LOOP;
1024 -----------End Testing
1025
1026 --see whether we need join with qrm_save_analyses_col or not
1027 --style Crosstab Timebuckets and Crosstab need to join
1028 IF p_style IN ('C','X') THEN
1029 v_col_used := TRUE;
1030 END IF;
1031 --need to construct p_sql_col for style='C'
1032 IF p_style='C' THEN
1033 p_sql_col := 'SELECT DISTINCT ';
1034 END IF;
1035 p_sql := 'SELECT ';
1036
1037 FOR j IN 1..v_act_agg.COUNT LOOP
1038 --for cross-tab and aggregated-table
1039 --IF (p_style='C') OR (p_style='A') THEN
1040 IF (g_proc_level>=g_debug_level) THEN
1041 xtr_risk_debug_pkg.dlog('create_cursor: ' || 'j:v_act_agg(j)',j||':'||v_act_agg(j));
1042 xtr_risk_debug_pkg.dlog('create_cursor: ' || 'j:p_type(j)',j||':'||p_type(j));
1043 END IF;
1044 IF p_type(j)='R' THEN
1045 --check whether att. is from table or view
1046 IF p_origin(j)='T' THEN
1047 p_sql := p_sql||'dc.'||v_act_agg(j);
1048 ELSIF p_origin(j)='V' THEN
1049 --check for deal_subtype
1050 --SELECT dst.user_deal_subtype deal_subtype
1051 IF v_act_agg(j)='DEAL_SUBTYPE' THEN
1052 p_sql := p_sql||'dst.user_deal_subtype '||v_act_agg(j);
1053 v_deal_subtype := TRUE;
1054 ELSE
1055 p_sql := p_sql||'v.'||v_act_agg(j);
1056 END IF;
1057 ELSE --IF p_origin(j)='B'
1058 p_sql := p_sql||'tb.'||v_act_agg(j);
1059 p_tb_calc_used := TRUE;
1060 END IF;
1061
1062 --find the aggregate level, if the next aggregate is of type M
1063 IF p_type(j+1)<>'R' THEN
1064 p_row_agg_no := j;
1065 IF p_style='A' THEN
1066 v_aggregate_level := j;
1067 END IF;
1068 END IF;
1069 --xtr_risk_debug_pkg.dlog('p_row_agg_no',p_row_agg_no);
1070 --if style = X and the next one is Measure then v_aggregate_level=j
1071 IF p_style='X' AND p_type(j+1)='M' THEN
1072 p_sql := p_sql||',c.seq_no';
1073 v_aggregate_level := j;
1074 END IF;
1075
1076 ELSIF p_type(j)='C' THEN --only style=C has type=C
1077 p_sql := p_sql||'c.seq_no';
1078 --dynamic sql for column header
1079 --check whether att. is from table or view
1080 IF p_origin(j)='T' THEN
1081 p_sql_col := p_sql_col||'dc.'||v_act_agg(j);
1082 v_table_used_col := TRUE;
1083 --exclude the null value
1084 v_where_col := v_where_col||' AND dc.'||v_act_agg(j)||' IS NOT NULL';
1085 ELSIF p_origin(j)='V' THEN
1086 --check for deal_subtype
1087 --SELECT dst.user_deal_subtype deal_subtype
1088 IF v_act_agg(j)='DEAL_SUBTYPE' THEN
1089 p_sql_col := p_sql_col||'dst.user_deal_subtype '||v_act_agg(j);
1090 v_deal_subtype := TRUE;
1091 v_deal_subtype_col := TRUE;
1092 ELSE
1093 p_sql_col := p_sql_col||'v.'||v_act_agg(j);
1094 END IF;
1095 --exclude the null value
1096 v_where_col := v_where_col||' AND v.'||v_act_agg(j)||' IS NOT NULL';
1097 ELSE --IF p_origin(j)='B'
1098 --xtr_risk_debug_pkg.dlog('C->B: v_act_agg(j)',v_act_agg(j));
1099 p_sql_col := p_sql_col||'tb.'||v_act_agg(j);
1100 p_tb_calc_used := TRUE;
1101 p_tb_calc_used_col := TRUE;
1102 --exclude the null value
1103 v_where_col := v_where_col||' AND tb.'||v_act_agg(j)||' IS NOT NULL';
1104 END IF;
1105
1106 --find the aggregate level, if the next aggregate is of type M
1107 --if so then we found the no. of aggregate level
1108 IF p_type(j+1)='M' THEN
1109 v_aggregate_level := j;
1110 END IF;
1111
1112 --p_type(j)='M' AND
1113 ELSIF v_act_agg(j) IN ('NUMBER_DEALS','NUMBER_DEALS_USD','NUMBER_DEALS_SOB') THEN
1114 --this attribute calculate the number of deals aggregated/displayed
1115 IF p_style='T' THEN --just put 1 bec. 1 row represent 1 deal
1116 p_sql := p_sql||'1,NULL';
1117 ELSE
1118 p_sql := p_sql||'COUNT(*),NULL';
1119 END IF;
1120 p_measure_no := p_measure_no+2;
1121 IF p_need_usd_arr THEN
1122 p_sql := p_sql||',NULL,NULL';
1123 p_measure_no := p_measure_no+2;
1124 END IF;
1125
1126 --p_type(j)='M' AND
1127 --xtr_risk_debug_pkg.dlog('M->T: j:v_act_agg,p_origin,p_tot_avg=',j||':'||v_act_agg(j)||','||p_origin(j)||','||p_tot_avg(j));
1128 ELSIF v_act_agg(j) IS NOT NULL AND p_tot_avg(j)='T' THEN
1129 IF p_origin(j)='T' THEN
1130 p_sql := p_sql||'SUM(dc.'||v_act_agg(j)||'),NULL';
1131 ELSIF p_origin(j)='V' THEN
1132 p_sql := p_sql||'SUM(v.'||v_act_agg(j)||'),NULL';
1133 ELSE --IF p_origin(j)='B'
1134 p_sql := p_sql||'SUM(tb.'||v_act_agg(j)||'),NULL';
1135 p_tb_calc_used := TRUE;
1136 END IF;
1137 p_measure_no := p_measure_no+2;
1138 --if style = X then v_aggregate_level=j-1
1139 IF p_need_usd_arr THEN
1140 --first find the origin bec. col+'_usd' may be different from
1141 --the original
1142 v_col_name := v_act_agg(j)||'_USD';
1143 --xtr_risk_debug_pkg.dlog('M->T: v_col_name=',v_col_name);
1144 --xtr_risk_debug_pkg.dlog('M->T: v_origin=',v_origin);
1145 --xtr_risk_debug_pkg.dlog('M->T: v_origin_usd(j)=',v_origin_usd(j));
1146 --xtr_risk_debug_pkg.dlog('M->T: v_agg_usd(j)=',v_agg_usd(j));
1147 IF v_origin_usd(j)='T' THEN
1148 p_sql := p_sql||',SUM(dc.'||v_agg_usd(j)||'),NULL';
1149 ELSIF v_origin_usd(j)='V' THEN
1150 p_sql := p_sql||',SUM(v.'||v_agg_usd(j)||'),NULL';
1151 ELSE --IF v_origin_usd(j)='B'
1152 p_sql := p_sql||',SUM(tb.'||v_agg_usd(j)||'),NULL';
1153 p_tb_calc_used := TRUE;
1154 END IF;
1155 p_measure_no := p_measure_no+2;
1156 END IF;
1157 --xtr_risk_debug_pkg.dlog('p_measure_no',p_measure_no);
1158 --p_type(j)='M' AND
1159 ELSIF v_act_agg(j) IS NOT NULL AND p_tot_avg(j)='A' THEN
1160 --xtr_risk_debug_pkg.dlog('M->A: v_act_agg',v_act_agg(j));
1161 IF p_nom(j) IS NULL THEN
1162 p_nom(j) := 'NULL';
1163 END IF;
1164 IF p_denom(j) IS NULL THEN
1165 p_denom(j) := 'NULL';
1166 END IF;
1167 p_sql := p_sql||p_nom(j)||','||p_denom(j);
1168 IF p_num_denom_origin(j) IN ('2','3') THEN
1169 p_tb_calc_used := TRUE;
1170 END IF;
1171 p_measure_no := p_measure_no+2;
1172 --if style = X then v_aggregate_level=j-1
1173 --xtr_risk_debug_pkg.dlog('j,v_nom_fl_usd.COUNT',j||','||v_nom_fl_usd.COUNT);
1174 IF p_need_usd_arr THEN
1175 --xtr_risk_debug_pkg.dlog('M->T: v_nom_fl_usd(j)=',v_nom_fl_usd(j));
1176 IF v_nom_fl_usd(j) IS NULL THEN
1177 v_nom_fl_usd(j) := 'NULL';
1178 END IF;
1179 --xtr_risk_debug_pkg.dlog('M->T: v_denom_fl_usd(j)=',v_denom_fl_usd(j));
1180 IF v_denom_fl_usd(j) IS NULL THEN
1181 v_denom_fl_usd(j) := 'NULL';
1182 END IF;
1183 p_sql := p_sql||','||v_nom_fl_usd(j)||','||v_denom_fl_usd(j);
1184 IF v_num_denom_origin_usd(j) IN ('2','3') THEN
1185 p_tb_calc_used := TRUE;
1186 END IF;
1187 p_measure_no := p_measure_no+2;
1188 END IF;
1189 ELSE
1190 p_sql := p_sql||'NULL,NULL';
1191 p_measure_no := p_measure_no+2;
1192 END IF;
1193 --add comma unless the end of SELECT clause
1194 IF j < v_act_agg.COUNT THEN
1195 p_sql := p_sql||',';
1196 END IF;
1197 END LOOP; --v_act_agg LOOP
1198
1199 --Construct p_sql_col
1200 IF p_style='C' THEN
1201 --add BULK COLLECT clause for p_sql_col
1202 j := 0;
1203 p_sql_col := p_sql_col||' BULK COLLECT INTO ';
1204 FOR i IN 1..v_aggregate_level LOOP
1205 IF p_type(i)='C' THEN
1206 j := j+1;
1207 IF j>1 THEN
1208 p_sql_col := p_sql_col||',';
1209 END IF;
1210 p_sql_col := p_sql_col||':'||TO_CHAR(j);
1211 END IF;
1212 END LOOP;
1213
1214 --add FROM clause for p_sql_col
1215 p_sql_col := p_sql_col||v_from;
1216 IF p_tb_calc_used_col THEN
1217 p_sql_col := p_sql_col||',qrm_tb_calculations tb';
1218 END IF;
1219 --FROM ...,xtr_deal_subtypes dst
1220 IF v_deal_subtype_col THEN
1221 p_sql_col := p_sql_col||',xtr_deal_subtypes dst';
1222 END IF;
1223
1224 --add WHERE clause for p_sql_col
1225 p_sql_col := p_sql_col||v_where||v_where_col;
1226 IF p_tb_calc_used_col THEN
1227 --p_sql_col := p_sql_col||' AND dc.deal_no=tb.deal_no AND dc.transaction_no=tb.transaction_no'; --bug 2550158
1228 p_sql_col := p_sql_col||' AND dc.deal_no=tb.deal_no AND dc.transaction_no=tb.transaction_no AND dc.market_data_set = tb.market_data_set'; --bug 2550158
1229 IF p_analysis_type='P' THEN
1233 p_sql_col := p_sql_col||' AND (tb.start_date IS NULL OR NVL(dc.gap_date,:ref_date+1)>=tb.start_date) AND NVL(dc.gap_date,:ref_date+1)<=tb.end_date';--bug 2638277
1230 --Bug 2318165 no.7
1231 p_sql_col := p_sql_col||' AND (tb.pos_start_date IS NULL OR :end_date>=tb.pos_start_date) AND (tb.pos_end_date IS NULL OR :end_date<tb.pos_end_date)'; --bug 3085258
1232 ELSIF p_analysis_type='G' THEN
1234 --p_sql_col := p_sql_col||' AND (tb.start_date IS NULL OR NVL(dc.gap_date,:ref_date+1)>=tb.start_date) AND NVL(dc.gap_date,:ref_date+1)<tb.end_date';--bug 2638277
1235 ELSE --p_analysis_type='M' THEN
1236 --p_sql_col := p_sql_col||' AND (tb.start_date IS NULL OR NVL(v.end_date,:ref_date+1)>=tb.start_date) AND NVL(v.end_date,:ref_date+1)<tb.end_date';
1237 --bug 2637950
1238 p_sql_col := p_sql_col||' AND ((v.start_date>=(:ref_date+1) AND NVL(v.end_date,v.start_date+1)>=tb.start_date AND NVL(v.end_date,v.start_date+1)<=tb.end_date)'||
1239 ' OR (v.start_date< (:ref_date+1) AND NVL(v.end_date,:ref_date+1)>=tb.start_date AND NVL(v.end_date,:ref_date+1)<=tb.end_date))';
1240 END IF;
1241 END IF;
1242 --WHERE ... AND dst.deal_subtype=v.deal_subtype
1243 IF v_deal_subtype_col THEN
1244 p_sql_col := p_sql_col||' AND dst.deal_subtype=v.deal_subtype';
1245 END IF;
1246
1247 --add ORDER BY clause for p_sql_col
1248 j := 0;
1249 p_sql_col := p_sql_col||' ORDER BY ';
1250 FOR i IN 1..v_aggregate_level LOOP
1251 IF p_type(i)='C' THEN
1252 j := j+1;
1253 IF j>1 THEN
1254 p_sql_col := p_sql_col||',';
1255 END IF;
1256 p_sql_col := p_sql_col||TO_CHAR(j);
1257 END IF;
1258 END LOOP;
1259 p_sql_col := p_sql_col||';';
1260 END IF;
1261
1262 --add FROM clause
1263 p_sql := p_sql||v_from;
1264 IF v_col_used THEN
1265 p_sql := p_sql||','||'qrm_saved_analyses_col c';
1266 END IF;
1267 IF p_tb_calc_used THEN
1268 p_sql := p_sql||','||'qrm_tb_calculations tb';
1269 END IF;
1270 --FROM ...,xtr_deal_subtypes dst
1271 IF v_deal_subtype THEN
1272 p_sql := p_sql||',xtr_deal_subtypes dst';
1273 END IF;
1274
1275 --add WHERE clause
1276 p_sql := p_sql||v_where;
1277 IF v_col_used THEN
1278 p_sql := p_sql||' AND c.analysis_name=da.analysis_name';
1279 --
1280 IF p_style='C' THEN
1281 p_sql := p_sql||' AND c.seq_no_key=';
1282 FOR j IN 1..v_aggregate_level LOOP
1283 IF p_type(j)='C' THEN
1284 --check whether att. is from table or view
1285 IF p_origin(j)='T' THEN
1286 p_sql := p_sql||'dc.'||v_act_agg(j);
1287 ELSIF p_origin(j)='V' THEN
1288 IF v_deal_subtype_col THEN
1289 p_sql := p_sql||'dst.user_deal_subtype';
1290 ELSE
1291 p_sql := p_sql||'v.'||v_act_agg(j);
1292 END IF;
1293 ELSE --p_origin(j)='B' THEN
1294 p_sql := p_sql||'tb.'||v_act_agg(j);
1295 END IF;
1296 END IF;
1297 END LOOP;
1298 END IF;
1299 END IF;
1300 IF p_style='X' AND p_analysis_type='P' THEN
1301 p_sql := p_sql||' AND v.deal_date<=c.end_date AND (v.end_date IS NULL OR c.end_date<=v.end_date)';
1302 ELSIF p_style='X' AND p_analysis_type='G' THEN
1303 p_sql := p_sql||' AND NVL(dc.gap_date,:ref_date+1)>=c.start_date AND NVL(dc.gap_date,:ref_date+1)<=c.end_date';--bug 2638277
1304 --p_sql := p_sql||' AND NVL(dc.gap_date,:ref_date+1)>=c.start_date AND NVL(dc.gap_date,:ref_date+1)<c.end_date';--bug 2638277
1305 ELSIF p_style='X' AND p_analysis_type='M' THEN
1306 --p_sql := p_sql||' AND c.start_date<=NVL(v.end_date,:ref_date+1) AND NVL(v.end_date,:ref_date+1)<c.end_date';
1307 --bug 2637950
1308 p_sql := p_sql||' AND ((v.start_date>=(:ref_date+1) AND NVL(v.end_date,v.start_date+1)>=c.start_date AND NVL(v.end_date,v.start_date+1)<=c.end_date)'||
1309 ' OR (v.start_date< (:ref_date+1) AND NVL(v.end_date,:ref_date+1)>=c.start_date AND NVL(v.end_date,:ref_date+1)<=c.end_date))';
1310 END IF;
1311 IF p_tb_calc_used THEN
1312 --p_sql := p_sql||' AND dc.deal_no=tb.deal_no AND dc.transaction_no=tb.transaction_no'; --bug 2550158
1313 p_sql := p_sql||' AND dc.deal_no=tb.deal_no AND dc.transaction_no=tb.transaction_no AND dc.market_data_set = tb.market_data_set'; --bug 2550158
1314 IF p_style='X' THEN
1315 IF p_analysis_type='P' THEN
1316 p_sql := p_sql||' AND (c.end_date>=tb.pos_start_date OR tb.pos_start_date IS NULL) AND (tb.pos_end_date IS NULL OR c.end_date<tb.pos_end_date)';
1317 ELSE
1318 --p_sql := p_sql||' AND (c.end_date>=tb.start_date OR tb.start_date IS NULL) AND c.end_date<=tb.end_date'; --bug 2638277
1319 p_sql := p_sql||' AND (c.start_date<=tb.end_date OR tb.start_date IS NULL) AND c.end_date>=tb.end_date'||
1320 ' AND (NVL(v.end_date,:ref_date+1)>=tb.start_date OR tb.start_date IS NULL) AND NVL(v.end_date,:ref_date+1)<=tb.end_date'; --bug 2638277
1321 END IF;
1322 ELSE --single period
1323 IF p_analysis_type='P' THEN
1324 --Bug 2318165 no.7
1325 p_sql := p_sql||' AND (tb.pos_start_date IS NULL OR :end_date>=tb.pos_start_date) AND (tb.pos_end_date IS NULL OR :end_date<tb.pos_end_date)'; --bug 3085258
1326 ELSIF p_analysis_type='G' THEN
1327 p_sql := p_sql||' AND (tb.start_date IS NULL OR NVL(dc.gap_date,:ref_date+1)>=tb.start_date) AND NVL(dc.gap_date,:ref_date+1)<=tb.end_date'; --bug 2638277
1328 --p_sql := p_sql||' AND (tb.start_date IS NULL OR NVL(dc.gap_date,:ref_date+1)>=tb.start_date) AND NVL(dc.gap_date,:ref_date+1)<tb.end_date'; --bug 2638277
1329 ELSE --p_analysis_type='M' THEN
1330 --p_sql := p_sql||' AND (tb.start_date IS NULL OR NVL(v.end_date,:ref_date+1)>=tb.start_date) AND NVL(v.end_date,:ref_date+1)<tb.end_date';
1331 --bug 2637950
1332 p_sql := p_sql||' AND ((v.start_date>=(:ref_date+1) AND NVL(v.end_date,v.start_date+1)>=tb.start_date AND NVL(v.end_date,v.start_date+1)<=tb.end_date)'||
1333 ' OR (v.start_date< (:ref_date+1) AND NVL(v.end_date,:ref_date+1)>=tb.start_date AND NVL(v.end_date,:ref_date+1)<=tb.end_date))';
1334 END IF;
1335 END IF;
1336 END IF;
1337 --WHERE ... AND dst.deal_subtype=v.deal_subtype
1338 IF v_deal_subtype THEN
1339 p_sql := p_sql||' AND dst.deal_subtype=v.deal_subtype AND dst.deal_type=v.deal_type';
1340 END IF;
1341
1342 IF p_style<>'T' THEN
1343 --add GROUP BY clause
1344 p_sql := p_sql||' GROUP BY ';
1345 IF (g_proc_level>=g_debug_level) THEN
1346 xtr_risk_debug_pkg.dlog('create_cursor: ' || 'v_aggregate_level',v_aggregate_level);
1347 END IF;
1348 FOR j IN 1..v_aggregate_level LOOP
1349 --xtr_risk_debug_pkg.dlog('v_act_agg(j)',j||':'||v_act_agg(j));
1350 --check whether att. is from table or view
1351 IF p_type(j)<>'C' THEN
1352 IF p_origin(j)='T' THEN
1353 p_sql := p_sql||'dc.'||v_act_agg(j);
1354 ELSIF p_origin(j)='V' THEN
1355 IF v_act_agg(j)='DEAL_SUBTYPE' THEN
1356 p_sql := p_sql||'dst.user_deal_subtype';
1357 ELSE
1358 p_sql := p_sql||'v.'||v_act_agg(j);
1359 END IF;
1360 ELSE --IF p_origin(j)='B'
1361 p_sql := p_sql||'tb.'||v_act_agg(j);
1362 END IF;
1363 ELSE --group by seq_no
1364 p_sql := p_sql||'c.seq_no';
1365 END IF;
1366 --special case where style=X
1367 IF p_style='X' AND p_type(j)='R' AND p_type(j+1)='M' THEN
1368 p_sql := p_sql||',c.seq_no';
1369 END IF;
1370 --put coma if not the end of Group By clause
1371 IF j<v_aggregate_level THEN
1372 p_sql := p_sql||',';
1373 END IF;
1374 END LOOP;
1375
1376 --add ORDER BY clause
1377 p_sql := p_sql||' ORDER BY ';
1378 FOR j IN 1..v_aggregate_level LOOP
1379 p_sql := p_sql||TO_CHAR(j);
1380 IF j<v_aggregate_level THEN
1381 p_sql := p_sql||',';
1382 END IF;
1383 END LOOP;
1384 END IF; --p_style<>'T'
1385
1386 IF (g_proc_level>=g_debug_level) THEN
1387 xtr_risk_debug_pkg.dpop(null,'QRM_PORTFOLIO_ANALYSIS.CREATE_CURSOR');
1388 END IF;
1389 END create_cursor;
1390
1391
1392
1393 /***************************************************************
1394 This function is the main function that does aggregation,
1395 transformation of the data and saving them into the
1396 qrm_saved_analyses_row and qrm_saved_analyses_col tables.
1397 ***************************************************************/
1398 FUNCTION transform_and_save (p_name VARCHAR2,
1399 p_ref_date DATE,
1400 p_caller_flag VARCHAR2)
1401 --'OA' if called from OA
1402 --'CONC' if called from Concurrent Program
1403 RETURN VARCHAR2 IS --'T' if success or 'F' for unsuccessful
1404
1405 v_start_date SYSTEM.QRM_DATE_TABLE := SYSTEM.QRM_DATE_TABLE();
1406 v_end_date SYSTEM.QRM_DATE_TABLE := SYSTEM.QRM_DATE_TABLE();
1407 v_col SYSTEM.QRM_VARCHAR_table;
1408 v_col_seq_no xtr_md_num_table := xtr_md_num_table();
1409 v_col_name_map SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1410 v_percent_col_name_map SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1411 v_a1 SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1412 v_col_hidden SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1413 v_col_type xtr_md_num_table := xtr_md_num_table();
1414 v_col_seq_no_key SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1415 v_col_order xtr_md_num_table;
1416 v_col_ccy_multp xtr_md_num_table := xtr_md_num_table();--Bug 2566711
1417
1418 v_header SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1419 v_measure xtr_md_num_table := xtr_md_num_table();
1420 v_save_header SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1421 v_save_measure xtr_md_num_table := xtr_md_num_table();
1422 v_nom xtr_md_num_table := xtr_md_num_table();
1423 v_denom xtr_md_num_table := xtr_md_num_table();
1424 v_nom_usd xtr_md_num_table := xtr_md_num_table();
1425 v_denom_usd xtr_md_num_table := xtr_md_num_table();
1426 v_origin SYSTEM.QRM_VARCHAR_table;
1427 v_tb_label_arr SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1428 v_num_denom_origin SYSTEM.QRM_VARCHAR_TABLE;
1429
1430 v_sql VARCHAR2(4000);
1431 v_sql_col VARCHAR2(4000);
1432 v_max_col_no NUMBER(5):=0; --actual column span length excluding rowheader
1433 v_row_agg_no NUMBER(5); --no of levels of row agg.
1434 --for C style means no of levels of col agg.
1435 --for A style means no of aggregated col.
1436 v_col_agg_no NUMBER(5) := 1;
1437 v_measure_no NUMBER(5) := 0; --no of measure columns in the SQL statement
1438 --no of measure columns+other number type columns in the SQL statement
1439 v_all_meas_no NUMBER(5);
1440
1441 v_date_type VARCHAR2(1);
1442 v_as_of_date DATE;--=v_start_date_fix
1443 v_start_date_ref VARCHAR2(2);
1444 v_start_date_offset NUMBER;
1445 v_start_offset_type VARCHAR2(1);
1446 v_end_date_fix DATE;
1447 v_end_date_ref VARCHAR2(2);
1448 v_end_date_offset NUMBER;
1449 v_end_offset_type VARCHAR2(1);
1450 v_tb_name VARCHAR2(20);
1451 v_tb_label VARCHAR2(1);
1452 v_style VARCHAR2(1);
1453 v_analysis_type VARCHAR2(1);
1454 v_calendar_id NUMBER(15);
1455 v_business_week VARCHAR2(1);
1456 v_currency_source VARCHAR2(1);
1457 v_curr_reporting VARCHAR2(15);
1458 v_md_set_code VARCHAR2(20);
1459 v_sens_exist BOOLEAN := FALSE; --whether the meas. contains sens.meas.
1460 v_sens_flag NUMBER(1);
1461 v_tb_calc_used BOOLEAN := FALSE;
1462 v_tb_calc_used_col BOOLEAN := FALSE;
1463 ----------CCY Variables------------
1464 v_ccy_suffix VARCHAR2(20); --suffix to be appended to att.(i.e. '_USD')
1465 v_ccy_multiplier NUMBER; --the FX rate between USD and other CCY
1466 --Flag for v_ccy_case_flag:
1467 --NULL = never tested
1468 --1 = 1 ccy for the whole analysis
1469 --0 = >1 ccy for the whole analysis(>1 ccy in each col. for style=A)
1470 --2 = >1 ccy for the whole analysis but 1 ccy in each col (style=A)
1471 v_ccy_case_flag NUMBER(1);
1472 --whether ccy/company is part of the agg.,depending on ccy pref(DEAL/SOB)
1473 --Flag for v_ccy_agg_flag:
1474 --NULL = never tested
1475 --1 = CCY (or COMPANY_CODE) is part of the aggregates
1476 --0 = CCY (or COMPANY_CODE) is not part of the aggregates
1477 --2 = CCY (or COMPANY_CODE) is part of row agg
1478 --3 = CCY (or COMPANY_CODE) is part of col agg
1479 v_ccy_agg_flag NUMBER(1);
1480 v_ccy_agg_level NUMBER(5);
1481 v_underlying_ccy VARCHAR2(15);--the ccy in the case of 1 underlying ccy used
1482 v_need_usd_arr BOOLEAN;
1483 v_current_ccy VARCHAR2(15);--the current ccy when CCY is aggregate
1484 v_row_ccy VARCHAR2(15);--the ccy of the last row with v_header(ccy_agg_level)
1485 --dummy variable used for style='T' required for get_underlying_currency
1486 v_table_col_curr SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1487 v_agg_col_curr SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
1488 ----------End CCY Variables--------
1489 CURSOR analysis_data IS
1490 SELECT analysis_type, style, tb_label, tb_name, date_type, start_date,
1491 start_date_ref, start_date_offset, start_offset_type, end_date,
1492 end_date_ref, end_date_offset, end_offset_type, business_week,
1493 gl_calendar_id,currency_source,curr_reporting,md_set_code
1494 FROM qrm_analysis_settings
1495 WHERE analysis_name=p_name AND history_flag='S';
1496
1497 CURSOR attribute_data IS
1498 SELECT DECODE(a.type,'R',1,'C',2,'M',3,4) seq, a.att_order,
1499 a.attribute_name, a.type, a.total_average, a.percentage, l.numerator,
1500 l.denominator, l.origin, l.amount, l.ccy_aggregate, l.sensitivity,
1501 l.num_denom_origin
1502 FROM qrm_analysis_atts a, qrm_ana_atts_lookups l
1503 WHERE a.attribute_name=l.attribute_name AND a.analysis_name=p_name
1504 AND history_flag='S'
1505 ORDER BY 1,2;
1506
1507 CURSOR count_max_col_no IS
1508 SELECT COUNT(*) FROM qrm_saved_analyses_col
1509 WHERE analysis_name=p_name
1510 AND type>-2;
1511
1512 v_agg SYSTEM.QRM_VARCHAR240_TABLE;
1513 --array of the actual column names including currency conversion
1514 --to be inserted into the DYNAMIC SQL
1515 v_att_type SYSTEM.QRM_VARCHAR_table;
1516 v_nom_fl SYSTEM.QRM_VARCHAR240_TABLE;
1517 v_denom_fl SYSTEM.QRM_VARCHAR240_TABLE;
1518 v_tot_avg SYSTEM.QRM_VARCHAR_table;
1519 v_percent SYSTEM.QRM_VARCHAR_table;
1520 v_dummy1 xtr_md_num_table;
1521 v_amount SYSTEM.QRM_VARCHAR_table;
1522 v_ccy_aggregate SYSTEM.QRM_VARCHAR_table;
1523 v_sensitivity SYSTEM.QRM_VARCHAR_table;
1524
1525 i NUMBER(5);
1526 j NUMBER(5);
1527 k NUMBER(5);
1528 m NUMBER(5);
1529 n NUMBER(5);
1530 v_row NUMBER(5) := 0;
1531 v_new_row BOOLEAN;
1532 v_type NUMBER(5);
1533 v_hidden VARCHAR(1);
1534 v_divisor NUMBER := 0.000001;
1535
1536 --the row agg level which is totaled up to the previous level
1537 v_total_level NUMBER(5);
1538 v_cursor INT;
1539 v_rows_processed NUMBER;
1540 v_success BOOLEAN := TRUE;
1541 v_skip_row BOOLEAN;
1542 -----------
1543 --For col seq no 1
1544 --CO.A NI USD
1545 --L1 L2 L3 --=v_total_level
1546 -----------
1547
1548 -------Testing parameters
1549 dummy NUMBER;
1550 v_test VARCHAR2(255);
1551 -------End Testing parameters
1552
1553 BEGIN
1554 IF (g_proc_level>=g_debug_level) THEN
1555 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE');
1556 END IF;
1557
1558 --initialize fnd_msg_pub if it has not been intialized
1559 IF p_caller_flag='OA' AND fnd_msg_pub.count_msg>0 THEN
1560 fnd_msg_pub.Initialize;
1561 END IF;
1562
1563 --query analysis data
1564 OPEN analysis_data;
1565 FETCH analysis_data INTO v_analysis_type, v_style, v_tb_label, v_tb_name,
1566 v_date_type, v_as_of_date, v_start_date_ref, v_start_date_offset,
1567 v_start_offset_type, v_end_date_fix, v_end_date_ref, v_end_date_offset,
1568 v_end_offset_type, v_business_week, v_calendar_id, v_currency_source,
1569 v_curr_reporting, v_md_set_code;
1570 CLOSE analysis_data;
1571
1572 --check whether analysis settings still there by looking whether the required
1573 --column value return IS NULL or not
1574 IF v_style IS NULL THEN
1575 FND_MESSAGE.SET_NAME('QRM','QRM_ANA_NO_SETTING');
1576 FND_MESSAGE.SET_TOKEN('ANALYSIS_NAME',p_name);
1577 RAISE e_pagg_no_setting_found;
1578 END IF;
1579
1580 --DELETE existing saved data
1581 DELETE qrm_saved_analyses_row WHERE analysis_name=p_name;
1582 IF NOT (v_style='X' AND p_caller_flag='OA') THEN
1583 DELETE qrm_saved_analyses_col WHERE analysis_name=p_name;
1584 END IF;
1585 COMMIT;
1586 --xtr_risk_debug_pkg.dlog('v_analysis_type',v_analysis_type);
1587 --xtr_risk_debug_pkg.dlog('v_style',v_style);
1588 --xtr_risk_debug_pkg.dlog('v_tb_label',v_tb_label);
1589 --xtr_risk_debug_pkg.dlog('v_tb_name',v_tb_name);
1590 --xtr_risk_debug_pkg.dlog('v_date_type',v_date_type);
1591 --xtr_risk_debug_pkg.dlog('v_as_of_date',v_as_of_date);
1592 --xtr_risk_debug_pkg.dlog('v_start_date_ref',v_start_date_ref);
1593 --xtr_risk_debug_pkg.dlog('v_start_date_offset',v_start_date_offset);
1594 --xtr_risk_debug_pkg.dlog('v_start_offset_type',v_start_offset_type);
1595 --xtr_risk_debug_pkg.dlog('v_business_week',v_business_week);
1596 --xtr_risk_debug_pkg.dlog('v_calendar_id',v_calendar_id);
1597 --query attributes data to from SQL statement
1598 OPEN attribute_data;
1599 FETCH attribute_data BULK COLLECT INTO v_dummy1,v_col_order,v_agg,v_att_type,
1600 v_tot_avg,v_percent,v_nom_fl,v_denom_fl,v_origin,v_amount,
1601 v_ccy_aggregate,v_sensitivity,v_num_denom_origin;
1602 CLOSE attribute_data;
1603 --xtr_risk_debug_pkg.dlog('v_agg.COUNT',v_agg.COUNT);
1604 --use some logic to determine what the report underlying currency is
1605 --First, find if there is any AMOUNT type
1606 --bec. amount typemeas. are the only one that can be converted to diff ccy
1607 FOR i IN 1..v_amount.LAST LOOP
1608 IF v_amount(i)='Y' THEN
1609 get_underlying_currency(p_name,p_ref_date,v_style,v_md_set_code,
1610 v_currency_source,v_curr_reporting,
1611 v_amount,v_agg,v_ccy_aggregate,v_att_type,
1612 v_col_order,v_ccy_suffix,
1613 v_ccy_multiplier,v_ccy_agg_flag,v_underlying_ccy,
1614 v_ccy_case_flag,v_agg(i),v_ccy_agg_level,
1615 v_table_col_curr,v_agg_col_curr,
1616 NULL);
1617 IF (g_proc_level>=g_debug_level) THEN
1618 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_ccy_suffix',v_ccy_suffix);
1619 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_ccy_multiplier',v_ccy_multiplier);
1620 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_ccy_case_flag',v_ccy_case_flag);
1621 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_ccy_agg_flag',v_ccy_agg_flag);
1622 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_ccy_agg_level',v_ccy_agg_level);
1623 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'After get_underlying_ccy: v_underlying_ccy',v_underlying_ccy);
1624 END IF;
1625 --see whether need USD array container if Total CCY is diff.
1626 --from CCY used
1627 IF (v_ccy_case_flag=0 AND v_ccy_agg_flag>0) THEN
1628 v_need_usd_arr := TRUE;
1629 ELSE
1630 v_need_usd_arr := FALSE;
1631 END IF;
1632 IF (g_proc_level>=g_debug_level) THEN
1633 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_need_usd_arr',v_need_usd_arr);
1634 END IF;
1635 EXIT;
1636 END IF;
1637 END LOOP;
1638
1639 --Make sure that v_ccy_multiplier is not NULL when needed, otherwise,
1640 --throws exception
1641 IF v_ccy_multiplier IS NULL AND v_curr_reporting<>'USD' AND
1642 ((v_ccy_case_flag=0 AND v_ccy_agg_flag=0) OR v_currency_source='R' OR
1643 (v_ccy_case_flag=0 AND v_ccy_agg_flag IN (1,2) AND v_ccy_agg_level>1))
1644 THEN
1645 FND_MESSAGE.SET_NAME('QRM','QRM_CALC_NO_DEFAULT_SPOT_ERR');
1646 FND_MESSAGE.SET_TOKEN('CCY',v_curr_reporting);
1647 raise e_pagg_no_fxrate_found;
1648 END IF;
1649 --Update currency_used in qrm_analysis_settings
1650 IF v_ccy_case_flag=0 AND v_ccy_agg_flag=0 THEN --use curr_reporting
1651 UPDATE qrm_analysis_settings
1652 SET currency_used='R', last_updated_by=FND_GLOBAL.user_id,
1653 last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
1654 WHERE analysis_name=p_name AND history_flag='S';
1655 ELSE --use whatever in currency_source
1656 UPDATE qrm_analysis_settings
1657 SET currency_used=currency_source, last_updated_by=FND_GLOBAL.user_id,
1658 last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
1659 WHERE analysis_name=p_name AND history_flag='S';
1660 END IF;
1661
1662 IF (g_event_level>=g_debug_level) THEN --bug 3236479
1663 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_ANALYSIS_SETTINGS.CURRENCY_USED',
1664 'QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_event_level);
1665 END IF;
1666
1667 --Fix end date to be used later, alrady calculated and saved by FHU engine
1668
1669 --construct the DYNAMIC SQL for the aggregate
1670 create_cursor(p_name,v_style,v_analysis_type,
1671 v_agg,v_att_type,v_nom_fl,v_denom_fl,v_tot_avg,
1672 v_sql,v_sql_col,v_row_agg_no,v_measure_no,v_origin,
1673 v_tb_calc_used,v_tb_calc_used_col,v_need_usd_arr,
1674 v_ccy_suffix,
1675 v_ccy_multiplier,v_amount,v_table_col_curr,v_num_denom_origin,
1676 v_curr_reporting,v_sensitivity);
1677
1678 IF (g_proc_level>=g_debug_level) THEN
1679 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'LENGTH(v_sql)',LENGTH(v_sql));
1680 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_sql',v_sql);
1681 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_sql_col',v_sql_col);
1682 END IF;
1683
1684 IF v_style='X' AND p_caller_flag='OA' THEN
1685 OPEN count_max_col_no;
1686 FETCH count_max_col_no INTO v_max_col_no;
1687 CLOSE count_max_col_no;
1688 --there is no agg for column in qrm_analysis_atts for style=X
1689 v_col_agg_no := 0;
1690 ELSE
1691 --loop over the col. header cursor and populate qrm_saved_analyses_table
1692 v_col_seq_no.EXTEND(v_row_agg_no);
1693 v_col_seq_no_key.EXTEND(v_row_agg_no);
1694 v_col_name_map.EXTEND(v_row_agg_no);
1695 v_percent_col_name_map.EXTEND(v_row_agg_no);
1696 v_a1.EXTEND(v_row_agg_no);
1697 v_col_type.EXTEND(v_row_agg_no);
1698 v_col_hidden.EXTEND(v_row_agg_no);
1699
1700 FOR j IN 1..v_agg.LAST LOOP
1701 --row aggreagate info on the column header
1702 IF v_att_type(j)='R' THEN
1703 v_col_seq_no(j) := j;
1704 --Need to create a LOOP in case of multiple col. level
1705 v_col_seq_no_key(j) := v_agg(j);
1706 v_col_name_map(j) := 'A'||TO_CHAR(j);
1707 v_a1(j) := v_agg(j);
1708 v_col_type(j) := -2; --header type
1709 v_col_hidden(j) := 'N';
1710 --column
1711 ELSIF v_att_type(j)='C' THEN
1712 --include col. agg. values in the column header
1713 --only v_style='C' has att_type='C'
1714 --bulk fetch into PL/SQL temp array
1715 v_sql_col := 'BEGIN '||v_sql_col||' END;';
1716 IF v_tb_calc_used_col THEN
1717 IF v_analysis_type='P' THEN
1718 EXECUTE IMMEDIATE v_sql_col USING OUT v_col,p_name,v_end_date_fix;
1719 ELSE
1720 EXECUTE IMMEDIATE v_sql_col USING OUT v_col,p_name,TRUNC(p_ref_date);
1721 END IF;
1722 ELSE
1723 EXECUTE IMMEDIATE v_sql_col USING OUT v_col,p_name;
1724 END IF;
1725
1726 v_max_col_no := v_col.COUNT;
1727 IF (g_proc_level>=g_debug_level) THEN
1728 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_max_col_no',v_max_col_no);
1729 END IF;
1730 --construct v_seq_no, v_col_name_map, v_hidden, v_type
1731 v_col_seq_no.EXTEND(v_max_col_no);
1732 v_col_seq_no_key.EXTEND(v_max_col_no);
1733 v_col_name_map.EXTEND(v_max_col_no);
1734 v_percent_col_name_map.EXTEND(v_max_col_no);
1735 v_a1.EXTEND(v_max_col_no);
1736 v_col_type.EXTEND(v_max_col_no);
1737 v_col_hidden.EXTEND(v_max_col_no);
1738 FOR i IN v_row_agg_no+1..(v_row_agg_no+v_max_col_no) LOOP
1739 v_col_seq_no(i) := i;
1740 v_col_seq_no_key(i) := v_col(i-v_row_agg_no);
1741 v_col_name_map(i) := 'M'||TO_CHAR(i-v_row_agg_no);
1742 v_percent_col_name_map(i) := 'P'||TO_CHAR(i-v_row_agg_no);
1743 v_a1(i) := v_col(i-v_row_agg_no);
1744 v_col_type(i) := -1; --measure type
1745 v_col_hidden(i) := 'N';
1746 END LOOP;
1747 --add total column at the end
1748
1749 --measure, becomes a column header only in the case of Aggregated Table
1750 ELSE
1751 --must be att. type = 'M' (measure)
1752 IF v_style='X' THEN
1753 --hardcoded date_type=(F)ixed, because qrmpaca*.pls will have
1754 --saved the fixed date by the time this function is called.
1755 update_timebuckets(p_name,p_ref_date,
1756 v_tb_name,v_tb_label,v_as_of_date,
1757 v_start_date_ref,v_start_date_offset,v_start_offset_type,
1758 v_row_agg_no,v_max_col_no,'F',v_calendar_id,
1759 v_business_week,v_col_seq_no,v_col_seq_no_key,
1760 v_col_name_map,v_percent_col_name_map,v_a1,
1761 v_col_type,v_col_hidden,v_start_date,v_end_date,
1762 v_tb_label_arr);
1763 --there is no agg for column in qrm_analysis_atts for style=X
1764 v_col_agg_no := 0;
1765 ELSIF v_style='A' THEN
1766 --if need usd arr then v_measure will include additional '_usd'
1767 --amount columns
1768 IF v_need_usd_arr THEN
1769 v_max_col_no := v_measure_no/4;
1770 ELSE
1771 v_max_col_no := v_measure_no/2;
1772 END IF;
1773
1774 v_col_agg_no := 0;
1775 v_col_seq_no.EXTEND(v_max_col_no);
1776 v_col_seq_no_key.EXTEND(v_max_col_no);
1777 v_col_name_map.EXTEND(v_max_col_no);
1778 v_percent_col_name_map.EXTEND(v_max_col_no);
1779 v_a1.EXTEND(v_max_col_no);
1780 v_col_type.EXTEND(v_max_col_no);
1781 v_col_hidden.EXTEND(v_max_col_no);
1782 v_col_seq_no(j) := j;
1783 v_col_seq_no_key(j) := v_agg(j);
1784 v_col_name_map(j) := 'M'||TO_CHAR(j-v_row_agg_no);
1785 v_percent_col_name_map(j) := 'P'||TO_CHAR(j-v_row_agg_no);
1786 v_a1(j) := v_agg(j);
1787 v_col_type(j) := -1;
1788 v_col_hidden(j) := 'N';
1789 ELSE
1790 --exit path for style C and X
1791 EXIT;
1792 END IF;
1793 END IF;
1794 END LOOP;
1795
1796 ------------Should be removed and done in a separate function
1797 ------------if multiple cil level is implemented
1798 --add total column at the end
1799 v_max_col_no := v_max_col_no+1;
1800 v_col_seq_no.EXTEND;
1801 v_col_seq_no_key.EXTEND;
1802 v_col_type.EXTEND;
1803 v_col_hidden.EXTEND;
1804 v_col_name_map.EXTEND;
1805 v_percent_col_name_map.EXTEND;
1806 v_a1.EXTEND;
1807 IF v_style='X' THEN
1808 v_start_date.EXTEND;
1809 v_end_date.EXTEND;
1810 v_tb_label_arr.EXTEND;
1811 END IF;
1812 j := v_max_col_no+v_row_agg_no;
1813 v_col_seq_no(j) := j;
1814 v_col_seq_no_key(j) := 'TOTAL';
1815 v_col_name_map(j) := 'M'||TO_CHAR(v_max_col_no);
1816 v_percent_col_name_map(j) := 'P'||TO_CHAR(v_max_col_no);
1817 --need to append ccy to total do the ccy logic
1818 v_a1(j) := 'TOTAL';
1819 v_col_type(j) := 1; --total level 1, grand total
1820 v_col_hidden(j) := 'N';
1821 ------------End Should be removed and done in a separate function
1822
1823 -------------Testing purposes
1824 FOR i IN 1..v_row_agg_no+v_max_col_no LOOP
1825 IF (g_proc_level>=g_debug_level) THEN
1826 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'i:seq_no:seq_no_key:a1',i||':'||v_col_seq_no(i)||':'||v_col_seq_no_key(i)||':'||v_a1(i));
1827 END IF;
1828 -- xtr_risk_debug_pkg.dlog('i:type:hidden:col_name_map:percent_col_name_map',i||':'||v_col_type(i)||':'||v_col_hidden(i)||':'||v_col_name_map(i)||':'||v_percent_col_name_map(i)||':');
1829 IF v_style='X' THEN
1830 IF (g_proc_level>=g_debug_level) THEN
1831 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'i:start:end',i||':'||v_start_date(i)||':'||v_end_date(i));
1832 END IF;
1833 END IF;
1834 END LOOP;
1835 -------------End Testing purposes
1836
1837 --bulk insert
1838 IF v_style='X' THEN
1839 FORALL i IN 1..v_max_col_no+v_row_agg_no
1840 INSERT INTO qrm_saved_analyses_col(analysis_name,seq_no,seq_no_key,
1841 type,hidden,col_name_map,a1,percent_col_name_map,start_date,
1842 end_date,tb_label,created_by,creation_date,last_updated_by,
1843 last_update_date,
1844 last_update_login) VALUES(p_name,v_col_seq_no(i),
1845 v_col_seq_no_key(i),v_col_type(i),v_col_hidden(i),
1846 v_col_name_map(i),
1847 v_a1(i),v_percent_col_name_map(i),v_start_date(i),v_end_date(i),
1848 v_tb_label_arr(i),
1849 FND_GLOBAL.user_id,p_ref_date,FND_GLOBAL.user_id,p_ref_date,
1850 FND_GLOBAL.login_id);
1851 ELSE
1852 FORALL i IN 1..v_max_col_no+v_row_agg_no
1853 INSERT INTO qrm_saved_analyses_col(analysis_name,seq_no,seq_no_key,
1854 type,hidden,col_name_map,a1,percent_col_name_map,created_by,
1855 creation_date,last_updated_by,last_update_date,
1856 last_update_login)
1857 VALUES(p_name,v_col_seq_no(i),v_col_seq_no_key(i),v_col_type(i),
1858 v_col_hidden(i),v_col_name_map(i),v_a1(i),
1859 v_percent_col_name_map(i),
1860 FND_GLOBAL.user_id,p_ref_date,FND_GLOBAL.user_id,p_ref_date,
1861 FND_GLOBAL.login_id);
1862 END IF;
1863 COMMIT;
1864
1865 IF (g_event_level>=g_debug_level) THEN --bug 3236479
1866 XTR_RISK_DEBUG_PKG.dlog('DML','Inserted into QRM_SAVED_ANALYSES_COL',
1867 'QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_event_level);
1868 END IF;
1869
1870 ----Start Bug 2566711
1871 --update the tot_currency and tot_currency_label columns
1872 IF v_style IN ('C','X') THEN
1873 IF v_ccy_case_flag=0 AND v_ccy_agg_flag=2 THEN
1874 UPDATE qrm_saved_analyses_col
1875 SET tot_currency=v_curr_reporting,
1876 tot_currency_label=' ('||v_curr_reporting||')',
1877 last_updated_by=FND_GLOBAL.user_id,
1878 last_update_date=p_ref_date,
1879 last_update_login=FND_GLOBAL.login_id
1880 WHERE type=1;
1881 ELSIF v_ccy_case_flag=1 THEN
1882 UPDATE qrm_saved_analyses_col
1883 SET tot_currency=v_underlying_ccy,
1884 tot_currency_label=' ('||v_underlying_ccy||')',
1885 last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date,
1886 last_update_login=FND_GLOBAL.login_id
1887 WHERE type=1;
1888 ELSE
1889 UPDATE qrm_saved_analyses_col
1890 SET tot_currency=NULL,
1891 tot_currency_label=NULL,
1892 last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date,
1893 last_update_login=FND_GLOBAL.login_id
1894 WHERE type=1;
1895 END IF;
1896 END IF;
1897 ----End Bug 2566711
1898 COMMIT;
1899
1900 IF (g_event_level>=g_debug_level) THEN --bug 3236479
1901 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SAVED_ANALYSES_COL.TOT_CURRENCY',
1902 'QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_event_level);
1903 END IF;
1904
1905 END IF;--for p_caller_flag='OA' and v_style='X'
1906
1907 --prepare the columns currencies multiplier in case each column has
1908 --different currencies. This is necessary to TOTAL columnwise.
1909 IF v_style IN ('C','X') and v_ccy_case_flag=0 and v_ccy_agg_flag=2 THEN
1910 get_col_ccy_multp(v_col_ccy_multp,
1911 v_a1,
1912 v_currency_source,
1913 v_row_agg_no,
1914 v_max_col_no,
1915 v_md_set_code,
1916 p_ref_date);
1917 END IF;
1918
1919 --find no of measure columns+other number type columns in the SQL statement
1920 IF v_style='A' THEN
1921 v_all_meas_no := v_measure_no;
1922 ELSE
1923 --add 1 for the col span seq no
1924 v_all_meas_no := v_measure_no+1;
1925 END IF;
1926
1927 --open dynamic cursor
1928 v_cursor := dbms_sql.open_cursor;
1929 --Parse the results (row: qrm_saved_analyses_row)
1930 dbms_sql.parse(v_cursor,v_sql,dbms_sql.native);
1931 dbms_sql.bind_variable(v_cursor,'analysis_name',p_name);
1932 --remember to add end_date as binding variable
1933 --for special cases
1934 IF (g_proc_level>=g_debug_level) THEN
1935 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_tb_calc_used',v_tb_calc_used);
1936 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_end_date_fix',v_end_date_fix);
1937 END IF;
1938 IF v_style='X' THEN
1939 IF v_analysis_type<>'P' THEN
1940 dbms_sql.bind_variable(v_cursor,'ref_date',TRUNC(p_ref_date));
1941 END IF;
1942 ELSE
1943 IF v_tb_calc_used THEN
1944 IF v_analysis_type='P' THEN
1945 dbms_sql.bind_variable(v_cursor,'end_date',v_end_date_fix);
1946 ELSE
1947 dbms_sql.bind_variable(v_cursor,'ref_date',TRUNC(p_ref_date));
1948 END IF;
1949 END IF;
1950 END IF;
1951
1952 --define columns for row agg
1953 v_header.EXTEND(2*v_row_agg_no); -- the extra storage to be used later
1954 v_measure.EXTEND(v_all_meas_no);
1955 FOR i IN 1..v_row_agg_no LOOP
1956 dbms_sql.define_column(v_cursor,i,v_header(i),20);
1957 END LOOP;
1958 IF (g_proc_level>=g_debug_level) THEN
1959 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_measure_no',v_measure_no);
1960 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_all_meas_no',v_all_meas_no||':'||v_measure.COUNT);
1961 END IF;
1962 FOR i IN 1..v_all_meas_no LOOP
1963 dbms_sql.define_column(v_cursor,i+v_row_agg_no,v_measure(i));
1964 END LOOP;
1965
1966 --execute
1967 v_rows_processed := dbms_sql.execute(v_cursor);
1968 --xtr_risk_debug_pkg.dlog('v_cursor = ',v_cursor);
1969 --xtr_risk_debug_pkg.dlog('v_rows_processed = ',v_rows_processed);
1970
1971 --calculate multiplier to be used in the total array for style=A
1972 IF v_need_usd_arr THEN -- need to consider USD array then
1973 m := 4;
1974 n := m-2;
1975 ELSE
1976 m := 2;
1977 n := m-2;
1978 END IF;
1979
1980 --creating/preparing the temporary storage
1981 v_save_header.EXTEND(v_row_agg_no);
1982
1983 v_save_measure.EXTEND(v_max_col_no);
1984 v_nom.EXTEND(v_row_agg_no*v_max_col_no);
1985 v_denom.EXTEND(v_row_agg_no*v_max_col_no);
1986 IF v_need_usd_arr THEN
1987 v_nom_usd.EXTEND(v_row_agg_no*v_max_col_no);
1988 v_denom_usd.EXTEND(v_row_agg_no*v_max_col_no);
1989 END IF;
1990
1991
1992 --loop through the fetched rows
1993 LOOP
1994 --fetch a row
1995 IF dbms_sql.fetch_rows(v_cursor)>0 THEN
1996 --fetch header/VARCHAR type
1997 FOR i IN 1..v_row_agg_no LOOP
1998 dbms_sql.column_value(v_cursor,i,v_header(i));
1999 --xtr_risk_debug_pkg.dlog('v_header(i)',i||':'||v_header(i));
2000 END LOOP;
2001
2002 --first reset the indicator
2003 v_skip_row := FALSE;
2004 --skip the row if the at least one of the header aggregate att IS NULL
2005 FOR i IN 1..v_row_agg_no LOOP
2006 IF v_header(i) IS NULL THEN
2007 v_skip_row := TRUE;
2008 END IF;
2009 END LOOP;
2010
2011 IF NOT v_skip_row THEN
2012 --fetch measure and other NUMBER type
2013 FOR i IN 1..v_all_meas_no LOOP
2014 dbms_sql.column_value(v_cursor,i+v_row_agg_no,v_measure(i));
2015 END LOOP;
2016
2017 --different treatment for Cross Tab and Aggregated Table
2018 IF v_style='A' THEN --no need for pivoting for style=A
2019 --check whether need to insert total
2020 v_total_level := 0;
2021 IF v_row<>0 THEN
2022 FOR i IN 1..v_row_agg_no-1 LOOP
2023 IF v_save_header(i)<>v_header(i) THEN
2024 v_total_level := i+1;
2025 EXIT;
2026 END IF;
2027 END LOOP;
2028 --INSERT the old values: v_save_header and v_save_measure
2029 v_type := -1;
2030 v_hidden := 'N';
2031 v_success := insert_row(v_save_header,v_save_measure,
2032 v_row_agg_no,v_max_col_no,
2033 p_name,v_row,v_type,v_hidden,NULL,
2034 v_style,p_ref_date,v_ccy_case_flag,
2035 v_ccy_agg_flag,v_col_ccy_multp);
2036
2037 --delete the previous array content in case the new column
2038 --is null
2039 FOR i IN 1..v_row_agg_no LOOP
2040 v_save_header(i) := NULL;
2041 END LOOP;
2042 FOR i IN 1..v_max_col_no LOOP
2043 v_save_measure(i) := NULL;
2044 END LOOP;
2045 END IF;
2046
2047 --if v_total_level>0 then calc total and insert
2048 ------------------Calculating the Total Row------------------------
2049 --see if we need to insert total in between
2050
2051 IF v_total_level>0 THEN
2052 FOR i IN REVERSE v_total_level..v_row_agg_no LOOP
2053 v_row := v_row+1;
2054 v_save_header(i) := 'TOTAL';
2055 -- loop through the measures total
2056 FOR j IN 1..v_max_col_no LOOP
2057 k := (i-1)*v_max_col_no+j;
2058 --determine whether to fetch USD arr or reg. arr
2059 IF v_need_usd_arr AND i<=v_ccy_agg_level THEN
2060 IF v_denom_usd(k)=0 THEN
2061 v_save_measure(j):=v_nom_usd(k)/v_divisor;
2062 ELSE
2063 v_save_measure(j):=v_nom_usd(k)/v_denom_usd(k);
2064 END IF;
2065 ELSE
2066 IF v_denom(k)=0 THEN
2067 v_save_measure(j):=v_nom(k)/v_divisor;
2068 ELSE
2069 v_save_measure(j):=v_nom(k)/v_denom(k);
2070 END IF;
2071 END IF;
2072 v_nom(k) := NULL;
2073 v_denom(k) := NULL;
2074 IF v_need_usd_arr THEN
2075 v_nom_usd(k) := NULL;
2076 v_denom_usd(k) := NULL;
2077 END IF;
2078 END LOOP;
2082 --determine the CCY to be appended after TOTAL
2079 --INSERT the old values: v_save_header and v_save_measure
2080 v_type := i;
2081 v_hidden := 'Y';
2083 --does not need to worry for the CCY agg logic
2084 --(tot. level),
2085 --bec. it's captured in v_current_ccy
2086 --Make sure that ccy is appended to Total that has
2087 --uniform currency across the columns
2088 IF v_need_usd_arr THEN
2089 IF v_ccy_agg_flag=2 THEN
2090 v_current_ccy := NULL;--cannot display CCY
2091 ELSE --check whether before/after the ccy_agg_level
2092 IF i>=v_ccy_agg_level THEN
2093 v_current_ccy := v_row_ccy;
2094 ELSE --v_current_ccy=v_header(ccy_agg_level)
2095 v_current_ccy := v_curr_reporting;
2096 END IF;
2097 --ELSE keep the v_current_ccy
2098 END IF;
2099 ELSIF v_ccy_case_flag=2 THEN
2100 v_current_ccy := NULL;--cannot display CCY
2101 ELSE
2102 v_current_ccy := v_underlying_ccy;
2103 END IF;
2104 v_success := insert_row(v_save_header,v_save_measure,
2105 v_row_agg_no,v_max_col_no,
2106 p_name,v_row,v_type,v_hidden,
2107 v_current_ccy,
2108 v_style,p_ref_date,v_ccy_case_flag,
2109 v_ccy_agg_flag,v_col_ccy_multp);
2110 v_current_ccy := NULL; --reset v_current_ccy
2111 --delete the previous array content
2112 FOR i IN 1..v_row_agg_no LOOP
2113 v_save_header(i) := NULL;
2114 END LOOP;
2115 FOR i IN 1..v_max_col_no LOOP
2116 v_save_measure(i) := NULL;
2117 END LOOP;
2118 END LOOP;
2119 END IF;
2120 ------------------End Calculating the Total Row--------------------
2121
2122 v_row := v_row+1;
2123 --copy to v_save_measure and v_save_header assign to nom and
2124 --denom
2125 FOR i IN 1..v_row_agg_no LOOP
2126 v_save_header(i):=v_header(i);
2127 --determine the current row ccy
2128 IF v_ccy_agg_level=i AND v_need_usd_arr THEN
2129 v_row_ccy := v_header(i);
2130 END IF;
2131 END LOOP;
2132 --for style=A v_measure_no=2*(v_max_col_no-1)
2133 --1 is for the total at the column end
2134 --'-1' in 'v_max_col_no-1' is to compensate for the End Col TOTAL
2135 FOR k IN 1..v_max_col_no-1 LOOP
2136 IF v_tot_avg(v_row_agg_no+k)='T' THEN
2137 v_save_measure(k):=v_measure(k*m-n-1);
2138 FOR i IN 1..v_row_agg_no LOOP
2139 --determining the storage location for a specific
2140 --level total
2141 j := (i-1)*v_max_col_no+k;
2142 IF v_nom(j) IS NOT NULL THEN
2143 IF v_measure(k*m-n-1) IS NOT NULL THEN
2144 v_nom(j):=v_nom(j)+v_measure(k*m-n-1);
2145 END IF;
2146 ELSE
2147 v_nom(j):=v_measure(k*m-n-1);
2148 END IF;
2149 v_denom(j):=1;
2150 --determining the storage location for a USD specific
2151 --level total
2152 IF v_need_usd_arr THEN
2153 IF v_nom_usd(j) IS NOT NULL THEN
2154 IF v_measure(k*m-1) IS NOT NULL THEN
2155 v_nom_usd(j):=v_nom_usd(j)+v_measure(k*m-1);
2156 END IF;
2157 ELSE
2158 v_nom_usd(j):=v_measure(k*m-1);
2159 END IF;
2160 v_denom_usd(j):=1;
2161 END IF;
2162 END LOOP;
2163 --Weighted Average operation
2164 ELSE --insert to side array to be totaled later
2165 IF v_measure(k*m-n)=0 THEN
2166 v_save_measure(k):=v_measure(k*m-n-1)/v_divisor;
2167 ELSE
2168 v_save_measure(k):=v_measure(k*m-n-1)/v_measure(k*m-n);
2169 END IF;
2170 FOR i IN 1..v_row_agg_no LOOP
2171 --determining the storage location for a specific
2172 --level total
2173 j := (i-1)*v_max_col_no+k;
2174 IF v_nom(j) IS NOT NULL THEN
2175 IF v_measure(k*m-n-1) IS NOT NULL THEN
2176 v_nom(j):=v_nom(j)+v_measure(k*m-n-1);
2177 v_denom(j) := v_denom(j)+v_measure(k*m-n);
2178 END IF;
2179 ELSE
2180 v_nom(j):=v_measure(k*m-n-1);
2181 v_denom(j) := v_measure(k*m-n);
2182 END IF;
2183 --determining the storage location for a USD specific
2184 --level total
2185 IF v_need_usd_arr THEN
2186 IF v_nom(j) IS NOT NULL THEN
2187 IF v_measure(k*m-1) IS NOT NULL THEN
2188 v_nom_usd(j):=v_nom_usd(j)+v_measure(k*m-1);
2189 v_denom_usd(j) := v_denom_usd(j)+v_measure(k*m);
2190 END IF;
2191 ELSE
2192 v_nom_usd(j):=v_measure(k*m-1);
2193 v_denom_usd(j) := v_measure(k*m);
2194 END IF;
2195 END IF;
2196 END LOOP;
2197 END IF;
2198 END LOOP;
2199
2200 ELSE --pivoting for style='C','X'
2201 --save the previous row header info in v_header(2*v_row+i)
2202 --insert to temp array all the output
2203 --nontotal case
2204 v_new_row := FALSE;
2205 v_total_level := 0;
2206 --check whether it's a new row
2207 FOR i IN 1..v_row_agg_no LOOP
2208 IF v_row=0 OR v_save_header(i)<>v_header(i) THEN
2209 v_new_row := TRUE;
2210 --exclude condition of the first row fetched
2211 IF v_row<>0 AND i<>v_row_agg_no THEN
2212 v_total_level := i+1;
2213 END IF;
2214 EXIT;
2215 END IF;
2216 END LOOP;
2217 --new row,therefore insert row header
2218 IF v_new_row THEN
2219 IF v_row<>0 THEN
2220 --INSERT the old values: v_save_header and v_save_measure
2221 v_type := -1;
2222 v_hidden := 'N';
2223 v_success := insert_row(v_save_header,v_save_measure,
2224 v_row_agg_no,v_max_col_no,
2225 p_name,v_row,v_type,v_hidden,NULL,
2226 v_style,p_ref_date,v_ccy_case_flag,
2227 v_ccy_agg_flag,v_col_ccy_multp);
2228 --delete the previous array content
2229 FOR i IN 1..v_row_agg_no LOOP
2230 v_save_header(i) := NULL;
2231 END LOOP;
2232 FOR i IN 1..v_max_col_no LOOP
2233 v_save_measure(i) := NULL;
2234 END LOOP;
2235 END IF;
2236
2237 ------------------Calculating the Total Row------------------------
2238 --see if we need to insert total in between
2239 IF v_total_level>0 THEN
2240 FOR i IN REVERSE v_total_level..v_row_agg_no LOOP
2241 v_row := v_row+1;
2242 v_save_header(i) := 'TOTAL';
2243 -- loop through the measures total
2244 FOR j IN 1..v_max_col_no LOOP
2245 --determine whether to fetch USD arr or reg. arr
2246 IF v_need_usd_arr AND i<=v_ccy_agg_level
2247 AND v_ccy_agg_flag<>2 THEN --bug 2566711
2248 IF v_denom_usd((i-1)*v_max_col_no+j)=0 THEN
2249 v_save_measure(j):=v_nom_usd((i-1)*v_max_col_no+j)/v_divisor;
2250 ELSE
2251 v_save_measure(j):=v_nom_usd((i-1)*v_max_col_no+j)/v_denom_usd((i-1)*v_max_col_no+j);
2252 END IF;
2253 ELSE
2254 IF v_denom((i-1)*v_max_col_no+j)=0 THEN
2255 v_save_measure(j):=v_nom((i-1)*v_max_col_no+j)/v_divisor;
2256 ELSE
2257 v_save_measure(j):=v_nom((i-1)*v_max_col_no+j)/v_denom((i-1)*v_max_col_no+j);
2258 END IF;
2259 END IF;
2260 v_nom((i-1)*v_max_col_no+j) := NULL;
2261 v_denom((i-1)*v_max_col_no+j) := NULL;
2262 IF v_need_usd_arr THEN
2263 v_nom_usd((i-1)*v_max_col_no+j) := NULL;
2264 v_denom_usd((i-1)*v_max_col_no+j) := NULL;
2265 END IF;
2266 END LOOP;
2267
2268 --INSERT the old values: v_save_header and
2269 --v_save_measure
2270 v_type := i;
2271 v_hidden := 'Y';
2272 --determine the CCY to be appended after TOTAL
2273 --does not need to worry for the CCY agg logic
2274 --(tot. level),
2275 --bec. it's captured in v_current_ccy
2276 --Make sure that ccy is appended to Total that has
2277 --uniform currency across the columns
2278 IF v_need_usd_arr THEN
2279 IF v_ccy_agg_flag=2 THEN
2280 v_current_ccy := NULL;--cannot display CCY
2281 ELSE --check whether before/after the ccy_agg_level
2282 IF i> v_ccy_agg_level THEN -- Bug 4533431
2283 v_current_ccy := v_row_ccy;
2284 ELSE --v_current_ccy=v_header(ccy_agg_level)
2285 v_current_ccy := v_curr_reporting;
2286 END IF;
2287 END IF;
2288 ELSIF v_ccy_case_flag=2 THEN
2289 v_current_ccy := NULL;--cannot display CCY
2290 ELSE
2291 v_current_ccy := v_underlying_ccy;
2292 END IF;
2293 v_success := insert_row(v_save_header,v_save_measure,
2294 v_row_agg_no,v_max_col_no,
2295 p_name,v_row,v_type,v_hidden,
2296 v_current_ccy,
2297 v_style,p_ref_date,v_ccy_case_flag,
2298 v_ccy_agg_flag,v_col_ccy_multp);
2299 v_current_ccy := NULL; --reset
2300 --delete the previous array content
2301 FOR i IN 1..v_row_agg_no LOOP
2302 v_save_header(i) := NULL;
2303 END LOOP;
2304 FOR i IN 1..v_max_col_no LOOP
2305 v_save_measure(i) := NULL;
2306 END LOOP;
2307 END LOOP;
2308 END IF;
2309 ------------------End Calculating the Total Row--------------------
2310
2311 --insert header increase row count
2312 v_row := v_row+1;
2313 --do not include the column aggregate in the row header
2314 FOR i IN 1..v_row_agg_no LOOP
2315 v_save_header(i):=v_header(i);
2316 --determine the current row ccy
2317 IF v_ccy_agg_level=i AND v_need_usd_arr THEN
2318 v_row_ccy := v_header(i);
2319 END IF;
2320 END LOOP;
2321 END IF;
2322 --insert measure
2323 --v_measure(1) has the Y Axis coordinate
2324 --Total operation
2325 IF v_tot_avg(v_row_agg_no+v_col_agg_no+1)='T' THEN
2326 v_save_measure(v_measure(1)-v_row_agg_no):=v_measure(2);
2327 FOR i IN 1..v_row_agg_no LOOP
2328 --determining the storage location for a specific level
2329 --total
2330 j:=(i-1)*v_max_col_no+(v_measure(1)-v_row_agg_no);
2331 IF v_nom(j) IS NOT NULL THEN
2332 IF v_measure(2) IS NOT NULL THEN
2333 v_nom(j):=v_nom(j)+v_measure(2);
2334 END IF;
2335 ELSE
2336 v_nom(j):=v_measure(2);
2337 END IF;
2338 v_denom(j):=1;
2339 --determining the storage location for USD specific level
2340 --total
2341 IF v_need_usd_arr THEN
2342 IF v_nom_usd(j) IS NOT NULL THEN
2343 IF v_measure(4) IS NOT NULL THEN
2344 v_nom_usd(j):=v_nom_usd(j)+v_measure(4);
2345 END IF;
2346 ELSE
2347 v_nom_usd(j):=v_measure(4);
2348 END IF;
2349 v_denom_usd(j):=1;
2350 END IF;
2351 END LOOP;
2352 --Weighted Average operation
2353 ELSE --insert to side array to be totaled later
2354 IF v_measure(3)=0 THEN
2355 v_save_measure(v_measure(1)-v_row_agg_no):=v_measure(2)/v_divisor;
2356 ELSE
2357 v_save_measure(v_measure(1)-v_row_agg_no):=v_measure(2)/v_measure(3);
2358 END IF;
2359 FOR i IN 1..v_row_agg_no LOOP
2360 --determining the storage location for a specific level
2361 --total
2362 j:=(i-1)*v_max_col_no+(v_measure(1)-v_row_agg_no);
2363 IF v_nom(j) IS NOT NULL THEN
2364 IF v_measure(2) IS NOT NULL THEN
2365 v_nom(j) := v_nom(j)+v_measure(2);
2366 v_denom(j) := v_denom(j)+v_measure(3);
2367 END IF;
2368 ELSE
2369 v_nom(j) := v_measure(2);
2370 v_denom(j) := v_measure(3);
2371 END IF;
2372 --determining the storage location for USD specific level
2373 --total
2374 IF v_need_usd_arr THEN
2375 IF v_nom_usd(j) IS NOT NULL THEN
2376 IF v_measure(4) IS NOT NULL THEN
2377 v_nom_usd(j) := v_nom_usd(j)+v_measure(4);
2378 v_denom_usd(j) := v_denom_usd(j)+v_measure(5);
2379 END IF;
2380 ELSE
2384 END IF;
2381 v_nom_usd(j) := v_measure(4);
2382 v_denom_usd(j) := v_measure(5);
2383 END IF;
2385 END LOOP;
2386 END IF;
2387 END IF; --style
2388 END IF; --v_skip_row
2389
2390 ELSE
2391 --before exit:insert last row and do grand total at the bottom
2392 IF v_row<>0 THEN
2393 --INSERT the old values: v_save_header and v_save_measure
2394 v_type := -1;
2395 v_hidden := 'N';
2396 v_success := insert_row(v_save_header,v_save_measure,
2397 v_row_agg_no,v_max_col_no,
2398 p_name,v_row,v_type,v_hidden,NULL,
2399 v_style,p_ref_date,v_ccy_case_flag,
2400 v_ccy_agg_flag,v_col_ccy_multp);
2401
2402 --start from 1,the grand total
2403 v_total_level := 1;
2404 FOR i IN REVERSE v_total_level..v_row_agg_no LOOP
2405 --delete the previous array content
2406 FOR i IN 1..v_row_agg_no LOOP
2407 v_save_header(i) := NULL;
2408 END LOOP;
2409 FOR i IN 1..v_max_col_no LOOP
2410 v_save_measure(i) := NULL;
2411 END LOOP;
2412 v_row := v_row+1;
2413 v_save_header(i) := 'TOTAL';
2414 -- loop through the measures total
2415 FOR j IN 1..v_max_col_no LOOP
2416 --determine whether to fetch USD arr or reg. arr
2417 IF v_need_usd_arr AND i<=v_ccy_agg_level
2418 AND v_ccy_agg_flag<>2 THEN --bug 2566711
2419 IF v_denom_usd((i-1)*v_max_col_no+j)=0 THEN
2420 v_save_measure(j):=v_nom_usd((i-1)*v_max_col_no+j)/v_divisor;
2421 ELSE
2422 v_save_measure(j):=v_nom_usd((i-1)*v_max_col_no+j)/v_denom_usd((i-1)*v_max_col_no+j);
2423 END IF;
2424 ELSE
2425 IF v_denom((i-1)*v_max_col_no+j)=0 THEN
2426 v_save_measure(j):=v_nom((i-1)*v_max_col_no+j)/v_divisor;
2427 ELSE
2428 v_save_measure(j):=v_nom((i-1)*v_max_col_no+j)/v_denom((i-1)*v_max_col_no+j);
2429 END IF;
2430 END IF;
2431 v_nom((i-1)*v_max_col_no+j) := NULL;
2432 v_denom((i-1)*v_max_col_no+j) := NULL;
2433 IF v_need_usd_arr THEN
2434 v_nom_usd((i-1)*v_max_col_no+j) := NULL;
2435 v_denom_usd((i-1)*v_max_col_no+j) := NULL;
2436 END IF;
2437 END LOOP;
2438 --INSERT total
2439 v_type := i;
2440 v_hidden := 'Y';
2441 --determine the CCY to be appended after TOTAL
2442 --does not need to worry for the CCY agg logic (tot. level),
2443 --bec. it's captured in v_current_ccy
2444 IF v_need_usd_arr THEN
2445 IF v_ccy_agg_flag=2 THEN
2446 v_current_ccy := NULL;--cannot display CCY
2447 ELSE --check whether before/after the ccy_agg_level
2448 IF i > v_ccy_agg_level THEN --Bug 4533431
2449 v_current_ccy := v_row_ccy;
2450 ELSE --v_current_ccy=v_header(ccy_agg_level)
2451 v_current_ccy := v_curr_reporting;
2452 END IF;
2453 END IF;
2454 ELSIF v_ccy_case_flag=2 THEN
2455 v_current_ccy := NULL;--cannot display CCY
2456 ELSE
2457 v_current_ccy := v_underlying_ccy;
2458 END IF;
2459 v_success := insert_row(v_save_header,v_save_measure,
2460 v_row_agg_no,v_max_col_no,
2461 p_name,v_row,v_type,v_hidden,
2462 v_current_ccy,
2463 v_style,p_ref_date,v_ccy_case_flag,
2464 v_ccy_agg_flag,v_col_ccy_multp);
2465 END LOOP;
2466 END IF;
2467 EXIT;
2468 END IF;
2469 END LOOP;
2470
2471 COMMIT;
2472 dbms_sql.close_cursor(v_cursor);
2473
2474 --update total
2475 v_success := update_total(p_name,p_ref_date);
2476 IF (g_proc_level>=g_debug_level) THEN
2477 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_successT',v_success);
2478 END IF;
2479 IF NOT v_success THEN
2480 RAISE e_pagg_update_total_fail;
2481 END IF;
2482 --find out NOCOPY currency for each saved cells in the table
2483 v_success := update_aggregate_curr(p_name,p_ref_date,v_ccy_case_flag,
2484 v_ccy_agg_flag,v_ccy_agg_level,v_row_agg_no,v_max_col_no,
2485 v_underlying_ccy,v_currency_source,v_curr_reporting,v_agg_col_curr);
2486
2487 IF (g_proc_level>=g_debug_level) THEN
2488 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_successCurr',v_success);
2489 END IF;
2490 IF NOT v_success THEN
2491 RAISE e_pagg_update_agg_curr_fail;
2492 END IF;
2493 --update percent
2494 v_success := update_percent (p_name,v_style,v_row_agg_no,v_max_col_no,
2495 p_ref_date,v_md_set_code);
2496 IF (g_proc_level>=g_debug_level) THEN
2497 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_success%',v_success);
2498 END IF;
2499 IF NOT v_success THEN
2500 RAISE e_pagg_update_percent_fail;
2501 END IF;
2502 IF v_style='C' THEN
2503 v_success := update_label(p_name,v_agg,v_col_order,v_att_type,p_ref_date);
2504 IF (g_proc_level>=g_debug_level) THEN
2505 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_successL',v_success);
2506 END IF;
2510 END IF;
2507 IF NOT v_success THEN
2508 RAISE e_pagg_update_label_fail;
2509 END IF;
2511 --update timebuckets label
2512 IF v_style='X' AND p_caller_flag='OA' THEN
2513 v_success := update_timebuckets_label(p_name);
2514 IF (g_proc_level>=g_debug_level) THEN
2515 xtr_risk_debug_pkg.dlog('transform_and_save: ' || 'v_successTBLabel',v_success);
2516 END IF;
2517 IF NOT v_success THEN
2518 RAISE e_pagg_update_tb_label_fail;
2519 END IF;
2520 END IF;
2521
2522 --update dirty column if called from 'OA'
2523 IF p_caller_flag='OA' THEN
2524 UPDATE qrm_analysis_settings SET dirty='N' WHERE analysis_name=p_name;
2525
2526 IF (g_event_level>=g_debug_level) THEN --bug 3236479
2527 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_ANALYSIS_SETTINGS.DIRTY=N',
2528 'QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_event_level);
2529 END IF;
2530
2531 END IF;
2532
2533 COMMIT;
2534 IF (g_proc_level>=g_debug_level) THEN
2535 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE');
2536 END IF;
2537 RETURN 'T';
2538
2539 EXCEPTION
2540 WHEN e_pagg_no_fxrate_found THEN
2541 IF p_caller_flag='CONC' THEN
2542 RAISE e_pagg_no_fxrate_found;
2543 ELSE
2544 fnd_msg_pub.add;
2545 END IF;
2546 IF (g_error_level>=g_debug_level) THEN
2547 xtr_risk_debug_pkg.dlog('EXCEPTION','e_pagg_no_fxrate_found','QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_error_level);--bug 3236479
2548 --xtr_risk_debug_pkg.dpop('transform_and_save: ' || 'QRM_PA_AGGREGATION_P.T_AND_S');
2549 END IF;
2550 RETURN 'F';
2551 WHEN e_pagg_no_timebuckets_found THEN
2552 IF p_caller_flag='CONC' THEN
2553 RAISE e_pagg_no_timebuckets_found;
2554 ELSE
2555 fnd_msg_pub.add;
2556 END IF;
2557 IF (g_error_level>=g_debug_level) THEN
2558 xtr_risk_debug_pkg.dlog('EXCEPTION','e_pagg_no_timebuckets_found','QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_error_level);--bug 3236479
2559 --xtr_risk_debug_pkg.dpop('transform_and_save: ' || 'QRM_PA_AGGREGATION_P.T_AND_S');
2560 END IF;
2561 RETURN 'F';
2562 WHEN e_pagg_no_setting_found THEN
2563 IF p_caller_flag='CONC' THEN
2564 RAISE e_pagg_no_setting_found;
2565 ELSE
2566 fnd_msg_pub.add;
2567 END IF;
2568 IF (g_error_level>=g_debug_level) THEN
2569 xtr_risk_debug_pkg.dlog('EXCEPTION','e_pagg_no_setting_found','QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_error_level);--bug 3236479
2570 --xtr_risk_debug_pkg.dpop('transform_and_save: ' || 'QRM_PA_AGGREGATION_P.T_AND_S');
2571 END IF;
2572 RETURN 'F';
2573 WHEN OTHERS THEN
2574 IF p_caller_flag='OA' THEN
2575 FND_MESSAGE.SET_NAME('QRM','QRM_ANA_UNEXPECTED_ERROR');
2576 fnd_msg_pub.add;
2577 END IF;
2578 IF (g_error_level>=g_debug_level) THEN
2579 xtr_risk_debug_pkg.dlog('EXCEPTION','others','QRM_PA_AGGREGATION_P.TRANSFORM_AND_SAVE',g_error_level);--bug 3236479
2580 --xtr_risk_debug_pkg.dpop('transform_and_save: ' || 'QRM_PA_AGGREGATION_P.T_AND_S');
2581 END IF;
2582 RETURN 'F';
2583 END transform_and_save;
2584
2585
2586
2587 /***************************************************************
2588 This function check whether a particular date is a holiday or not
2589 in GL Calendar and if so, find the next/previous business day.
2590
2591 If anything goes wrong during the operation, the function will
2592 return the date passed in as the argument.
2593 ***************************************************************/
2594 -- from GL Calendar
2595 FUNCTION find_gl_business_days(p_indicator VARCHAR2,
2596 --'F'=forward next bus.days,'B'=backward next bus.days
2597 p_date_in DATE,
2598 p_calendar_id NUMBER)
2599 RETURN DATE IS
2600 v_date_out DATE;
2601 v_move VARCHAR2(1); --'B' for backward,'F' for forward
2602 v_day VARCHAR2(3);
2603 v_week SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
2604 v_day_no NUMBER;
2605 i NUMBER(1);
2606 j NUMBER(1);
2607 v_found BOOLEAN := FALSE;
2608 BEGIN
2609
2610 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
2611 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.FIND_GL_BUSINESS_DAY');
2612 END IF;
2613
2614 IF p_calendar_id IS NULL THEN
2615 v_date_out := p_date_in;
2616 ELSE
2617 IF p_indicator='F' THEN --find the next bus. day forward
2618 SELECT MIN(transaction_date)
2619 INTO v_date_out
2620 FROM gl_transaction_dates
2621 WHERE transaction_calendar_id = p_calendar_id
2622 AND TRUNC(transaction_date) >= TRUNC(p_date_in)
2623 AND business_day_flag = 'Y';
2624 ELSIF p_indicator='B' THEN --find the next bus. day backward
2625 SELECT MAX(transaction_date)
2626 INTO v_date_out
2627 FROM gl_transaction_dates
2628 WHERE transaction_calendar_id = p_calendar_id
2629 AND TRUNC(transaction_date) <= TRUNC(p_date_in)
2630 AND business_day_flag = 'Y';
2631 ELSE
2632 RAISE_APPLICATION_ERROR
2633 (-20001,'Invalid Interval Type of Time-Buckets');
2634 END IF;
2635 END IF;
2636
2637 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
2638 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.FIND_GL_BUSINESS_DAY');
2639 END IF;
2640
2641 RETURN v_date_out;
2642 EXCEPTION
2643 WHEN OTHERS THEN
2644
2645 IF (g_error_level>=g_debug_level) THEN --bug 3236479
2646 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS','QRM_PA_AGGREGATION_P.FIND_GL_BUSINESS_DAY',g_error_level);
2647 END IF;
2648
2649 RETURN p_date_in;
2650 END find_gl_business_days;
2651
2652
2653
2654 /********************************************************************
2655 get_beg_end_of_week
2656 Procedure that provides the beginning and end of the week given a
2657 reference date, based on a GL Transaction Calendar. In the case
2658 where there are either no or all business days, it defines the
2659 first of the week by following NLS_TERRITORY settings.
2660
2661 This procedure attempts to determine the beginning of the week by
2662 looking for the first business day following a "block" of
2663 non-business days.
2664
2665 In the case where there are multiple "blocks" of non-business days
2666 it will be based on the "block" that ends closest to (but on or
2667 after) Friday.
2668
2669 p_gl_trans_calendar_id - GL Transacation Calendar ID
2670 p_ref_date - Reference date
2671 p_beg_date - Beginning of the week
2672 p_end_date - End of the week
2673 ********************************************************************/
2674 PROCEDURE get_beg_end_of_week(p_gl_trans_calendar_id IN NUMBER,
2675 p_ref_date IN DATE,
2676 p_beg_date OUT NOCOPY DATE,
2677 p_end_date OUT NOCOPY DATE) IS
2678 --
2679 -- Be very careful when modifying this. The code runs on the
2680 -- the assumption that Friday comes first.
2681 CURSOR days_of_week_cursor IS
2682 SELECT
2683 fri_business_day_flag,
2684 sat_business_day_flag,
2685 sun_business_day_flag,
2686 mon_business_day_flag,
2687 tue_business_day_flag,
2688 wed_business_day_flag,
2689 thu_business_day_flag
2690 FROM gl_transaction_calendar
2691 WHERE transaction_calendar_id = p_gl_trans_calendar_id;
2692 --
2693 v_day_table SYSTEM.QRM_VARCHAR_TABLE;
2694 v_fri GL_TRANSACTION_CALENDAR.SAT_BUSINESS_DAY_FLAG%TYPE;
2695 v_sat GL_TRANSACTION_CALENDAR.SAT_BUSINESS_DAY_FLAG%TYPE;
2696 v_sun GL_TRANSACTION_CALENDAR.SAT_BUSINESS_DAY_FLAG%TYPE;
2697 v_mon GL_TRANSACTION_CALENDAR.SAT_BUSINESS_DAY_FLAG%TYPE;
2698 v_tue GL_TRANSACTION_CALENDAR.SAT_BUSINESS_DAY_FLAG%TYPE;
2699 v_wed GL_TRANSACTION_CALENDAR.SAT_BUSINESS_DAY_FLAG%TYPE;
2700 v_thu GL_TRANSACTION_CALENDAR.SAT_BUSINESS_DAY_FLAG%TYPE;
2701 --
2702 v_last_nonbus_day NUMBER := 0;
2703 v_nonbus_count NUMBER := 0;
2704 v_ref_day NUMBER;
2705 v_days_before NUMBER;
2706 v_offset NUMBER;
2707 --
2708 BEGIN
2709 IF (g_proc_level>=g_debug_level) THEN
2710 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.get_beg_end_of_week');
2711 END IF;
2712
2713 OPEN days_of_week_cursor;
2714 FETCH days_of_week_cursor INTO v_fri,v_sat,v_sun,v_mon,v_tue,v_wed,v_thu;
2715 CLOSE days_of_week_cursor;
2716
2717 -- Put the days of the week in an array for code cleanliness.
2718 v_day_table := SYSTEM.QRM_VARCHAR_table(Nvl(v_fri, 'Y'), Nvl(v_sat, 'Y'),
2719 Nvl(v_sun, 'Y'), Nvl(v_mon, 'Y'), Nvl(v_tue, 'Y'),
2720 Nvl(v_wed, 'Y'), Nvl(v_thu, 'Y'));
2721
2722 -- First go from top to bottom (Friday to Thursday)
2723 FOR i IN 1..v_day_table.count LOOP
2724 -- If non-business day, then we want to add to the count of the
2725 -- number of days this "block" of non-business days consists of
2726 IF v_day_table(i) = 'N' THEN
2727 v_nonbus_count := v_nonbus_count + 1;
2728 v_last_nonbus_day := i;
2729 ELSE
2730 -- If we hit a business day, and we've already encounted a non-business
2731 -- day "block" (count>0), we're done.
2732 IF v_nonbus_count > 0 THEN
2733 EXIT;
2734 END IF;
2735 END IF;
2736 END LOOP;
2737
2738 -- Now we just have to make sure this "block" of non-business days
2739 -- is not any bigger than it seems. It is bigger if it starts on
2740 -- the first day and the last day turns out NOCOPY to be a non-business
2741 -- day as well. If this is the case, we need to increase the "block"
2742 -- size, by running backwards.
2743 IF v_day_table(1) = 'N' AND v_day_table(7)= 'N' THEN
2744 FOR i IN REVERSE 1..v_day_table.count LOOP
2745 -- If non-business day, we continue add to the "block" size.
2746 IF v_day_table(i) = 'N' THEN
2747 v_nonbus_count := v_nonbus_count + 1;
2748 ELSE
2749 EXIT;
2750 END IF;
2751 END LOOP;
2752 END IF;
2753
2754 IF (g_proc_level>=g_debug_level) THEN
2755 xtr_risk_debug_pkg.dlog('get_beg_end_of_week: ' || 'v_last_nonbus_day',v_last_nonbus_day);
2756 xtr_risk_debug_pkg.dlog('get_beg_end_of_week: ' || 'v_nonbus_count',v_nonbus_count);
2757 END IF;
2758
2759 IF v_nonbus_count <= 0 OR v_nonbus_count >= 7 THEN
2760 p_beg_date := trunc(p_ref_date,'D');
2761 p_end_date := trunc(p_ref_date,'D')+6;
2762 ELSE
2763 -- TO_CHAR with 'D' format returns 1-7 for SUN-SAT (dependent on
2764 -- NLS_TERRITORY settings).
2765 -- Since this changes depending on the customer settings,
2766 -- we need a fixed reference point (Fri 5/31/2002).
2767 -- Now that we know NLS number system, we will apply that "offset"
2768 -- to our ref_date so that it is back in our system (where Friday
2769 -- is 1). If Friday is no longer 1, we would need to pick a date
2770 -- that falls on that new reference day.
2771 v_offset := to_number(to_char(to_date('05/31/2002','MM/DD/YYYY'),'D'))-1;
2772 v_ref_day := to_number(to_char(p_ref_date,'D')) - v_offset;
2773 -- If negative, need to wrap so represent the correct day
2774 IF v_ref_day < 0 THEN
2775 v_ref_day := v_ref_day + 7;
2776 END IF;
2777 -- If negative, need to wrap so represent the correct day
2778 v_days_before := v_ref_day - (v_last_nonbus_day + 1);
2779 IF v_days_before < 0 THEN
2780 v_days_before := v_days_before + 7;
2781 END IF;
2782 p_beg_date := trunc(p_ref_date) - v_days_before;
2783 p_end_date := trunc(p_ref_date) + (7 - (v_days_before + v_nonbus_count) - 1);
2784
2785 IF (g_proc_level>=g_debug_level) THEN
2786 xtr_risk_debug_pkg.dlog('get_beg_end_of_week: ' || 'v_ref_day',v_ref_day);
2787 xtr_risk_debug_pkg.dlog('get_beg_end_of_week: ' || 'v_days_before',v_days_before);
2788 END IF;
2789 END IF;
2790
2791 IF (g_proc_level>=g_debug_level) THEN
2792 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGRREGATION_P.get_beg_end_of_week');
2793 END IF;
2794 END get_beg_end_of_week;
2795
2796
2797
2798 /***************************************************************
2799 This function calculates the actual date givent the relative date
2800 ,fixed date, and the date type.
2801 ***************************************************************/
2802 FUNCTION calculate_relative_date(p_ref_date DATE,
2803 p_date_type VARCHAR2,
2804 p_as_of_date DATE,
2805 p_start_date_ref VARCHAR2,
2806 p_start_date_offset NUMBER,
2807 p_start_offset_type VARCHAR2,
2808 p_calendar_id NUMBER,
2809 p_business_week VARCHAR2)
2810 RETURN DATE IS
2811 v_date DATE;
2812 v_dummy DATE;
2813 BEGIN
2814
2815 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
2816 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGRREGATION_P.CALCULATE_RELATIVE_DATE');
2817 END IF;
2818
2819 --see whether the as of date is fixed or relative
2820 IF p_date_type='F' THEN
2821 v_date := TRUNC(p_as_of_date);
2822 IF (g_proc_level>=g_debug_level) THEN
2823 xtr_risk_debug_pkg.dlog('calculate_relative_date: ' || 'v_date',v_date);
2824 END IF;
2825 ELSE
2826 --reference
2827 IF p_start_date_ref='BW' THEN --Beginning of Week
2828 get_beg_end_of_week(p_calendar_id,TRUNC(p_ref_date),v_date,v_dummy);
2829 ELSIF p_start_date_ref='BM' THEN --Beginning of Month
2830 v_date := TRUNC(p_ref_date,'MONTH');
2831 ELSIF p_start_date_ref='BY' THEN --Beginning of Year
2832 v_date := TRUNC(p_ref_date,'YEAR');
2833 ELSIF p_start_date_ref='S' THEN --p_ref_date
2834 v_date := TRUNC(p_ref_date);
2835 ELSIF p_start_date_ref='EW' THEN --End of Week
2836 get_beg_end_of_week(p_calendar_id,TRUNC(p_ref_date),v_dummy,v_date);
2837 ELSIF p_start_date_ref='EM' THEN --End of Month
2838 v_date := ADD_MONTHS(TRUNC(p_ref_date,'MONTH'),1)-1;
2839 ELSIF p_start_date_ref='EY' THEN --End of Year
2840 v_date := ADD_MONTHS(TRUNC(p_ref_date,'YEAR'),12)-1;
2841 ELSE
2842 RAISE_APPLICATION_ERROR
2843 (-20001,'Invalid start_date_ref.');
2844 END IF;
2845 --offset
2846 IF p_start_date_offset IS NOT NULL THEN
2847 IF p_start_offset_type='D' THEN
2848 v_date := v_date+p_start_date_offset;
2849 ELSIF p_start_offset_type='W' THEN
2850 v_date := v_date+7*p_start_date_offset;
2851 ELSIF p_start_offset_type='M' THEN
2852 v_date := ADD_MONTHS(v_date,p_start_date_offset);
2853 ELSIF p_start_offset_type='Y' THEN
2854 v_date := ADD_MONTHS(v_date,12*p_start_date_offset);
2855 ELSE
2856 RAISE_APPLICATION_ERROR
2857 (-20001,'Invalid start_offset_type.');
2858 END IF;
2859 END IF;
2860 END IF;
2861 IF (g_proc_level>=g_debug_level) THEN
2862 xtr_risk_debug_pkg.dlog('calculate_relative_date: ' || 'v_date',v_date);
2863 xtr_risk_debug_pkg.dlog('calculate_relative_date: ' || 'p_calendar_id',p_calendar_id);
2864 END IF;
2865 --Only check holiday if p_business_week='C' otherwise
2866 --assume 7-days-week
2867 IF p_business_week='C' THEN
2868 v_date := find_gl_business_days('F',
2869 v_date, p_calendar_id);
2870 END IF;
2871
2872 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
2873 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGRREGATION_P.CALCULATE_RELATIVE_DATE');
2874 END IF;
2875
2876 RETURN v_date;
2877 END calculate_relative_date;
2878
2879
2880
2881 /***************************************************************
2882 This procedure calculates the time-buckets interval actual
2883 dates and saved them intot qrm_saved_analyses_col
2884 ***************************************************************/
2885 PROCEDURE update_timebuckets (p_name VARCHAR2,
2886 p_ref_date DATE,
2887 p_tb_name VARCHAR2,
2888 p_tb_label VARCHAR2,
2889 p_as_of_date DATE,
2890 p_start_date_ref VARCHAR2,
2891 p_start_date_offset NUMBER,
2892 p_start_offset_type VARCHAR2,
2893 p_row_agg_no NUMBER,
2894 p_max_col_no OUT NOCOPY NUMBER,
2895 p_date_type VARCHAR2,
2896 p_calendar_id NUMBER,
2897 p_business_week VARCHAR2,
2898 p_col_seq_no IN OUT NOCOPY XTR_MD_NUM_TABLE,
2899 p_col_seq_no_key IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
2900 p_col_name_map IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
2901 p_percent_col_name_map IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
2902 p_a1 IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
2903 p_col_type IN OUT NOCOPY XTR_MD_NUM_TABLE,
2904 p_col_hidden IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
2905 p_start_date IN OUT NOCOPY SYSTEM.QRM_DATE_TABLE,
2906 p_end_date IN OUT NOCOPY SYSTEM.QRM_DATE_TABLE,
2907 p_tb_label_arr IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE) IS
2908
2909 CURSOR v_tb_cursor IS
2910 SELECT interval_length, interval_type, label
2911 FROM qrm_time_intervals
2912 WHERE tb_name = p_tb_name AND sequence_number<>0
2913 ORDER BY sequence_number;
2914 CURSOR v_find_tb IS
2915 SELECT COUNT(*) FROM qrm_time_buckets
2916 WHERE tb_name = p_tb_name;
2917 v_int_length xtr_md_num_table;
2918 v_int_type SYSTEM.QRM_VARCHAR_table;
2919 v_label SYSTEM.QRM_VARCHAR_table;
2920 v_date DATE;
2921 v_prev_end_date DATE;
2922 v_dummy NUMBER;
2923 i NUMBER(5);
2924 j NUMBER(5);
2925 BEGIN
2926 IF (g_proc_level>=g_debug_level) THEN
2927 xtr_risk_debug_pkg.dpush(null,'QRM_PA_P.UPDATE_TIMEBUCKETS'); --bug3236479
2928 END IF;
2929
2930 --check whether time buckets exist
2931 OPEN v_find_tb;
2932 FETCH v_find_tb INTO v_dummy;
2933 CLOSE v_find_tb;
2934 IF v_dummy=0 THEN
2935 FND_MESSAGE.SET_NAME('QRM','QRM_ANA_NO_TIMEBUCKETS');
2936 FND_MESSAGE.SET_TOKEN('TB_NAME',p_tb_name);
2937 RAISE e_pagg_no_timebuckets_found;
2938 END IF;
2939
2940 OPEN v_tb_cursor;
2941 FETCH v_tb_cursor BULK COLLECT INTO v_int_length,v_int_type,v_label;
2942 p_max_col_no := v_int_length.LAST;
2943 CLOSE v_tb_cursor;
2944
2945 --construct p_seq_no, p_a1, p_hidden, p_type
2946 p_col_name_map.EXTEND(p_max_col_no);
2947 p_percent_col_name_map.EXTEND(p_max_col_no);
2948 p_a1.EXTEND(p_max_col_no);
2952 p_col_seq_no_key.EXTEND(p_max_col_no);
2949 p_col_seq_no.EXTEND(p_max_col_no);
2950 p_col_type.EXTEND(p_max_col_no);
2951 p_col_hidden.EXTEND(p_max_col_no);
2953 --start and end date has not been initilized earlier, thus, lacking
2954 --p_row_agg_no rows
2955 p_start_date.EXTEND(p_max_col_no+p_row_agg_no);
2956 p_end_date.EXTEND(p_max_col_no+p_row_agg_no);
2957 p_tb_label_arr.EXTEND(p_max_col_no+p_row_agg_no);
2958
2959 --for the rest of the timebuckets
2960 FOR i IN p_row_agg_no+1..(p_row_agg_no+p_max_col_no) LOOP
2961 --find start date = previous end date + 1
2962 IF i=p_row_agg_no+1 THEN --for the first case/timebucket
2963 p_start_date(i) := calculate_relative_date(p_ref_date,
2964 p_date_type,
2965 p_as_of_date,
2966 p_start_date_ref,
2967 p_start_date_offset,
2968 p_start_offset_type,
2969 p_calendar_id,
2970 p_business_week);
2971 v_prev_end_date := p_start_date(i);
2972 ELSE
2973 IF p_business_week='C' THEN
2974 p_start_date(i) := find_gl_business_days('F',
2975 p_end_date(i-1)+1,p_calendar_id);
2976 ELSE
2977 p_start_date(i) := p_end_date(i-1)+1;
2978 END IF;
2979 --need the -1 since timebucket start and end date cannot overlap.
2980 v_prev_end_date := p_start_date(i);
2981 END IF;
2982 IF (g_proc_level>=g_debug_level) THEN
2983 xtr_risk_debug_pkg.dlog('p_start_date(i)',i||':'||p_start_date(i));
2984 END IF;
2985 xtr_risk_debug_pkg.dlog('v_int_type(i),v_int_length(i)',i||':'||v_int_type(i-p_row_agg_no)||','||v_int_length(i-p_row_agg_no));
2986 IF (g_proc_level>=g_debug_level) THEN
2987 xtr_risk_debug_pkg.dlog('v_prev_end_date',v_prev_end_date);
2988 END IF;
2989 --find temp end date
2990 IF v_int_type(i-p_row_agg_no)='D' THEN
2991 v_date := v_prev_end_date+v_int_length(i-p_row_agg_no);
2992 ELSIF v_int_type(i-p_row_agg_no)='W' THEN
2993 v_date := v_prev_end_date+7*v_int_length(i-p_row_agg_no);
2994 ELSIF v_int_type(i-p_row_agg_no)='M' THEN
2995 v_date := add_months(v_prev_end_date,v_int_length(i-p_row_agg_no));
2996 ELSIF v_int_type(i-p_row_agg_no)='Y' THEN
2997 v_date := add_months(v_prev_end_date,12*v_int_length(i-p_row_agg_no));
2998 ELSE
2999 RAISE_APPLICATION_ERROR
3000 (-20001,'Invalid Interval Type of Time-Buckets');
3001 END IF;
3002 --find actual end date
3003 IF p_business_week='C' THEN
3004 p_end_date(i) := find_gl_business_days('B',v_date-1,p_calendar_id);
3005 ELSE
3006 p_end_date(i) := v_date-1;
3007 END IF;
3008 --xtr_risk_debug_pkg.dlog('p_end_date(i)',i||':'||p_end_date(i));
3009 p_col_seq_no(i) := i;
3010 p_col_seq_no_key(i) := TO_CHAR(i);
3011 p_col_name_map(i) := 'M'||TO_CHAR(i-p_row_agg_no);
3012 p_percent_col_name_map(i) := 'P'||TO_CHAR(i-p_row_agg_no);
3013 p_tb_label_arr(i) := v_label(i-p_row_agg_no);
3014 --logic whether to look for TB Label or display the end date
3015 IF p_tb_label='L' THEN
3016 p_a1(i) := p_tb_label_arr(i);
3017 ELSE--p_tb_label='D'
3018 p_a1(i) := TO_CHAR(TRUNC(p_end_date(i)));
3019 END IF;
3020 p_col_type(i) := -1; --measure type
3021 p_col_hidden(i) := 'N';
3022 END LOOP;
3023
3024 IF (g_proc_level>=g_debug_level) THEN
3025 xtr_risk_debug_pkg.dpop(null,'QRM_PA_P.UPDATE_TIMEBUCKETS');--bug 3236479
3026 END IF;
3027 END update_timebuckets;
3028
3029
3030
3031 /***************************************************************
3032 This procedure calculates the time-buckets start date and end date
3033 and used by qrmpacab.pls
3034
3035 IMPORTANT:
3036 For Timebuckets style, there is a discrepancy between the start
3037 and end date in the DB and in the display.
3038 END_DATE in DB for style=X means the first
3039 START_DATE in the Timebuckets display.
3040 That's why this procedure passes in DB's END_DATE in what should've
3041 been the Timebuckets START_DATE only when analysis type='P'.
3042 (Bug 2355584 no.2)
3043 ***************************************************************/
3044 PROCEDURE calc_tb_start_end_dates (p_name VARCHAR2,
3045 p_ref_date DATE,
3046 p_tb_name VARCHAR2,
3047 p_tb_label VARCHAR2,
3048 p_end_date IN OUT NOCOPY DATE,
3049 p_end_date_ref IN OUT NOCOPY VARCHAR2,
3050 p_end_date_offset IN OUT NOCOPY NUMBER,
3051 p_end_offset_type IN OUT NOCOPY VARCHAR2,
3052 p_date_type VARCHAR2,
3053 p_calendar_id NUMBER,
3054 p_business_week VARCHAR2,
3055 p_start_date IN OUT NOCOPY DATE,
3056 p_start_date_ref IN OUT NOCOPY VARCHAR2,
3057 p_start_date_offset IN OUT NOCOPY NUMBER,
3058 p_start_offset_type IN OUT NOCOPY VARCHAR2,
3059 p_analysis_type VARCHAR2) IS
3060
3061 v_col_seq_no XTR_MD_NUM_TABLE := XTR_MD_NUM_TABLE();
3062 v_col_seq_no_key SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
3063 v_col_name_map SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
3064 v_percent_col_name_map SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
3065 v_a1 SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
3066 v_col_type XTR_MD_NUM_TABLE := XTR_MD_NUM_TABLE();
3067 v_col_hidden SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
3068 v_start_date SYSTEM.QRM_DATE_TABLE := SYSTEM.QRM_DATE_TABLE();
3069 v_end_date SYSTEM.QRM_DATE_TABLE := SYSTEM.QRM_DATE_TABLE();
3070 v_tb_label_arr SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
3071 v_row_agg_no NUMBER := 0;
3072 v_max_col_no NUMBER;
3073
3074 BEGIN
3075 IF (g_proc_level>=g_debug_level) THEN
3076 xtr_risk_debug_pkg.dpush(null,'QRM_PA_P.CALC_TB_START_END_DATE');--bug 3236479
3077 END IF;
3078 --need to swap because the END_DATE is the start date for the
3079 --timebuckets
3080 update_timebuckets(p_name, p_ref_date, p_tb_name, p_tb_label, p_end_date,
3081 p_end_date_ref, p_end_date_offset,
3082 p_end_offset_type, v_row_agg_no, v_max_col_no,
3083 p_date_type, p_calendar_id, p_business_week,
3084 v_col_seq_no, v_col_seq_no_key, v_col_name_map,
3085 v_percent_col_name_map, v_a1, v_col_type,
3086 v_col_hidden, v_start_date, v_end_date,
3087 v_tb_label_arr);
3088 p_start_date := v_start_date(1);
3089 p_start_date_ref := p_end_date_ref;
3090 p_start_date_offset := p_end_date_offset;
3091 p_start_offset_type := p_end_offset_type;
3092 p_end_date := v_end_date(v_end_date.LAST);
3093
3094 IF (g_proc_level>=g_debug_level) THEN
3095 xtr_risk_debug_pkg.dpop(null,'QRM_PA_P.CALC_TB_START_END_DATE');--bug 3236479
3096 END IF;
3097 END calc_tb_start_end_dates;
3098
3099
3100
3101 /***************************************************************
3102 This function should be used
3103 everytime the Total page is modified.
3104 ***************************************************************/
3105 FUNCTION update_total(p_name VARCHAR2, p_ref_date DATE) RETURN BOOLEAN IS
3106 BEGIN
3107 IF (g_proc_level>=g_debug_level) THEN
3108 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_TOTAL');--bug 3236479
3109 END IF;
3110 --update qrm_saved_analyses_row first
3111 --set all the total rows to be hidden
3112 UPDATE qrm_saved_analyses_row
3113 SET hidden='Y', last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3114 WHERE type>0 AND analysis_name=p_name;
3115
3116 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3117 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_ROW.HIDDEN=Y',
3118 'QRM_PA_AGGREGATION_P.UPDATE_TOTAL',g_event_level);
3119 END IF;
3120
3121 --set selected total rows to be displayed
3122 UPDATE qrm_saved_analyses_row
3123 SET hidden='N', last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3124 WHERE analysis_name=p_name
3125 AND type IN (SELECT att_order FROM qrm_analysis_atts
3126 WHERE analysis_name=p_name
3127 AND total_ind<>'N'
3128 AND type='R'
3129 AND history_flag='S');
3130
3131 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3132 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_ROW.HIDDEN=N for those that need to be displayed',
3133 'QRM_PA_AGGREGATION_P.UPDATE_TOTAL',g_event_level);
3134 END IF;
3135
3136 --update qrm_saved_analyses_col
3137 --set all the total rows to be hidden
3138 UPDATE qrm_saved_analyses_col
3139 SET hidden='Y', last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3140 WHERE type>0 AND analysis_name=p_name;
3141
3142 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3143 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_COL.HIDDEN=Y',
3144 'QRM_PA_AGGREGATION_P.UPDATE_TOTAL',g_event_level);
3145 END IF;
3146
3147 --set selected total rows to be displayed
3148 UPDATE qrm_saved_analyses_col
3149 SET hidden='N', last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3150 WHERE analysis_name=p_name
3151 AND type IN (SELECT att_order FROM qrm_analysis_atts
3152 WHERE analysis_name=p_name
3153 AND total_ind<>'N'
3154 AND type='C'
3155 AND history_flag='S');
3156
3157 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3158 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_COL.HIDDEN=N for those that need to be displayed',
3159 'QRM_PA_AGGREGATION_P.UPDATE_TOTAL',g_event_level);
3160 END IF;
3161
3162 COMMIT;
3163 IF (g_proc_level>=g_debug_level) THEN
3164 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_TOTAL');--bug 3236479
3165 END IF;
3166 RETURN TRUE;
3167 EXCEPTION
3168 WHEN OTHERS THEN
3169 IF (g_error_level>=g_debug_level) THEN
3170 --xtr_risk_debug_pkg.dpop('QRM_PA_AGGREGATION_P.UPDATE_TOTAL');
3171 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS','QRM_PA_AGGREGATION_P.UPDATE_TOTAL',g_error_level);--bug 3236479
3172 END IF;
3173 RETURN FALSE;
3174 END update_total;
3175
3176
3177
3178 /***************************************************************
3179 This function updates the percent columns (P1..P100) given
3180 the analysis name and seq_no, one row at the time.
3181 ***************************************************************/
3182 FUNCTION update_percent_cols(p_name VARCHAR2,
3183 p_row NUMBER,
3184 p_ref_date DATE,
3185 p_meas XTR_MD_NUM_TABLE)
3186 RETURN BOOLEAN IS
3187 BEGIN
3188
3189 IF (g_proc_level>=g_debug_level) THEN
3190 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_PERCENT_COLS');--bug 3236479
3191 END IF;
3192
3193 UPDATE qrm_saved_analyses_row
3194 SET p1=p_meas(1),p2=p_meas(2),p3=p_meas(3),
3195 p4=p_meas(4),p5=p_meas(5),p6=p_meas(6),
3196 p7=p_meas(7),p8=p_meas(8),p9=p_meas(9),
3197 p10=p_meas(10),p11=p_meas(11),
3198 p12=p_meas(12),
3199 p13=p_meas(13),p14=p_meas(14),
3200 p15=p_meas(15),
3201 p16=p_meas(16),p17=p_meas(17),
3202 p18=p_meas(18),
3203 p19=p_meas(19),p20=p_meas(20),
3204 p21=p_meas(21),p22=p_meas(22),
3205 p23=p_meas(23),
3206 p24=p_meas(24),p25=p_meas(25),
3207 p26=p_meas(26),
3208 p27=p_meas(27),p28=p_meas(28),
3209 p29=p_meas(29),
3210 p30=p_meas(30),p31=p_meas(31),
3211 p32=p_meas(32),
3212 p33=p_meas(33),p34=p_meas(34),
3213 p35=p_meas(35),
3214 p36=p_meas(36),p37=p_meas(37),
3215 p38=p_meas(38),
3216 p39=p_meas(39),p40=p_meas(40),
3217 p41=p_meas(41),p42=p_meas(42),
3218 p43=p_meas(43),
3219 p44=p_meas(44),p45=p_meas(45),
3220 p46=p_meas(46),
3221 p47=p_meas(47),p48=p_meas(48),
3222 p49=p_meas(49),p50=p_meas(50),
3223 p51=p_meas(51),p52=p_meas(52),
3224 p53=p_meas(53),
3225 p54=p_meas(54),p55=p_meas(55),
3226 p56=p_meas(56),
3227 p57=p_meas(57),p58=p_meas(58),
3228 p59=p_meas(59),
3229 p60=p_meas(60),p61=p_meas(61),
3230 p62=p_meas(62),
3231 p63=p_meas(63),p64=p_meas(64),
3232 p65=p_meas(65),
3233 p66=p_meas(66),p67=p_meas(67),
3234 p68=p_meas(68),
3235 p69=p_meas(69),p70=p_meas(70),
3236 p71=p_meas(71),p72=p_meas(72),
3237 p73=p_meas(73),
3238 p74=p_meas(74),p75=p_meas(75),
3239 p76=p_meas(76),
3240 p77=p_meas(77),p78=p_meas(78),
3241 p79=p_meas(79),
3242 p80=p_meas(80),p81=p_meas(81),
3243 p82=p_meas(82),
3244 p83=p_meas(83),p84=p_meas(84),
3245 p85=p_meas(85),
3246 p86=p_meas(86),p87=p_meas(87),
3247 p88=p_meas(88),
3248 p89=p_meas(89),p90=p_meas(90),
3249 p91=p_meas(91),p92=p_meas(92),
3250 p93=p_meas(93),
3251 p94=p_meas(94),p95=p_meas(95),
3252 p96=p_meas(96),
3253 p97=p_meas(97),p98=p_meas(98),
3254 p99=p_meas(99),p100=p_meas(100),
3255 last_updated_by=FND_GLOBAL.user_id,
3256 last_update_date=p_ref_date,
3257 last_update_login=FND_GLOBAL.login_id
3258 WHERE analysis_name=p_name
3259 AND seq_no=p_row;
3260
3261 IF (g_proc_level>=g_debug_level) THEN
3262 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_PERCENT_COLS');--bug 3236479
3263 END IF;
3264
3265 RETURN TRUE;
3266 EXCEPTION
3267 WHEN OTHERS THEN
3268 IF (g_proc_level>=g_debug_level) THEN
3269 --xtr_risk_debug_pkg.dpop('QRM_PA_AGGREGATION_P.UPDATE_PERCENT_COLS');
3270 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS','QRM_PA_AGGREGATION_P.UPDATE_PERCENT_COLS');--bug 3236479
3271 END IF;
3272 RETURN FALSE;
3273 END update_percent_cols;
3274
3275
3276
3277 /***************************************************************
3278 This function converts values from M1..M100 and translate them
3279 into USD and then updates the P1..P100 before calculating the
3280 percent. This is necessary to get values based on 1 currency so
3281 that they can be percentaged correctly.
3282 Please refer to bug 2393589 for more details.
3283 ***************************************************************/
3284 FUNCTION translate_to_usd (p_name VARCHAR2,
3285 p_ref_date DATE,
3286 p_md_set_code VARCHAR2,
3287 p_tot_level NUMBER)
3288 RETURN BOOLEAN IS
3289
3290 v_level NUMBER;
3291 v_row NUMBER;
3292 v_meas XTR_MD_NUM_TABLE := XTR_MD_NUM_TABLE();
3293 v_ccy SYSTEM.QRM_VARCHAR_TABLE := SYSTEM.QRM_VARCHAR_TABLE();
3294 v_fx_rate NUMBER;
3295 v_success BOOLEAN;
3296
3297 CURSOR get_all_measures IS
3298 SELECT seq_no,type,
3299 m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,
3300 m18,m19,m20,m21,m22,m23,m24,m25,m26,m27,m28,m29,m30,m31,m32,m33,m34,
3301 m35,m36,m37,m38,m39,m40,m41,m42,m43,m44,m45,m46,m47,m48,m49,m50,m51,
3302 m52,m53,m54,m55,m56,m57,m58,m59,m60,m61,m62,m63,m64,m65,m66,m67,m68,
3303 m69,m70,m71,m72,m73,m74,m75,m76,m77,m78,m79,m80,m81,m82,m83,m84,m85,
3304 m86,m87,m88,m89,m90,m91,m92,m93,m94,m95,m96,m97,m98,m99,m100,
3305 curr1,curr2,curr3,curr4,curr5,curr6,curr7,curr8,curr9,
3306 curr10,curr11,curr12,curr13,curr14,curr15,curr16,curr17,
3307 curr18,curr19,curr20,curr21,curr22,curr23,curr24,curr25,curr26,
3308 curr27,curr28,curr29,curr30,curr31,curr32,curr33,curr34,
3309 curr35,curr36,curr37,curr38,curr39,curr40,curr41,curr42,curr43,
3310 curr44,curr45,curr46,curr47,curr48,curr49,curr50,curr51,
3311 curr52,curr53,curr54,curr55,curr56,curr57,curr58,curr59,curr60,
3312 curr61,curr62,curr63,curr64,curr65,curr66,curr67,curr68,
3313 curr69,curr70,curr71,curr72,curr73,curr74,curr75,curr76,curr77,
3314 curr78,curr79,curr80,curr81,curr82,curr83,curr84,curr85,
3315 curr86,curr87,curr88,curr89,curr90,curr91,curr92,curr93,curr94,
3316 curr95,curr96,curr97,curr98,curr99,curr100
3317 FROM qrm_saved_analyses_row
3318 WHERE analysis_name=p_name
3319 ORDER BY seq_no;
3320
3321 BEGIN
3322
3323 IF (g_proc_level>=g_debug_level) THEN
3324 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.TRANSLATE_TO_USD');
3325 END IF;
3326
3327 OPEN get_all_measures;
3328 v_meas.EXTEND(100);
3329 v_ccy.EXTEND(100);
3330 --xtr_risk_debug_pkg.dlog('p_name',p_name);
3331 LOOP
3332 FETCH get_all_measures INTO
3333 v_row,v_level,v_meas(1),v_meas(2),v_meas(3),v_meas(4),v_meas(5),
3334 v_meas(6),v_meas(7),v_meas(8),v_meas(9),v_meas(10),v_meas(11),
3335 v_meas(12),v_meas(13),v_meas(14),v_meas(15),v_meas(16),
3336 v_meas(17),
3337 v_meas(18),v_meas(19),v_meas(20),
3338 v_meas(21),v_meas(22),v_meas(23),v_meas(24),v_meas(25),
3339 v_meas(26),v_meas(27),v_meas(28),v_meas(29),v_meas(30),
3340 v_meas(31),
3341 v_meas(32),v_meas(33),v_meas(34),v_meas(35),v_meas(36),
3342 v_meas(37),
3343 v_meas(38),v_meas(39),v_meas(40),
3344 v_meas(41),v_meas(42),v_meas(43),v_meas(44),v_meas(45),
3345 v_meas(46),v_meas(47),v_meas(48),v_meas(49),v_meas(50),
3346 v_meas(51),v_meas(52),v_meas(53),v_meas(54),v_meas(55),
3347 v_meas(56),v_meas(57),v_meas(58),v_meas(59),v_meas(60),
3348 v_meas(61),
3349 v_meas(62),v_meas(63),v_meas(64),v_meas(65),v_meas(66),
3350 v_meas(67),
3351 v_meas(68),v_meas(69),v_meas(70),
3352 v_meas(71),v_meas(72),v_meas(73),v_meas(74),v_meas(75),
3353 v_meas(76),v_meas(77),v_meas(78),v_meas(79),v_meas(80),
3354 v_meas(81),
3355 v_meas(82),v_meas(83),v_meas(84),v_meas(85),v_meas(86),
3356 v_meas(87),
3357 v_meas(88),v_meas(89),v_meas(90),
3358 v_meas(91),v_meas(92),v_meas(93),v_meas(94),v_meas(95),
3359 v_meas(96),v_meas(97),v_meas(98),v_meas(99),v_meas(100),
3360 v_ccy(1),v_ccy(2),v_ccy(3),v_ccy(4),v_ccy(5),
3361 v_ccy(6),v_ccy(7),v_ccy(8),v_ccy(9),v_ccy(10),v_ccy(11),
3362 v_ccy(12),v_ccy(13),v_ccy(14),v_ccy(15),v_ccy(16),
3363 v_ccy(17),
3364 v_ccy(18),v_ccy(19),v_ccy(20),
3365 v_ccy(21),v_ccy(22),v_ccy(23),v_ccy(24),v_ccy(25),
3366 v_ccy(26),v_ccy(27),v_ccy(28),v_ccy(29),v_ccy(30),
3367 v_ccy(31),
3368 v_ccy(32),v_ccy(33),v_ccy(34),v_ccy(35),v_ccy(36),
3369 v_ccy(37),
3370 v_ccy(38),v_ccy(39),v_ccy(40),
3371 v_ccy(41),v_ccy(42),v_ccy(43),v_ccy(44),v_ccy(45),
3372 v_ccy(46),v_ccy(47),v_ccy(48),v_ccy(49),v_ccy(50),
3373 v_ccy(51),v_ccy(52),v_ccy(53),v_ccy(54),v_ccy(55),
3374 v_ccy(56),v_ccy(57),v_ccy(58),v_ccy(59),v_ccy(60),
3375 v_ccy(61),
3376 v_ccy(62),v_ccy(63),v_ccy(64),v_ccy(65),v_ccy(66),
3377 v_ccy(67),
3378 v_ccy(68),v_ccy(69),v_ccy(70),
3379 v_ccy(71),v_ccy(72),v_ccy(73),v_ccy(74),v_ccy(75),
3380 v_ccy(76),v_ccy(77),v_ccy(78),v_ccy(79),v_ccy(80),
3381 v_ccy(81),
3382 v_ccy(82),v_ccy(83),v_ccy(84),v_ccy(85),v_ccy(86),
3383 v_ccy(87),
3384 v_ccy(88),v_ccy(89),v_ccy(90),
3385 v_ccy(91),v_ccy(92),v_ccy(93),v_ccy(94),v_ccy(95),
3386 v_ccy(96),v_ccy(97),v_ccy(98),v_ccy(99),v_ccy(100);
3387 EXIT WHEN get_all_measures%NOTFOUND OR get_all_measures%NOTFOUND IS NULL;
3388 --
3389 FOR i IN 1..v_ccy.COUNT LOOP
3390 --if TYPE > total level then insert NULL
3391 IF v_level>0 AND v_level<p_tot_level THEN
3392 v_meas(i) := NULL;
3393 ELSE
3394 --do some checks for optimization
3395 IF v_ccy(i) IS NOT NULL and v_meas(i) IS NOT NULL and
3396 v_meas(i)<>0 THEN
3397 --Additional check for optimization
3398 IF i>1 and v_ccy(i)=v_ccy(i-1) THEN
3399 v_meas(i) := v_meas(i)*v_fx_rate;
3400 ELSE
3401 v_fx_rate := get_fx_rate(p_md_set_code,
3402 p_ref_date,
3403 v_ccy(i),
3404 'USD',
3405 'M');
3406 v_meas(i) := v_meas(i)*v_fx_rate;
3407 END IF;
3408 END IF;
3409 END IF;
3410 END LOOP;
3411 --
3412 v_success := update_percent_cols(p_name,v_row,p_ref_date,v_meas);
3413 --
3414 END LOOP;
3415 CLOSE get_all_measures;
3416
3417 IF (g_proc_level>=g_debug_level) THEN
3418 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.TRANSLATE_TO_USD'); --bug 3236479
3419 END IF;
3420
3421 RETURN TRUE;
3422
3423 EXCEPTION
3424 WHEN OTHERS THEN
3425 IF (g_error_level>=g_debug_level) THEN
3426 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS','QRM_PA_AGGREGATION_P.TRANSLATE_TO_USD',g_error_level);--bug 3236479
3427 END IF;
3428 RETURN FALSE;
3429 END translate_to_usd;
3430
3431
3432
3433 /***************************************************************
3434 This update_percent function should be used by external call
3435 everytime the Total page is modified.
3436 Internal call (transform_and_save) will use the other signature.
3437 ***************************************************************/
3438 FUNCTION update_percent (p_name VARCHAR2,p_ref_date DATE)
3439 RETURN BOOLEAN IS
3440
3441 CURSOR count_column IS
3442 SELECT COUNT(*) FROM qrm_saved_analyses_col
3443 WHERE analysis_name=p_name
3444 AND type>-2;
3445 CURSOR count_row_header IS
3446 SELECT COUNT(*) FROM qrm_saved_analyses_col
3447 WHERE analysis_name=p_name
3448 AND type=-2;
3449 CURSOR get_style IS
3450 SELECT style,md_set_code FROM qrm_analysis_settings
3451 WHERE analysis_name=p_name AND history_flag='S';
3452 v_max_col_no NUMBER(5);
3453 v_row_agg_no NUMBER(5);
3454 v_style VARCHAR2(1);
3455 v_success BOOLEAN;
3456 v_md_set_code qrm_analysis_settings.md_set_code%TYPE;
3457
3458 BEGIN
3459
3460 IF (g_proc_level>=g_debug_level) THEN
3461 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_PERCENT'); --bug 3236479
3462 END IF;
3463
3464 OPEN count_column;
3465 FETCH count_column INTO v_max_col_no;
3466 CLOSE count_column;
3467 OPEN count_row_header;
3468 FETCH count_row_header INTO v_row_agg_no;
3469 CLOSE count_row_header;
3470 OPEN get_style;
3471 FETCH get_style INTO v_style,v_md_set_code;
3472 CLOSE get_style;
3473 v_success:=update_percent(p_name,v_style,v_row_agg_no,v_max_col_no,
3474 p_ref_date,v_md_set_code);
3475
3476 IF (g_proc_level>=g_debug_level) THEN
3477 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_PERCENT'); --bug 3236479
3478 END IF;
3479
3480 RETURN v_success;
3481 END update_percent;
3482
3483
3484
3485 /***************************************************************
3486 This update_percent function should be used by internal call
3487 from transform_and_save procedure.
3488 External call should use the other signature.
3489 ***************************************************************/
3490 FUNCTION update_percent (p_name VARCHAR2,
3491 p_style VARCHAR2,
3492 p_row_agg_no NUMBER,
3493 p_max_col_no NUMBER,
3494 p_ref_date DATE,
3495 p_md_set_code VARCHAR2)
3496 RETURN BOOLEAN IS
3497
3498 v_tot XTR_MD_NUM_TABLE := XTR_MD_NUM_TABLE();
3499 v_type VARCHAR2(1);
3500 v_level VARCHAR2(1); --the order
3501 v_row NUMBER;
3502 v_previous_count NUMBER := 1;
3503 i NUMBER(5);
3504 v_sql VARCHAR2(4000);
3505 v_tot_segment NUMBER;
3506 v_divisor NUMBER := 0.000001; --bug 2393972
3507 v_success BOOLEAN;
3508
3509 CURSOR percent_info IS
3510 SELECT type,att_order FROM qrm_analysis_atts
3511 WHERE analysis_name=p_name AND percentage='Y' AND history_flag='S';
3512 CURSOR get_col_tot_seq_no IS
3513 SELECT seq_no FROM qrm_saved_analyses_col
3514 WHERE analysis_name=p_name AND type=v_level;
3515 CURSOR col_100 IS
3516 SELECT seq_no,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,
3517 m18,m19,m20,m21,m22,m23,m24,m25,m26,m27,m28,m29,m30,m31,m32,m33,m34,
3518 m35,m36,m37,m38,m39,m40,m41,m42,m43,m44,m45,m46,m47,m48,m49,m50,m51,
3519 m52,m53,m54,m55,m56,m57,m58,m59,m60,m61,m62,m63,m64,m65,m66,m67,m68,
3520 m69,m70,m71,m72,m73,m74,m75,m76,m77,m78,m79,m80,m81,m82,m83,m84,m85,
3521 m86,m87,m88,m89,m90,m91,m92,m93,m94,m95,m96,m97,m98,m99,m100
3522 FROM qrm_saved_analyses_row
3523 WHERE analysis_name=p_name AND type=v_level ORDER BY seq_no;
3524 BEGIN
3525
3526 IF (g_proc_level>=g_debug_level) THEN
3527 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_PERCENT');
3528 END IF;
3529
3530 OPEN percent_info;
3531 FETCH percent_info INTO v_type,v_level;
3532 CLOSE percent_info;
3533 IF (g_proc_level>=g_debug_level) THEN
3534 xtr_risk_debug_pkg.dlog('v_type:v_level',v_type||':'||v_level);
3535 END IF;
3536
3537 v_success := translate_to_usd (p_name,
3538 p_ref_date,
3539 p_md_set_code,
3540 v_level);
3541
3542 --percentage is based on the row aggregates
3543 IF v_type='R' THEN
3544
3545 --prep cursor that contains total at the specified level
3546 v_tot.EXTEND(100);
3547
3548 --bug 2393972
3549 FOR i in 1..100 LOOP
3550 IF (v_tot(i)=0) THEN
3551 v_tot(i):=v_divisor;
3552 END IF;
3553 END LOOP;
3554
3555 OPEN col_100;
3556 LOOP
3557 --fetch the specified level total row
3558 FETCH col_100 INTO
3559 v_row,v_tot(1),v_tot(2),v_tot(3),v_tot(4),v_tot(5),
3560 v_tot(6),v_tot(7),v_tot(8),v_tot(9),v_tot(10),v_tot(11),
3561 v_tot(12),v_tot(13),v_tot(14),v_tot(15),v_tot(16),v_tot(17),
3562 v_tot(18),v_tot(19),v_tot(20),
3563 v_tot(21),v_tot(22),v_tot(23),v_tot(24),v_tot(25),
3564 v_tot(26),v_tot(27),v_tot(28),v_tot(29),v_tot(30),v_tot(31),
3565 v_tot(32),v_tot(33),v_tot(34),v_tot(35),v_tot(36),v_tot(37),
3566 v_tot(38),v_tot(39),v_tot(40),
3567 v_tot(41),v_tot(42),v_tot(43),v_tot(44),v_tot(45),
3568 v_tot(46),v_tot(47),v_tot(48),v_tot(49),v_tot(50),
3569 v_tot(51),v_tot(52),v_tot(53),v_tot(54),v_tot(55),
3570 v_tot(56),v_tot(57),v_tot(58),v_tot(59),v_tot(60),v_tot(61),
3571 v_tot(62),v_tot(63),v_tot(64),v_tot(65),v_tot(66),v_tot(67),
3572 v_tot(68),v_tot(69),v_tot(70),
3573 v_tot(71),v_tot(72),v_tot(73),v_tot(74),v_tot(75),
3574 v_tot(76),v_tot(77),v_tot(78),v_tot(79),v_tot(80),v_tot(81),
3575 v_tot(82),v_tot(83),v_tot(84),v_tot(85),v_tot(86),v_tot(87),
3576 v_tot(88),v_tot(89),v_tot(90),
3577 v_tot(91),v_tot(92),v_tot(93),v_tot(94),v_tot(95),
3578 v_tot(96),v_tot(97),v_tot(98),v_tot(99),v_tot(100);
3579 --calculating the % while updating the rows in between
3580 UPDATE qrm_saved_analyses_row
3581 SET p1=100*p1/v_tot(1),p2=100*p2/v_tot(2),p3=100*p3/v_tot(3),
3582 p4=100*p4/v_tot(4),p5=100*p5/v_tot(5),p6=100*p6/v_tot(6),
3583 p7=100*p7/v_tot(7),p8=100*p8/v_tot(8),p9=100*p9/v_tot(9),
3584 p10=100*p10/v_tot(10),p11=100*p11/v_tot(11),
3585 p12=100*p12/v_tot(12),
3586 p13=100*p13/v_tot(13),p14=100*p14/v_tot(14),
3587 p15=100*p15/v_tot(15),
3588 p16=100*p16/v_tot(16),p17=100*p17/v_tot(17),
3589 p18=100*p18/v_tot(18),
3590 p19=100*p19/v_tot(19),p20=100*p20/v_tot(20),
3591 p21=100*p21/v_tot(21),p22=100*p22/v_tot(22),
3592 p23=100*p23/v_tot(23),
3593 p24=100*p24/v_tot(24),p25=100*p25/v_tot(25),
3594 p26=100*p26/v_tot(26),
3595 p27=100*p27/v_tot(27),p28=100*p28/v_tot(28),
3596 p29=100*p29/v_tot(29),
3597 p30=100*p30/v_tot(30),p31=100*p31/v_tot(31),
3598 p32=100*p32/v_tot(32),
3599 p33=100*p33/v_tot(33),p34=100*p34/v_tot(34),
3600 p35=100*p35/v_tot(35),
3601 p36=100*p36/v_tot(36),p37=100*p37/v_tot(37),
3602 p38=100*p38/v_tot(38),
3603 p39=100*p39/v_tot(39),p40=100*p40/v_tot(40),
3604 p41=100*p41/v_tot(41),p42=100*p42/v_tot(42),
3605 p43=100*p43/v_tot(43),
3606 p44=100*p44/v_tot(44),p45=100*p45/v_tot(45),
3607 p46=100*p46/v_tot(46),
3608 p47=100*p47/v_tot(47),p48=100*p48/v_tot(48),
3609 p49=100*p49/v_tot(49),p50=100*p50/v_tot(50),
3610 p51=100*p51/v_tot(51),p52=100*p52/v_tot(52),
3611 p53=100*p53/v_tot(53),
3612 p54=100*p54/v_tot(54),p55=100*p55/v_tot(55),
3613 p56=100*p56/v_tot(56),
3614 p57=100*p57/v_tot(57),p58=100*p58/v_tot(58),
3615 p59=100*p59/v_tot(59),
3616 p60=100*p60/v_tot(60),p61=100*p61/v_tot(61),
3617 p62=100*p62/v_tot(62),
3618 p63=100*p63/v_tot(63),p64=100*p64/v_tot(64),
3619 p65=100*p65/v_tot(65),
3620 p66=100*p66/v_tot(66),p67=100*p67/v_tot(67),
3621 p68=100*p68/v_tot(68),
3622 p69=100*p69/v_tot(69),p70=100*p70/v_tot(70),
3623 p71=100*p71/v_tot(71),p72=100*p72/v_tot(72),
3624 p73=100*p73/v_tot(73),
3625 p74=100*p74/v_tot(74),p75=100*p75/v_tot(75),
3626 p76=100*p76/v_tot(76),
3627 p77=100*p77/v_tot(77),p78=100*p78/v_tot(78),
3628 p79=100*p79/v_tot(79),
3629 p80=100*p80/v_tot(80),p81=100*p81/v_tot(81),
3630 p82=100*p82/v_tot(82),
3631 p83=100*p83/v_tot(83),p84=100*p84/v_tot(84),
3632 p85=100*p85/v_tot(85),
3633 p86=100*p86/v_tot(86),p87=100*p87/v_tot(87),
3634 p88=100*p88/v_tot(88),
3635 p89=100*p89/v_tot(89),p90=100*p90/v_tot(90),
3636 p91=100*p91/v_tot(91),p92=100*p92/v_tot(92),
3637 p93=100*p93/v_tot(93),
3638 p94=100*p94/v_tot(94),p95=100*p95/v_tot(95),
3639 p96=100*p96/v_tot(96),
3640 p97=100*p97/v_tot(97),p98=100*p98/v_tot(98),
3641 p99=100*p99/v_tot(99),p100=100*p100/v_tot(100),
3642 last_updated_by=FND_GLOBAL.user_id,
3643 last_update_date=p_ref_date,
3644 last_update_login=FND_GLOBAL.login_id
3645 WHERE analysis_name=p_name AND seq_no>=v_previous_count
3646 AND seq_no<=v_row
3647 AND (type=-1 OR type>=v_level);
3648
3649 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3650 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_ROW.P1..P100 Row Level Agg',
3651 'QRM_PA_AGGREGATION_P.UPDATE_PERCENT',g_event_level);
3652 END IF;
3653
3654 v_previous_count := v_row+1;
3655 EXIT WHEN col_100%NOTFOUND;
3656 END LOOP;
3657 CLOSE col_100;
3658
3659 --update the column info, first null all the COL_PERCENT_LEVEL
3660 UPDATE qrm_saved_analyses_col
3661 SET col_percent_level=NULL, last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3662 WHERE analysis_name=p_name;
3663 --left null total columns,so it won't be displayed
3664 UPDATE qrm_saved_analyses_col
3665 SET col_percent_level=v_level, last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3666 WHERE analysis_name=p_name AND type=-1;
3667
3668 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3669 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_COL.COL_PERCENT_LEVEL to null then '||v_level,
3670 'QRM_PA_AGGREGATION_P.UPDATE_PERCENT',g_event_level);
3671 END IF;
3672
3673 --percentage is based on the col aggregates
3674 ELSIF v_type='C' THEN
3675 --get all the specified total column index
3676 v_tot := NULL;
3677 IF (g_proc_level>=g_debug_level) THEN
3678 xtr_risk_debug_pkg.dlog('Before FETCH v_tot');
3679 END IF;
3680 OPEN get_col_tot_seq_no;
3681 FETCH get_col_tot_seq_no BULK COLLECT INTO v_tot;
3682 CLOSE get_col_tot_seq_no;
3683 IF (g_proc_level>=g_debug_level) THEN
3684 xtr_risk_debug_pkg.dlog('After FETCH v_tot');
3685 END IF;
3686 v_previous_count := p_row_agg_no;
3690 xtr_risk_debug_pkg.dlog('v_previous_count',v_previous_count);
3687 IF (g_proc_level>=g_debug_level) THEN
3688 xtr_risk_debug_pkg.dlog('v_tot.COUNT',v_tot.COUNT);
3689 xtr_risk_debug_pkg.dlog('v_tot.LAST',v_tot.LAST);
3691 END IF;
3692 FOR i IN 1..v_tot.COUNT LOOP
3693 --
3694 --Have to do dynamic sql bec. we have to divide per block of col
3695 --Trying to get all column between the total index
3696 --
3697 IF (g_proc_level>=g_debug_level) THEN
3698 xtr_risk_debug_pkg.dlog('v_tot(i)',i||':'||v_tot(i));
3699 END IF;
3700 v_tot_segment := v_tot(i)-v_previous_count;
3701 FOR j IN 1..v_tot_segment LOOP
3702 --IF j<v_tot(i)-v_previous_count THEN
3703 -- v_sql := v_sql||'p'||j||'=100*m'||j||'/m'||v_tot_segment||',';
3704 --ELSE
3705 -- v_sql := v_sql||'p'||j||'=100*m'||j||'/m'||v_tot_segment;
3706 --END IF;
3707
3708 --bug 2393972
3709 IF j<v_tot(i)-v_previous_count THEN
3710 v_sql := v_sql||'p'||j||'=100*p'||j||'/DECODE(p'||v_tot_segment||',0,TO_NUMBER('''||v_divisor||'''),p'||v_tot_segment||'),';
3711 ELSE
3712 v_sql := v_sql||'p'||j||'=100*p'||j||'/DECODE(p'||v_tot_segment||',0,TO_NUMBER('''||v_divisor||'''),p'||v_tot_segment||')';
3713 END IF;
3714
3715 END LOOP;
3716 v_sql:='UPDATE qrm_saved_analyses_row SET '||v_sql||' , last_updated_by=FND_GLOBAL.user_id, last_update_date=:p_ref_date, last_update_login=FND_GLOBAL.login_id WHERE analysis_name=:p_name';
3717
3718 IF (g_proc_level>=g_debug_level) THEN
3719 xtr_risk_debug_pkg.dlog('v_sql',v_sql);
3720 END IF;
3721 EXECUTE IMMEDIATE v_sql USING p_ref_date,p_name;
3722 v_previous_count := v_tot(i)+1;
3723 END LOOP;
3724 IF (g_proc_level>=g_debug_level) THEN
3725 xtr_risk_debug_pkg.dlog('After EXECUTE IMMEDIATE');
3726 END IF;
3727 --update the column info, first null all the COL_PERCENT_LEVEL
3728 UPDATE qrm_saved_analyses_col
3729 SET col_percent_level=NULL, last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3730 WHERE analysis_name=p_name;
3731 --left null total columns,so it won't be displayed
3732 UPDATE qrm_saved_analyses_col
3733 SET col_percent_level=-v_level, last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3734 WHERE analysis_name=p_name AND (type=-1 OR type>=v_level);
3735
3736 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3737 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_COL.COL_PERCENT_LEVEL to null then '||v_level,
3738 'QRM_PA_AGGREGATION_P.UPDATE_PERCENT',g_event_level);
3739 END IF;
3740
3741 ELSE
3742 --no percentage calculation is necessary
3743 IF (g_proc_level>=g_debug_level) THEN
3744 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_PERCENT');--bug 3236479
3745 END IF;
3746 RETURN TRUE;
3747 END IF;
3748
3749 COMMIT;
3750 IF (g_proc_level>=g_debug_level) THEN
3751 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_PERCENT');-- bug 3236479
3752 END IF;
3753 RETURN TRUE;
3754 EXCEPTION
3755 WHEN OTHERS THEN
3756
3757 IF (g_error_level>=g_debug_level) THEN
3758 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS',
3759 'QRM_PA_AGGREGATION_P.UPDATE_PERCENT',g_error_level);--bug 3236479
3760 END IF;
3761
3762 RETURN FALSE;
3763 END update_percent;
3764
3765
3766
3767 /***************************************************************
3768 This function updates the label of the DEAL_TYPE and
3769 DEAL_SUBTYPE aggregate attributes with the user defined ones
3770 from table qrm_saved_analyses_col.
3771 The label of table qrm_saved_analyses_row will be updated at run
3772 time in OA.
3773
3774 DEAL_TYPE -> xtr_deal_types.user_deal_type
3775
3776 DEAL_SUBTYPE -> xtr_deal_subtypes.user_deal_subtype
3777 is taken care in the dynamic cursor when aggregation is done.
3778 ***************************************************************/
3779 FUNCTION update_label(p_name VARCHAR2,
3780 p_agg IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,
3781 p_col_order IN OUT NOCOPY XTR_MD_NUM_TABLE,
3782 p_att_type IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,
3783 p_ref_date DATE)
3784 RETURN BOOLEAN IS
3785 v_col_name VARCHAR2(50);
3786 BEGIN
3787 IF (g_proc_level>=g_debug_level) THEN
3788 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_LABEL');
3789 END IF;
3790
3791 --loop through all the aggregate to see whether DEAL_TYPE is there.
3792 FOR i IN 1..p_agg.COUNT LOOP
3793 IF p_agg(i)='DEAL_TYPE' AND p_att_type(i)='C' THEN
3794 --update the column header to reflect user defined DEAL_TYPE
3795 UPDATE qrm_saved_analyses_col
3796 SET a1=(SELECT DISTINCT user_deal_type FROM xtr_deal_types WHERE deal_type=a1), last_updated_by=FND_GLOBAL.user_id, last_update_date=p_ref_date, last_update_login=FND_GLOBAL.login_id
3797 WHERE analysis_name=p_name AND type=-1;
3798 COMMIT;
3799
3800 IF (g_event_level>=g_debug_level) THEN --bug 3236479
3801 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SET_ANALYSES_COL.A1 to user_deal_type',
3802 'QRM_PA_AGGREGATION_P.UPDATE_LABEL',g_event_level);
3803 END IF;
3804
3805 EXIT;
3806 END IF;
3807 END LOOP;
3808
3809 IF (g_proc_level>=g_debug_level) THEN
3810 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_LABEL');
3811 END IF;
3812 RETURN TRUE;
3813 EXCEPTION
3814 WHEN OTHERS THEN
3818 RETURN FALSE;
3815 IF (g_error_level>=g_debug_level) THEN
3816 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS','QRM_PA_AGGREGATION_P.UPDATE_LABEL',g_error_level);-- bug 3236479
3817 END IF;
3819 END update_label;
3820
3821
3822
3823 /***************************************************************
3824 This procedure calculate the Totals for Table style using the
3825 currency conversion logic. Moreover, the underlying currency
3826 of the Totals will be returned together with the calculated totals.
3827 Also calculate the currency multipler (FX Rate) for reporting
3828 currency as needed.
3829 IMPORTANT:
3830 If an attribute cannot be averaged/totaled (sensitivity with
3831 > 1 underlying curr) then the p_att_name(i) will be NULLED.
3832 ***************************************************************/
3833 PROCEDURE calc_table_total_and_fxrate(p_name VARCHAR2,--1
3834 p_calc_total_ind VARCHAR2,--2: 'Y'es or 'N'o
3835 p_curr_reporting VARCHAR2,--3
3836 p_currency_source VARCHAR2,--4
3837 p_last_run_date DATE,--5
3838 p_md_set_code VARCHAR2,--6
3839 p_dirty VARCHAR2,--7
3840 p_end_date_fix DATE,--8
3841 p_tot_avg SYSTEM.QRM_VARCHAR_TABLE,--9
3842 p_ccy_multiplier OUT NOCOPY NUMBER,--10
3843 p_att_name IN OUT NOCOPY SYSTEM.QRM_VARCHAR240_TABLE,--11
3844 p_total OUT NOCOPY XTR_MD_NUM_TABLE,--12
3845 p_table_col_curr OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE,--13
3846 p_sensitivity SYSTEM.QRM_VARCHAR_TABLE, --14
3847 p_analysis_type VARCHAR2, --15
3848 p_business_week VARCHAR2,--16
3849 p_amount SYSTEM.QRM_VARCHAR_TABLE)--17
3850 IS
3851
3852 v_ccy_suffix VARCHAR2(20);
3853 v_underlying_ccy VARCHAR2(20);
3854 v_origin SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
3855 v_att_type SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
3856 v_nom SYSTEM.QRM_VARCHAR240_TABLE := SYSTEM.QRM_VARCHAR240_TABLE();
3857 v_denom SYSTEM.QRM_VARCHAR240_TABLE := SYSTEM.QRM_VARCHAR240_TABLE();
3858 v_num_denom_origin SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
3859 v_sql VARCHAR2(4000);
3860 i NUMBER(5);
3861 v_cursor INTEGER;
3862 v_rows_processed INTEGER;
3863 v_tb_calc_used BOOLEAN;
3864 v_temp VARCHAR2(240);
3865 v_total_temp xtr_md_num_table := xtr_md_num_table();
3866
3867 --dummy variables required only for other styles
3868 v_tb_calc_used_col BOOLEAN;
3869 v_ccy_aggregate SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
3870 v_type SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
3871 v_order xtr_md_num_table := xtr_md_num_table();
3872 v_ccy_agg_flag NUMBER;
3873 v_ccy_case_flag NUMBER;
3874 v_ccy_agg_level NUMBER;
3875 v_measure_no NUMBER(5);
3876 v_row_agg_no NUMBER(5);
3877 v_dummy VARCHAR2(1);
3878 v_sql_col VARCHAR2(1);
3879 v_agg_col_curr SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
3880
3881 CURSOR get_lookup_prop IS
3882 SELECT origin,attribute_type,numerator,denominator,num_denom_origin
3883 FROM qrm_ana_atts_lookups
3884 WHERE attribute_name=v_temp;
3885
3886 BEGIN
3887 IF (g_proc_level>=g_debug_level) THEN
3888 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.CALC_TABLE_TOTAL');--bug 3236479
3889 END IF;
3890
3891 --initialize fnd_msg_pub if it has not been intialized
3892 IF fnd_msg_pub.count_msg>0 THEN
3893 fnd_msg_pub.Initialize;
3894 END IF;
3895
3896 --FHU will convert the relative date and saved them into the fix date col
3897
3898 --see whether we need to do total or just to get multiplier
3899 IF p_calc_total_ind='Y' THEN
3900 --first extend v_table_col_curr
3901 IF (g_proc_level>=g_debug_level) THEN
3902 xtr_risk_debug_pkg.dlog('p_att_name.COUNT,p_att_name.LAST',p_att_name.COUNT||','||p_att_name.LAST);
3903 END IF;
3904 p_table_col_curr := SYSTEM.QRM_VARCHAR_table();
3905 p_table_col_curr.EXTEND(p_att_name.COUNT);
3906 v_origin.EXTEND(p_att_name.COUNT);
3907 v_att_type.EXTEND(p_att_name.COUNT);
3908 v_nom.EXTEND(p_att_name.COUNT);
3909 v_denom.EXTEND(p_att_name.COUNT);
3910 v_num_denom_origin.EXTEND(p_att_name.COUNT);
3911 p_total := xtr_md_num_table();
3912 p_total.EXTEND(p_att_name.COUNT);
3913
3914 --xtr_risk_debug_pkg.dlog('p_table_col_curr.COUNT',p_table_col_curr.COUNT);
3915 --get the underlying currency for each column and modify the the
3916 --attribute name with '_USD' and '_SOB'
3917 get_underlying_currency(p_name,p_last_run_date,'T',p_md_set_code,
3918 p_currency_source,p_curr_reporting,p_amount,
3919 p_att_name,v_ccy_aggregate,v_type,v_order,
3920 v_ccy_suffix,p_ccy_multiplier,v_ccy_agg_flag,
3921 v_underlying_ccy,v_ccy_case_flag,NULL,
3922 v_ccy_agg_level,p_table_col_curr,v_agg_col_curr,
3923 p_sensitivity);
3924 --xtr_risk_debug_pkg.dlog('p_table_col_curr.COUNT',p_table_col_curr.COUNT);
3925 IF (g_proc_level>=g_debug_level) THEN
3926 xtr_risk_debug_pkg.dlog('p_ccy_multiplier',p_ccy_multiplier);
3927 END IF;
3928 --make sure p_ccy_multiplier is not null when necessary otherwise throws error
3929 FOR i IN 1..p_table_col_curr.COUNT LOOP
3930 --xtr_risk_debug_pkg.dlog('p_table_col_curr(i)',i||':'||p_table_col_curr(i));
3931 IF p_table_col_curr(i) IS NULL THEN
3932 IF p_curr_reporting<>'USD' AND p_ccy_multiplier IS NULL THEN
3933 FND_MESSAGE.SET_NAME('QRM','QRM_CALC_NO_DEFAULT_SPOT_ERR');
3934 FND_MESSAGE.SET_TOKEN('CCY',p_curr_reporting);
3935 RAISE e_pagg_no_fxrate_found;
3936 END IF;
3937 END IF;
3938 END LOOP;
3939
3940 --get the property of the new name attributes
3941 FOR i IN 1..p_att_name.COUNT LOOP
3942 IF p_att_name(i) IS NOT NULL THEN
3943 v_temp := p_att_name(i);
3944 --xtr_risk_debug_pkg.dlog('v_temp',v_temp);
3945 OPEN get_lookup_prop;
3946 FETCH get_lookup_prop INTO v_origin(i),v_att_type(i),v_nom(i),
3947 v_denom(i),v_num_denom_origin(i);
3948 IF (g_proc_level>=g_debug_level) THEN
3949 xtr_risk_debug_pkg.dlog('v_origin,v_att_type,v_nom,v_denom',i||':'||v_origin(i)||','||v_att_type(i)||','||v_nom(i)||','||v_denom(i));
3950 END IF;
3951 CLOSE get_lookup_prop;
3952 END IF;
3953 END LOOP;
3954
3955 --create dynamic sql, first get the origin and alias
3956 create_cursor (p_name,'T',p_analysis_type,p_att_name,v_att_type,
3957 v_nom,v_denom,p_tot_avg,v_sql,v_sql_col,
3958 v_row_agg_no,v_measure_no,v_origin,v_tb_calc_used,
3959 v_tb_calc_used_col,
3960 FALSE,v_ccy_suffix,p_ccy_multiplier,
3961 p_amount,p_table_col_curr,v_num_denom_origin,
3962 p_curr_reporting,p_sensitivity);
3963
3964 IF (g_proc_level>=g_debug_level) THEN
3965 xtr_risk_debug_pkg.dlog('v_sql',v_sql);
3966 END IF;
3967 --open dynamic cursor
3968 v_cursor := dbms_sql.open_cursor;
3969 --Parse the results
3970 dbms_sql.parse(v_cursor,v_sql,dbms_sql.native);
3971 dbms_sql.bind_variable(v_cursor,'analysis_name',p_name);
3972 --remember to add end_date as binding variable
3973 --for special cases: v_tb_calc_used=TRUE
3974 IF v_tb_calc_used THEN
3975 IF p_analysis_type='P' THEN
3976 dbms_sql.bind_variable(v_cursor,'end_date',p_end_date_fix);
3977 ELSE
3978 dbms_sql.bind_variable(v_cursor,'ref_date',TRUNC(p_last_run_date));
3979 END IF;
3980 END IF;
3981 --xtr_risk_debug_pkg.dlog('v_measure_no',v_measure_no);
3982 --the number of columns is twice as many in the SQL bec. of nom and denom
3983 v_total_temp.EXTEND(p_att_name.COUNT*2);
3984 FOR i IN 1..v_total_temp.COUNT LOOP
3985 dbms_sql.define_column(v_cursor,i,v_total_temp(i));
3986 END LOOP;
3987 --execute
3988 v_rows_processed := dbms_sql.execute(v_cursor);
3989 --get the value
3990 LOOP
3991 IF dbms_sql.fetch_rows(v_cursor)>0 THEN
3992 FOR i IN 1..v_total_temp.COUNT LOOP
3993 dbms_sql.column_value(v_cursor,i,v_total_temp(i));
3994 END LOOP;
3995 ELSE
3996 EXIT;
3997 END IF;
3998 END LOOP;
3999 --transfer the value from v_total_temp to p_total
4000 FOR i IN 1..p_total.COUNT LOOP
4001 IF p_att_name(i) IS NOT NULL THEN
4002 IF p_tot_avg(i)='T' THEN --do SUM operation
4003 p_total(i) := v_total_temp(i*2-1);
4004 ELSE --do AVERAGE operation
4005 p_total(i) := v_total_temp(i*2-1)/v_total_temp(i*2);
4006 END IF;
4007 END IF;
4008 IF (g_proc_level>=g_debug_level) THEN
4009 xtr_risk_debug_pkg.dlog('p_total(i)',i||':'||p_att_name(i)||','||p_total(i)||','||p_table_col_curr(i));
4010 END IF;
4011 END LOOP;
4012 --close dynamic cursor
4013 dbms_sql.close_cursor(v_cursor);
4014
4015 ELSE --just need to call MD API to get the FX Rate/Ccy multiplier
4016 --Find multiplier
4017 p_ccy_multiplier := get_fx_rate(p_md_set_code,
4018 p_last_run_date,
4019 'USD',
4020 p_curr_reporting,
4021 'M');
4022
4023 --check whether p_ccy_multiplier is not null when needed
4024 IF p_ccy_multiplier IS NULL THEN
4025 FND_MESSAGE.SET_NAME('QRM','QRM_CALC_NO_DEFAULT_SPOT_ERR');
4026 FND_MESSAGE.SET_TOKEN('CCY',p_curr_reporting);
4027 RAISE e_pagg_no_fxrate_found;
4028 END IF;
4029 END IF;
4030
4031 --update dirty flag if semi-dirty
4032 IF p_dirty IN ('C','S') THEN
4033 UPDATE qrm_analysis_settings SET dirty='N' WHERE analysis_name=p_name;
4034 END IF;
4035
4036 IF (g_event_level>=g_debug_level) THEN
4037 xtr_risk_debug_pkg.dlog('DML','UPDATE QRM_ANALYSIS_SETTINGS.DIRTY=N',
4038 'QRM_PA_AGGREGATION_P.CALC_TABLE_TOTAL',g_event_level);--bug 3236479
4039 END IF;
4040
4041 IF (g_proc_level>=g_debug_level) THEN
4042 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.CALC_TABLE_TOTAL');--bug 3236479
4043 END IF;
4044
4045 EXCEPTION
4046 WHEN e_pagg_no_fxrate_found THEN
4047 fnd_msg_pub.add;
4048 IF (g_error_level>=g_debug_level) THEN
4049 xtr_risk_debug_pkg.dlog('EXCEPTION','e_pagg_no_fxrate_found','QRM_PA_AGGREGATION_P.CALC_TABLE_TOTAL',g_error_level);--bug 3236479
4050 END IF;
4051 WHEN OTHERS THEN
4052 IF (g_error_level>=g_debug_level) THEN
4053 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS','QRM_PA_AGGREGATION_P.CALC_TABLE_TOTAL',g_error_level);--bug 3236479
4054 END IF;
4055 END calc_table_total_and_fxrate;
4056
4057
4058
4059 /***************************************************************
4060 This procedure calculate the Totals for Table style using the
4061 currency conversion logic. Moreover, the underlying currency
4062 of the Totals will be returned together with the calculated totals.
4063 Also calculate the currency multipler (FX Rate) for reporting
4064 currency as needed.
4065 ***************************************************************/
4066 FUNCTION update_currency_columns(p_indicator NUMBER,
4067 p_name VARCHAR2,
4068 p_ref_date DATE,
4069 v_curr IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE)
4070 RETURN BOOLEAN IS
4071 BEGIN
4072 IF (g_proc_level>=g_debug_level) THEN
4073 xtr_risk_debug_pkg.dpush('QRM_PA_AGGREGATION_P.UPDATE_CURR_COL');
4074 END IF;
4075 IF p_indicator=1 THEN
4076 UPDATE qrm_saved_analyses_row
4077 SET curr1=v_curr(1),curr2=v_curr(2),curr3=v_curr(3),
4078 curr4=v_curr(4),curr5=v_curr(5),curr6=v_curr(6),
4079 curr7=v_curr(7),curr8=v_curr(8),curr9=v_curr(9),
4080 curr10=v_curr(10),curr11=v_curr(11),curr12=v_curr(12),
4084 curr21=v_curr(21),curr22=v_curr(22),curr23=v_curr(23),
4081 curr13=v_curr(13),curr14=v_curr(14),curr15=v_curr(15),
4082 curr16=v_curr(16),curr17=v_curr(17),curr18=v_curr(18),
4083 curr19=v_curr(19),curr20=v_curr(20),
4085 curr24=v_curr(24),curr25=v_curr(25),curr26=v_curr(26),
4086 curr27=v_curr(27),curr28=v_curr(28),curr29=v_curr(29),
4087 curr30=v_curr(30),curr31=v_curr(31),curr32=v_curr(32),
4088 curr33=v_curr(33),curr34=v_curr(34),curr35=v_curr(35),
4089 curr36=v_curr(36),curr37=v_curr(37),curr38=v_curr(38),
4090 curr39=v_curr(39),curr40=v_curr(40),
4091 curr41=v_curr(41),curr42=v_curr(42),curr43=v_curr(43),
4092 curr44=v_curr(44),curr45=v_curr(45),curr46=v_curr(46),
4093 curr47=v_curr(47),curr48=v_curr(48),
4094 curr49=v_curr(49),curr50=v_curr(50),
4095 curr51=v_curr(51),curr52=v_curr(52),curr53=v_curr(53),
4096 curr54=v_curr(54),curr55=v_curr(55),curr56=v_curr(56),
4097 curr57=v_curr(57),curr58=v_curr(58),curr59=v_curr(59),
4098 curr60=v_curr(60),curr61=v_curr(61),curr62=v_curr(62),
4099 curr63=v_curr(63),curr64=v_curr(64),curr65=v_curr(65),
4100 curr66=v_curr(66),curr67=v_curr(67),curr68=v_curr(68),
4101 curr69=v_curr(69),curr70=v_curr(70),
4102 curr71=v_curr(71),curr72=v_curr(72),curr73=v_curr(73),
4103 curr74=v_curr(74),curr75=v_curr(75),curr76=v_curr(76),
4104 curr77=v_curr(77),curr78=v_curr(78),curr79=v_curr(79),
4105 curr80=v_curr(80),curr81=v_curr(81),curr82=v_curr(82),
4106 curr83=v_curr(83),curr84=v_curr(84),curr85=v_curr(85),
4107 curr86=v_curr(86),curr87=v_curr(87),curr88=v_curr(88),
4108 curr89=v_curr(89),curr90=v_curr(90),
4109 curr91=v_curr(91),curr92=v_curr(92),curr93=v_curr(93),
4110 curr94=v_curr(94),curr95=v_curr(95),curr96=v_curr(96),
4111 curr97=v_curr(97),curr98=v_curr(98),
4112 curr99=v_curr(99),curr100=v_curr(100),
4113 last_updated_by=FND_GLOBAL.user_id,
4114 last_update_date=p_ref_date,
4115 last_update_login=FND_GLOBAL.login_id
4116 WHERE analysis_name=p_name;
4117
4118 IF (g_event_level>=g_debug_level) THEN --bug 3236479
4119 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SAVED_ANALYSES_ROW.CURR1..100 with p_indicator=1',
4120 'QRM_PA_AGGREGATION_P.UPDATE_CURRENCY_COLUMNS',g_event_level);
4121 END IF;
4122
4123 ELSE --p_indicator=2 where curr1 has the CCY for the row
4124 UPDATE qrm_saved_analyses_row
4125 SET curr2=curr1,curr3=curr1,
4126 curr4=curr1,curr5=curr1,curr6=curr1,
4127 curr7=curr1,curr8=curr1,curr9=curr1,
4128 curr10=curr1,curr11=curr1,curr12=curr1,
4129 curr13=curr1,curr14=curr1,curr15=curr1,
4130 curr16=curr1,curr17=curr1,curr18=curr1,
4131 curr19=curr1,curr20=curr1,
4132 curr21=curr1,curr22=curr1,curr23=curr1,
4133 curr24=curr1,curr25=curr1,curr26=curr1,
4134 curr27=curr1,curr28=curr1,curr29=curr1,
4135 curr30=curr1,curr31=curr1,curr32=curr1,
4136 curr33=curr1,curr34=curr1,curr35=curr1,
4137 curr36=curr1,curr37=curr1,curr38=curr1,
4138 curr39=curr1,curr40=curr1,
4139 curr41=curr1,curr42=curr1,curr43=curr1,
4140 curr44=curr1,curr45=curr1,curr46=curr1,
4141 curr47=curr1,curr48=curr1,
4142 curr49=curr1,curr50=curr1,
4143 curr51=curr1,curr52=curr1,curr53=curr1,
4144 curr54=curr1,curr55=curr1,curr56=curr1,
4145 curr57=curr1,curr58=curr1,curr59=curr1,
4146 curr60=curr1,curr61=curr1,curr62=curr1,
4147 curr63=curr1,curr64=curr1,curr65=curr1,
4148 curr66=curr1,curr67=curr1,curr68=curr1,
4149 curr69=curr1,curr70=curr1,
4150 curr71=curr1,curr72=curr1,curr73=curr1,
4151 curr74=curr1,curr75=curr1,curr76=curr1,
4152 curr77=curr1,curr78=curr1,curr79=curr1,
4153 curr80=curr1,curr81=curr1,curr82=curr1,
4154 curr83=curr1,curr84=curr1,curr85=curr1,
4155 curr86=curr1,curr87=curr1,curr88=curr1,
4156 curr89=curr1,curr90=curr1,
4157 curr91=curr1,curr92=curr1,curr93=curr1,
4158 curr94=curr1,curr95=curr1,curr96=curr1,
4159 curr97=curr1,curr98=curr1,
4160 curr99=curr1,curr100=curr1,
4161 last_updated_by=FND_GLOBAL.user_id,
4162 last_update_date=p_ref_date,
4163 last_update_login=FND_GLOBAL.login_id
4164 WHERE analysis_name=p_name;
4165
4166 IF (g_event_level>=g_debug_level) THEN --bug 3236479
4167 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SAVED_ANALYSES_ROW.CURR1..100 with p_indicator='||p_indicator,
4168 'QRM_PA_AGGREGATION_P.UPDATE_CURRENCY_COLUMNS',g_event_level);
4169 END IF;
4170
4171 END IF;
4172 IF (g_proc_level>=g_debug_level) THEN
4173 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_CURR_COL');
4174 END IF;
4175 RETURN TRUE;
4176 EXCEPTION
4177 WHEN OTHERS THEN
4178 IF (g_error_level>=g_debug_level) THEN
4179 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS','QRM_PA_AGGREGATION_P.UPDATE_CURR_COL',g_error_level);--bug 3236479
4180 END IF;
4181 RETURN FALSE;
4182 END update_currency_columns;
4183
4184
4185
4186 /***************************************************************
4187 This procedure calculate the Totals for Table style using the
4188 currency conversion logic. Moreover, the underlying currency
4189 of the Totals will be returned together with the calculated totals.
4193 FUNCTION update_aggregate_curr(p_name VARCHAR2,
4190 Also calculate the currency multipler (FX Rate) for reporting
4191 currency as needed.
4192 ***************************************************************/
4194 p_ref_date DATE,
4195 p_ccy_case_flag NUMBER,
4196 p_ccy_agg_flag NUMBER,
4197 p_ccy_agg_level NUMBER,
4198 p_row_agg_no NUMBER,
4199 p_max_col_no NUMBER,
4200 p_underlying_ccy VARCHAR2,
4201 p_currency_source VARCHAR2,
4202 p_curr_reporting VARCHAR2,
4203 p_agg_col_curr IN OUT NOCOPY SYSTEM.QRM_VARCHAR_TABLE)
4204 RETURN BOOLEAN IS
4205
4206 v_curr SYSTEM.QRM_VARCHAR_table;
4207 i NUMBER(3);
4208 v_success BOOLEAN;
4209 v_sql VARCHAR2(255);
4210 v_curr_col_name_map SYSTEM.QRM_VARCHAR_table := SYSTEM.QRM_VARCHAR_table();
4211
4212 CURSOR get_column_header IS
4213 SELECT DECODE(type,-2,a1,-1,a1,tot_currency) FROM qrm_saved_analyses_col
4214 WHERE analysis_name=p_name AND seq_no>p_row_agg_no
4215 ORDER BY 1;
4216
4217 BEGIN
4218 IF (g_proc_level>=g_debug_level) THEN
4219 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_AGG_CURR');--bug 3236479
4220 END IF;
4221
4222 IF p_ccy_case_flag=1 THEN
4223 v_curr := SYSTEM.QRM_VARCHAR_table();
4224 v_curr.EXTEND(100);
4225 FOR i IN 1..v_curr.COUNT LOOP
4226 v_curr(i) := p_underlying_ccy;
4227 END LOOP;
4228 v_success := update_currency_columns(1,p_name,p_ref_date,v_curr);
4229 ELSIF p_ccy_case_flag=2 THEN
4230 v_curr := SYSTEM.QRM_VARCHAR_table();
4231 v_curr.EXTEND(100);
4232 --need to make it into array of size 100 bec. of the
4233 --update SQL
4234 FOR i IN 1..p_agg_col_curr.COUNT LOOP
4235 v_curr(i) := p_agg_col_curr(i);
4236 END LOOP;
4237 v_success := update_currency_columns(1,p_name,p_ref_date,v_curr);
4238 ELSIF p_ccy_case_flag=0 THEN
4239 IF p_ccy_agg_flag=1 THEN
4240 v_sql := 'UPDATE qrm_saved_analyses_row SET curr1=DECODE(type,-1,a'||p_ccy_agg_level||',tot_currency) WHERE analysis_name=:analysis_name';
4241 IF (g_proc_level>=g_debug_level) THEN
4242 xtr_risk_debug_pkg.dlog('v_sql',v_sql);
4243 END IF;
4244 EXECUTE IMMEDIATE v_sql USING p_name;
4245
4246 IF (g_event_level>=g_debug_level) THEN --bug 3236479
4247 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SAVED_ANALYSES_ROW.CURR1',
4248 'QRM_PA_AGGREGATION_P.UPDATE_AGGREGATE_CURR',g_event_level);
4249 END IF;
4250
4251 v_success := update_currency_columns(2,p_name,p_ref_date,v_curr);
4252 ELSIF p_ccy_agg_flag=2 THEN
4253 OPEN get_column_header;
4254 FETCH get_column_header BULK COLLECT INTO v_curr;
4255 CLOSE get_column_header;
4256 --need to make it into array of size 100 bec. of the
4257 --update SQL
4258 v_curr.EXTEND(100-p_max_col_no);
4259 v_success := update_currency_columns(1,p_name,p_ref_date,v_curr);
4260 ELSE --p_ccy_agg_flag=0
4261 v_curr := SYSTEM.QRM_VARCHAR_table();
4262 v_curr.EXTEND(100);
4263 FOR i IN 1..v_curr.COUNT LOOP
4264 v_curr(i) := p_curr_reporting;
4265 END LOOP;
4266 v_success := update_currency_columns(1,p_name,p_ref_date,v_curr);
4267 END IF;
4268 END IF;
4269
4270 --insert the currency col name (CURR1, CURR2, ...)
4271 v_curr_col_name_map.EXTEND(p_max_col_no+p_row_agg_no);
4272 FOR i IN p_row_agg_no+1..p_row_agg_no+p_max_col_no LOOP
4273 v_curr_col_name_map(i) := 'CURR'||i;
4274 UPDATE qrm_saved_analyses_col
4275 SET curr_col_name_map=v_curr_col_name_map(i)
4276 WHERE analysis_name=p_name AND seq_no=i;
4277 END LOOP;
4278
4279 IF (g_event_level>=g_debug_level) THEN --bug 3236479
4280 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SAVED_ANALYSES_COL.CURR_COL_NAME',
4281 'QRM_PA_AGGREGATION_P.UPDATE_AGGREGATE_CURR',g_event_level);
4282 END IF;
4283
4284 IF (g_proc_level>=g_debug_level) THEN
4285 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_AGG_CURR');-- bug 3236479
4286 END IF;
4287 RETURN TRUE;
4288
4289 EXCEPTION
4290 WHEN OTHERS THEN
4291 IF (g_error_level>=g_debug_level) THEN
4292 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS',
4293 'QRM_PA_AGGREGATION_P.UPDATE_AGG_CURR',g_error_level);--bug 3236479
4294 END IF;
4295 RETURN FALSE;
4296 END update_aggregate_curr;
4297
4298
4299
4300 /***************************************************************
4301 This function should be called if TB Label in the Setup changed.
4302 i.e. The user prefer to show the user-defined labels in the
4303 cross-tab from showing the End Date.
4304 ***************************************************************/
4305 FUNCTION update_timebuckets_label(p_name VARCHAR2)
4306 RETURN BOOLEAN IS
4307
4308 v_tb_label VARCHAR2(1);
4309 i NUMBER(5);
4310 v_row_agg_no NUMBER(5);
4311 v_dummy NUMBER;
4312 CURSOR get_tb_label IS
4313 SELECT tb_label FROM qrm_analysis_settings
4314 WHERE analysis_name=p_name AND history_flag='S';
4315 CURSOR get_row_agg_no IS
4316 SELECT COUNT(*) FROM qrm_saved_analyses_col
4317 WHERE analysis_name=p_name AND type=-2;
4318 BEGIN
4319 IF (g_proc_level>=g_debug_level) THEN
4320 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_TB_LABEL');
4321 END IF;
4322
4323 OPEN get_tb_label;
4324 FETCH get_tb_label INTO v_tb_label;
4325 CLOSE get_tb_label;
4326 IF v_tb_label IS NULL THEN
4327 FND_MESSAGE.SET_NAME('QRM','QRM_ANA_NO_SETTING');
4328 FND_MESSAGE.SET_TOKEN('ANALYSIS_NAME',p_name);
4329 RAISE e_pagg_no_setting_found;
4330 END IF;
4331 OPEN get_row_agg_no;
4332 FETCH get_row_agg_no INTO v_row_agg_no;
4333 CLOSE get_row_agg_no;
4334
4335 IF v_tb_label='L' THEN
4336 --update the qrm_saved_analyses_col by using the tb label
4337 UPDATE qrm_saved_analyses_col SET a1=tb_label
4338 WHERE analysis_name=p_name AND seq_no>v_row_agg_no
4339 AND type<0;
4340 ELSE --v_tb_label='D'
4341 --update the qrm_saved_analyses_col by using the end date
4342 UPDATE qrm_saved_analyses_col SET a1=TO_CHAR(end_date)
4343 WHERE analysis_name=p_name AND seq_no>v_row_agg_no
4344 AND type<0;
4345 END IF;
4346 COMMIT;
4347
4348 IF (g_event_level>=g_debug_level) THEN --bug 3236479
4349 XTR_RISK_DEBUG_PKG.dlog('DML','Updated QRM_SAVED_ANALYSES_COL.A1 with v_tb_label='||v_tb_label,
4350 'QRM_PA_AGGREGATION_P.UPDATE_TIMEBUCKETS_LABELS',g_event_level);
4351 END IF;
4352
4353 IF (g_proc_level>=g_debug_level) THEN
4354 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_TB_LABEL');
4355 END IF;
4356 RETURN TRUE;
4357
4358 EXCEPTION
4359 WHEN e_pagg_no_setting_found THEN
4360 RAISE e_pagg_no_setting_found;
4361
4362 IF (g_error_level>=g_debug_level) THEN
4363 xtr_risk_debug_pkg.dlog('EXCEPTION','e_pagg_no_setting_found',
4364 'QRM_PA_AGGREGATION_P.UPDATE_TB_LABEL',g_error_level);--bug 3236479
4365 END IF;
4366
4367 WHEN OTHERS THEN
4368
4369 IF (g_error_level>=g_debug_level) THEN
4370 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS',
4371 'QRM_PA_AGGREGATION_P.UPDATE_TB_LABEL',g_error_level);--bug 3236479
4372 END IF;
4373
4374 RETURN FALSE;
4375 END update_timebuckets_label;
4376
4377
4378
4379 /***************************************************************
4380 This function should be called from OA if the DIRTY indicator
4381 is semi-dirty that does not involved currency updates (S).
4382 ***************************************************************/
4383 FUNCTION update_semidirty(p_name VARCHAR2, p_ref_date DATE)
4384 RETURN VARCHAR2 IS
4385
4386 v_style VARCHAR2(1);
4387 v_success BOOLEAN := TRUE;
4388 CURSOR get_style IS
4389 SELECT style FROM qrm_analysis_settings
4390 WHERE analysis_name=p_name AND history_flag='S';
4391 BEGIN
4392 IF (g_proc_level>=g_debug_level) THEN
4393 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.UPDATE_SEMIDIRTY');
4394 END IF;
4395 --initialize fnd_msg_pub if it has not been intialized
4396 IF fnd_msg_pub.count_msg>0 THEN
4397 fnd_msg_pub.Initialize;
4398 END IF;
4399 --check whether analysis settings still there by looking whether the required
4400 --column value return IS NULL or not
4401 OPEN get_style;
4402 FETCH get_style INTO v_style;
4403 CLOSE get_style;
4404 IF v_style IS NULL THEN
4405 FND_MESSAGE.SET_NAME('QRM','QRM_ANA_NO_SETTING');
4406 FND_MESSAGE.SET_TOKEN('ANALYSIS_NAME',p_name);
4407 RAISE e_pagg_no_setting_found;
4408 END IF;
4409
4410 --update total
4411 v_success := update_total(p_name,p_ref_date);
4412 IF (g_proc_level>=g_debug_level) THEN
4413 xtr_risk_debug_pkg.dlog('update_semidirty: ' || 'v_successT',v_success);
4414 END IF;
4415 IF NOT v_success THEN
4416 RAISE e_pagg_update_total_fail;
4417 END IF;
4418 --update percent
4419 v_success := update_percent (p_name,p_ref_date);
4420 IF (g_proc_level>=g_debug_level) THEN
4421 xtr_risk_debug_pkg.dlog('update_semidirty: ' || 'v_success%',v_success);
4422 END IF;
4423 IF NOT v_success THEN
4424 RAISE e_pagg_update_percent_fail;
4425 END IF;
4426 --update timebuckets label
4427 IF v_style='X' THEN
4428 v_success := update_timebuckets_label(p_name);
4429 IF (g_proc_level>=g_debug_level) THEN
4430 xtr_risk_debug_pkg.dlog('update_semidirty: ' || 'v_successTBLabel',v_success);
4431 END IF;
4432 IF NOT v_success THEN
4433 RAISE e_pagg_update_tb_label_fail;
4434 END IF;
4435 END IF;
4436
4437 --update dirty flag
4438 UPDATE qrm_analysis_settings SET dirty='N' WHERE analysis_name=p_name;
4439 COMMIT;
4440 IF (g_proc_level>=g_debug_level) THEN
4441 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.UPDATE_SEMIDIRTY');
4442 END IF;
4443 RETURN 'T';
4444 EXCEPTION
4445 WHEN e_pagg_no_setting_found THEN
4446 fnd_msg_pub.add;
4447 --bug 3236479
4448 IF (g_proc_level>=g_ERROR_level) THEN
4449 XTR_RISK_DEBUG_PKG.dlog('EXCEPTION','QRM_PA_AGGREGATION_P.E_PAGG_NO_SETTING_FOUND',
4450 'QRM_PA_AGGREGATION_P.UPDATE_SEMIDIRTY',
4451 g_error_level);
4452 END IF;
4453 RETURN 'F';
4454 WHEN OTHERS THEN
4455
4456 IF (g_error_level>=g_debug_level) THEN
4457 xtr_risk_debug_pkg.dlog('EXCEPTION','OTHERS',
4458 'QRM_PA_AGGREGATION_P.UPDATE_SEMIDIRTY',g_error_level);--bug 3236479
4459 END IF;
4460
4461 RETURN 'F';
4462 END update_semidirty;
4463
4464
4465
4466 /***************************************************************
4467 This function find the FX Spot Rate. If there is MD_SET_CODE defined
4468 this will call xtr_market_data_p.get_md_from_set otherwise
4469 this will call qrm_calculators_p.get_rates_from_base
4470 ***************************************************************/
4471 FUNCTION get_fx_rate(p_md_set_code VARCHAR2,
4472 p_spot_date DATE,
4473 p_base_ccy VARCHAR2,
4474 p_contra_ccy VARCHAR2,
4475 p_side VARCHAR2)
4476 RETURN NUMBER IS
4477
4478 v_md_in xtr_market_data_p.md_from_set_in_rec_type;
4479 v_md_out xtr_market_data_p.md_from_set_out_rec_type;
4480 v_ccy_multiplier NUMBER;
4481 v_bid_rate_comm NUMBER;
4482 v_ask_rate_comm NUMBER;
4483 v_bid_rate_base NUMBER;
4484 v_ask_rate_base NUMBER;
4485 v_ccy VARCHAR2(15);
4486
4487 --use the same cursor as in XTR_MARKET_DATA_P.GET_MD_FROM_SET
4488 CURSOR get_fx_spot_rates IS
4489 SELECT usd_base_curr_bid_rate bid_rate,
4490 usd_base_curr_offer_rate ask_rate,
4491 1/usd_base_curr_offer_rate bid_rate_base,
4492 1/usd_base_curr_bid_rate ask_rate_base,
4493 currency
4494 FROM xtr_spot_rates
4495 WHERE (rate_date, currency) IN (SELECT MAX(rate_date), currency
4496 FROM xtr_spot_rates
4497 WHERE currency IN (p_base_ccy, p_contra_ccy)
4498 AND currency <> 'USD'
4499 AND trunc(rate_date) <= trunc(p_spot_date)
4500 GROUP BY currency);
4501
4502 BEGIN
4503 IF (g_proc_level>=g_debug_level) THEN
4504 xtr_risk_debug_pkg.dpush(null,'QRM_PA_AGGREGATION_P.GET_FX_RATE');
4505 END IF;
4506
4507 IF p_base_ccy=p_contra_ccy THEN
4508 v_ccy_multiplier := 1;
4509 ELSE
4510 IF p_md_set_code IS NOT NULL THEN
4511 v_md_in.p_md_set_code := p_md_set_code;
4512 v_md_in.p_source := 'C';
4513 v_md_in.p_indicator := 'S';
4514 v_md_in.p_spot_date := p_spot_date;
4515 v_md_in.p_ccy := p_base_ccy;
4516 v_md_in.p_contra_ccy := p_contra_ccy;
4517 v_md_in.p_side := p_side;
4518 xtr_market_data_p.get_md_from_set(v_md_in,v_md_out);
4519 --Round the FX Spot
4520 v_ccy_multiplier := v_md_out.p_md_out;
4521 ELSE
4522 OPEN get_fx_spot_rates;
4523 FETCH get_fx_spot_rates INTO v_bid_rate_comm, v_ask_rate_comm,
4524 v_bid_rate_base, v_ask_rate_base,
4525 v_ccy;
4526 CLOSE get_fx_spot_rates;
4527 IF v_bid_rate_comm IS NULL THEN
4528 FND_MESSAGE.SET_NAME('QRM','QRM_CALC_NO_DEFAULT_SPOT_ERR');
4529 FND_MESSAGE.SET_TOKEN('CCY',p_contra_ccy);
4530 RAISE e_pagg_no_fxrate_found;
4531 ELSE
4532 IF p_side IN ('A','ASK') THEN
4533 IF p_base_ccy='USD' THEN --use Commodity Quote Basis
4534 v_ccy_multiplier := v_ask_rate_comm;
4535 ELSE
4536 v_ccy_multiplier := v_ask_rate_base;
4537 END IF;
4538 ELSIF p_side IN ('B','BID') THEN
4539 IF p_base_ccy='USD' THEN --use Commodity Quote Basis
4540 v_ccy_multiplier := v_bid_rate_comm;
4541 ELSE
4542 v_ccy_multiplier := v_bid_rate_base;
4543 END IF;
4544 ELSE --'MID'
4545 IF p_base_ccy='USD' THEN --use Commodity Quote Basis
4546 v_ccy_multiplier := (v_ask_rate_comm+v_bid_rate_comm)/2;
4547 ELSE
4548 v_ccy_multiplier := (v_ask_rate_base+v_bid_rate_base)/2;
4549 END IF;
4550 END IF;
4551 END IF;
4552 END IF;
4553
4554 END IF;
4555 IF (g_proc_level>=g_debug_level) THEN
4556 xtr_risk_debug_pkg.dpop(null,'QRM_PA_AGGREGATION_P.GET_FX_RATE');
4557 END IF;
4558 RETURN v_ccy_multiplier;
4559
4560 EXCEPTION
4561 WHEN xtr_market_data_p.e_mdcs_no_data_found THEN
4562
4563 IF (G_ERROR_level>=g_debug_level) THEN
4564 xtr_risk_debug_pkg.dlog('EXCEPTION','xtr_market_data.e_mdcs_no_data_found',
4565 'QRM_PA_AGGREGATION_P.GET_FX_RATE',g_eRROR_level);--bug 3236479
4566 END IF;
4567
4568 FND_MESSAGE.SET_NAME('QRM','QRM_CALC_NO_DEFAULT_SPOT_ERR');
4569 FND_MESSAGE.SET_TOKEN('CCY',p_contra_ccy);
4570 RAISE e_pagg_no_fxrate_found;
4571 END get_fx_rate;
4572
4573
4574
4575
4576 END QRM_PA_AGGREGATION_P;