[Home] [Help]
PACKAGE BODY: APPS.OKL_PRICING_UTILS_PVT
Source
1 PACKAGE BODY OKL_PRICING_UTILS_PVT AS
2 /* $Header: OKLRPIUB.pls 120.80.12020000.5 2012/11/24 04:22:54 rpillay ship $ */
3
4 G_MODULE VARCHAR2(255) := 'okl.stream.esg.okl_esg_transport_pvt';
5 G_DEBUG_ENABLED CONSTANT VARCHAR2(10) := OKL_DEBUG_PUB.CHECK_LOG_ENABLED;
6 G_IS_DEBUG_STATEMENT_ON BOOLEAN;
7
8 PROCEDURE put_in_log(
9 p_debug_enabled IN VARCHAR2,
10 is_debug_procedure_on IN BOOLEAN,
11 is_debug_statement_on IN BOOLEAN,
12 p_module IN fnd_log_messages.module%TYPE,
13 p_level IN VARCHAR2,
14 msg IN VARCHAR2 )
15 AS
16 -- l_level: S - Statement, P- Procedure, B - Both
17 BEGIN
18 IF(p_debug_enabled='Y' AND is_debug_procedure_on AND p_level = 'P')
19 THEN
20 okl_debug_pub.log_debug(
21 FND_LOG.LEVEL_PROCEDURE,
22 p_module,
23 msg);
24 ELSIF (p_debug_enabled='Y' AND is_debug_statement_on AND
25 (p_level = 'S' OR p_level = 'B' ))
26 THEN
27 okl_debug_pub.log_debug(
28 FND_LOG.LEVEL_STATEMENT,
29 p_module,
30 msg);
31 END IF;
32 END put_in_log;
33
34 -- Returns true if the inputed p_year is an leap year
35 -- else false
36 FUNCTION is_leap_year( p_year IN NUMBER)
37 RETURN BOOLEAN
38 AS
39 l_year NUMBER(5);
40 BEGIN
41 IF ( MOD(p_year, 4) = 0 AND MOD(p_year, 100) <> 0 )OR
42 MOD(p_year, 400) = 0
43 THEN
44 RETURN TRUE;
45 END IF;
46 RETURN FALSE;
47 END is_leap_year;
48
49 -- Returns true if the year in the p_date is a leap year
50 -- else returns false
51 FUNCTION is_leap_year( p_date IN DATE)
52 RETURN BOOLEAN
53 AS
54 l_year NUMBER(5);
55 BEGIN
56 l_year := to_number( to_char( p_date, 'YYYY') );
57 IF is_leap_year( p_year => l_year )
58 THEN
59 RETURN TRUE;
60 END IF;
61 RETURN FALSE;
62 END is_leap_year;
63
64 PROCEDURE get_day_count_method(
65 p_days_in_month IN VARCHAR2,
66 p_days_in_year IN VARCHAR2,
67 x_day_count_method OUT NOCOPY VARCHAR2,
68 x_return_status OUT NOCOPY VARCHAR2 )
69 AS
70 l_api_name VARCHAR2(30) := 'get_day_count_method';
71 BEGIN
72 IF p_days_in_month = '30' AND
73 p_days_in_year = '360'
74 THEN
75 x_day_count_method := 'THIRTY';
76 ELSIF p_days_in_month = 'ACTUAL' AND
77 p_days_in_year = '365'
78 THEN
79 x_day_count_method := 'ACT365';
80 ELSIF p_days_in_month = 'ACTUAL' AND
81 p_days_in_year = 'ACTUAL'
82 THEN
83 x_day_count_method := 'ACTUAL';
84 ELSE
85 x_return_status := OKL_API.G_RET_STS_ERROR;
86 RETURN;
87 END IF;
88 --print( l_api_name || ': ' || 'l_days_in_month= ' || p_days_in_month ||
89 -- ' | l_days_in_year = ' || p_days_in_year);
90
91 x_return_status := OKL_API.G_RET_STS_SUCCESS;
92 END get_day_count_method;
93
94
95 PROCEDURE get_days_in_year_and_month(
96 p_day_count_method IN VARCHAR2,
97 x_days_in_month OUT NOCOPY VARCHAR2,
98 x_days_in_year OUT NOCOPY VARCHAR2,
99 x_return_status OUT NOCOPY VARCHAR2 )
100 AS
101 l_api_name VARCHAR2(30) := 'get_days_in_year_and_month';
102 BEGIN
103 IF p_day_count_method = 'THIRTY'
104 THEN
105 x_days_in_month := '30';
106 x_days_in_year := '360';
107 ELSIF p_day_count_method = 'ACT365'
108 THEN
109 x_days_in_month := 'ACTUAL';
110 x_days_in_year := '365';
111 ELSIF p_day_count_method = 'ACTUAL'
112 THEN
113 x_days_in_month := 'ACTUAL';
114 x_days_in_year := 'ACTUAL';
115 ELSE
116 --print( l_api_name || ': ' || 'p_day_count_method= ' || p_day_count_method );
117 x_return_status := OKL_API.G_RET_STS_ERROR;
118 RETURN;
119 END IF;
120 --print( l_api_name || ': ' || 'l_days_in_month= ' || x_days_in_month ||
121 -- ' | l_days_in_year = ' || x_days_in_year);
122 x_return_status := OKL_API.G_RET_STS_SUCCESS;
123 END get_days_in_year_and_month;
124
125 -- Procedure to fetch the day convention from the OKL_K_RATE_PARAMS
126 -- if not found reach the SGT assosiated and fetch the day conventions
127 PROCEDURE get_day_convention(
128 p_id IN NUMBER, -- ID of the contract/quote
129 p_source IN VARCHAR2, -- 'ESG'/'ISG' are acceptable values
130 x_days_in_month OUT NOCOPY VARCHAR2,
131 x_days_in_year OUT NOCOPY VARCHAR2,
132 x_return_status OUT NOCOPY VARCHAR2)
133 AS
134 l_api_name VARCHAR2(30) := 'get_day_convention';
135 l_return_status VARCHAR2(1);
136
137 -- Cursor to fetch the day convention from the OKL_K_RATE_PARAMS table ..
138 CURSOR day_conv_csr( khrId NUMBER) IS
139 SELECT days_in_a_year_code,
140 days_in_a_month_code,
141 DECODE(rate_params.days_in_a_month_code,'30','360',
142 rate_params.days_in_a_month_code) esg_days_in_month_code
143 FROM OKL_K_RATE_PARAMS rate_params
144 WHERE khr_id = khrId;
145
146 -- Cursor to fetch the day convention from the SGT
147 CURSOR get_day_conv_on_sgt_csr( p_khr_id IN VARCHAR2 )
148 IS
149 SELECT gts.days_in_month_code days_in_a_month_code,
150 gts.days_in_yr_code days_in_a_year_code,
151 DECODE(gts.days_in_month_code,'30','360',gts.days_in_month_code)
152 esg_days_in_month_code
153 FROM
154 okl_k_headers khr,
155 okl_products_v pdt,
156 okl_ae_tmpt_sets_v aes,
157 OKL_ST_GEN_TMPT_SETS gts
158 WHERE
159 khr.pdt_id = pdt.id AND
160 pdt.aes_id = aes.id AND
161 aes.gts_id = gts.id AND
162 khr.id = p_khr_id;
163 l_days_in_month VARCHAR2(30);
164 l_days_in_year VARCHAR2(30);
165 BEGIN
166 IF (G_DEBUG_ENABLED = 'Y') THEN
167 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
168 END IF;
169 l_return_status := G_RET_STS_ERROR;
170 FOR t_rec IN day_conv_csr(p_id)
171 LOOP
172 IF p_source = 'ESG'
173 THEN
174 l_days_in_month := t_rec.esg_days_in_month_code;
175 ELSE
176 l_days_in_month := t_rec.days_in_a_month_code;
177 END IF;
178 l_days_in_year := t_rec.days_in_a_year_code;
179 l_return_status := G_RET_STS_SUCCESS;
180 END LOOP;
181 -- Bug 4960625: Start
182 -- If there is a record present in the OKL_K_RATE_PARAMS for the corresponding
183 -- Contract, but the Day conventions are null there, then fetch the Day conventions
184 -- from the Stream Generation Template.
185 IF l_days_in_month IS NULL OR
186 l_days_in_year IS NULL
187 THEN
188 l_return_status := G_RET_STS_ERROR;
189 END IF;
190 -- Bug 4960625: End
191 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
192 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'Tried fetching the day convention from OKL_K_RATE_PARAMS ' || l_return_status );
193 END IF;
194 IF l_return_status <> G_RET_STS_SUCCESS
195 THEN
196 -- Fetch the day convention from the SGT assosiated to the contract
197 FOR t_rec IN get_day_conv_on_sgt_csr( p_khr_id => p_id )
198 LOOP
199 IF p_source = 'ESG'
200 THEN
201 l_days_in_month := t_rec.esg_days_in_month_code;
202 ELSE
203 l_days_in_month := t_rec.days_in_a_month_code;
204 END IF;
205 l_days_in_year := t_rec.days_in_a_year_code;
206 l_return_status := G_RET_STS_SUCCESS;
207 END LOOP;
208 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
209 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'Tried fetching the day convention from SGT ' || l_return_status );
210 END IF;
211 END IF;
212 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
213 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'Month / Year = ' || l_days_in_month || '/' || l_days_in_year );
214 END IF;
215 IF l_return_status = OKL_API.G_RET_STS_ERROR THEN
216 RAISE OKL_API.G_EXCEPTION_ERROR;
217 END IF;
218 -- Return the values
219 x_days_in_month := l_days_in_month;
220 x_days_in_year := l_days_in_year;
221 x_return_status := l_return_status;
222 EXCEPTION
223 WHEN OKL_API.G_EXCEPTION_ERROR THEN
224 x_return_status := G_RET_STS_ERROR;
225 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
226 x_return_status := G_RET_STS_UNEXP_ERROR;
227 WHEN OTHERS THEN
228 OKL_API.SET_MESSAGE (
229 p_app_name => G_APP_NAME,
230 p_msg_name => G_DB_ERROR,
231 p_token1 => G_PROG_NAME_TOKEN,
232 p_token1_value => l_api_name,
233 p_token2 => G_SQLCODE_TOKEN,
234 p_token2_value => sqlcode,
235 p_token3 => G_SQLERRM_TOKEN,
236 p_token3_value => sqlerrm);
237 x_return_status := G_RET_STS_UNEXP_ERROR;
238 END get_day_convention;
239
240
241 -- Get the Quick Quote Header Details
242 PROCEDURE get_so_hdr(
243 p_api_version IN NUMBER,
244 p_init_msg_list IN VARCHAR2,
245 x_return_status OUT NOCOPY VARCHAR2,
246 x_msg_count OUT NOCOPY NUMBER,
247 x_msg_data OUT NOCOPY VARCHAR2,
248 p_so_id IN NUMBER,
249 p_so_type IN VARCHAR2,
250 x_so_hdr_rec OUT NOCOPY so_hdr_rec_type )
251 AS
252 CURSOR so_qq_hdr_csr( p_qq_id IN NUMBER )
253 IS
254 SELECT ID
255 ,REFERENCE_NUMBER
256 ,EXPECTED_START_DATE
257 ,CURRENCY_CODE
258 ,TERM
259 ,SALES_TERRITORY_ID
260 ,END_OF_TERM_OPTION_ID
261 ,PRICING_METHOD
262 ,STRUCTURED_PRICING
263 ,LINE_LEVEL_PRICING
264 ,LEASE_RATE_FACTOR
265 ,RATE_CARD_ID
266 ,RATE_TEMPLATE_ID
267 ,TARGET_RATE_TYPE
268 ,TARGET_RATE
269 ,TARGET_AMOUNT -- Need to solve for this amount only ...!
270 ,TARGET_FREQUENCY
271 ,TARGET_ARREARS
272 ,TARGET_PERIODS
273 FROM OKL_QUICK_QUOTES_B
274 WHERE ID = p_qq_id;
275 l_so_hdr_rec so_hdr_rec_type;
276 -- Local Variables
277 l_api_version CONSTANT NUMBER DEFAULT 1.0;
278 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_so_hdr';
279 l_return_status VARCHAR2(1);
280 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.OKL_PRICING_UTILS_PVT.get_so_hdr';
281 l_debug_enabled VARCHAR2(10);
282 is_debug_procedure_on BOOLEAN;
283 is_debug_statement_on BOOLEAN;
284 BEGIN
285 l_return_status := OKL_API.G_RET_STS_SUCCESS;
286 l_debug_enabled := okl_debug_pub.check_log_enabled;
287 is_debug_procedure_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
288 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
289 'begin debug OKLRPIUB.pls call get_so_hdr');
290 -- check for logging on STATEMENT level
291 is_debug_statement_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
292 -- Call START_ACTIVITY to create savepoint, check compatibility
293 -- and initialize message list
294 l_return_status := OKL_API.START_ACTIVITY(
295 p_api_name => l_api_name,
296 p_pkg_name => G_PKG_NAME,
297 p_init_msg_list => p_init_msg_list,
298 l_api_version => l_api_version,
299 p_api_version => p_api_version,
300 p_api_type => g_api_type,
301 x_return_status => x_return_status);
302 --Check if activity started successfully
303 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
304 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
305 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
306 RAISE OKL_API.G_EXCEPTION_ERROR;
307 END IF;
308 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
309 ': p_so_type =' || p_so_type );
310 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
311 ': p_so_id =' || p_so_id );
312 IF (p_so_type = 'QQ')
313 THEN
314 -- Fetch the Header Information from the so_qq_hdr_csr
315 FOR t_rec in so_qq_hdr_csr(p_qq_id => p_so_id)
316 LOOP
317 l_so_hdr_rec.id := t_rec.id;
318 l_so_hdr_rec.so_type := 'QQ';
319 l_so_hdr_rec.reference_number := t_rec.reference_number ;
320 l_so_hdr_rec.expected_start_date := t_rec.expected_start_date ;
321 l_so_hdr_rec.currency_code := t_rec.currency_code ;
322 l_so_hdr_rec.term := t_rec.term ;
323 l_so_hdr_rec.sales_territory_id := t_rec.sales_territory_id;
324 l_so_hdr_rec.end_of_term_option_id := t_rec.end_of_term_option_id ;
325 l_so_hdr_rec.pricing_method := t_rec.pricing_method;
326 l_so_hdr_rec.structured_pricing := t_rec.structured_pricing;
327 l_so_hdr_rec.line_level_pricing := t_rec.line_level_pricing;
328 l_so_hdr_rec.lease_rate_factor := t_rec.lease_rate_factor;
329 l_so_hdr_rec.rate_card_id := t_rec.rate_card_id ;
330 l_so_hdr_rec.rate_template_id := t_rec.rate_template_id ;
331 l_so_hdr_rec.target_rate_type := t_rec.target_rate_type ;
332 l_so_hdr_rec.target_rate := t_rec.target_rate ;
333 l_so_hdr_rec.target_amount := t_rec.target_amount ;
334 l_so_hdr_rec.target_frequency := t_rec.target_frequency ;
335 l_so_hdr_rec.target_arrears := t_rec.target_arrears ;
336 l_so_hdr_rec.target_periods := t_rec.target_periods;
337 END LOOP;
338 ELSIF p_so_type = 'SQ'
339 THEN
340 -- Code to be written for handling the Standard Quote
341 NULL;
342 ELSE
343 -- Code to be written for raising an exception
344 OKL_API.SET_MESSAGE( p_app_name => g_app_name,
345 p_msg_name => g_invalid_value,
346 p_token1 => g_col_name_token,
347 p_token1_value => 'QQ_ID');
348 RAISE OKL_API.G_EXCEPTION_ERROR;
349 END IF;
350 x_so_hdr_rec := l_so_hdr_rec;
351 x_return_status := l_return_status;
352 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count, x_msg_data => x_msg_data);
353 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
354 'end debug OKLRPIUB.pls call get_so_hdr');
355 EXCEPTION
356 WHEN OKL_API.G_EXCEPTION_ERROR THEN
357 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
358 p_api_name => l_api_name,
359 p_pkg_name => G_PKG_NAME,
360 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
361 x_msg_count => x_msg_count,
362 x_msg_data => x_msg_data,
363 p_api_type => g_api_type);
364 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
365 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
366 p_api_name => l_api_name,
367 p_pkg_name => G_PKG_NAME,
368 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
369 x_msg_count => x_msg_count,
370 x_msg_data => x_msg_data,
371 p_api_type => g_api_type);
372 WHEN OTHERS THEN
373 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
374 p_api_name => l_api_name,
375 p_pkg_name => G_PKG_NAME,
376 p_exc_name => 'OTHERS',
377 x_msg_count => x_msg_count,
378 x_msg_data => x_msg_data,
379 p_api_type => g_api_type);
380 END get_so_hdr;
381 -- Procedure to return the Days Per Period and Periods Per Year
382 -- This api is based on the day convention of THIRTY only !
383 -- so for x_dpp the possible return values are 30, 90, 180. 360 only.
384 PROCEDURE get_dpp_ppy(
385 p_frequency IN VARCHAR2,
386 x_dpp OUT NOCOPY NUMBER,
387 x_ppy OUT NOCOPY NUMBER,
388 x_return_status OUT NOCOPY VARCHAR2)
389 IS
390 l_api_name VARCHAR2(30):= 'get_dpp_ppy';
391 BEGIN
392 IF p_frequency = 'M'
393 THEN
394 -- Monthly
395 x_dpp := 30;
396 x_ppy := 12;
397 x_return_status := OKL_API.G_RET_STS_SUCCESS;
398 RETURN;
399 ELSIF p_frequency = 'Q'
400 THEN
401 -- Quarterly
402 x_dpp := 90;
403 x_ppy := 4;
404 x_return_status := OKL_API.G_RET_STS_SUCCESS;
405 RETURN;
406 ELSIF p_frequency = 'S'
407 THEN
408 -- Semi Anually
409 x_dpp := 180;
410 x_ppy := 2;
411 x_return_status := OKL_API.G_RET_STS_SUCCESS;
412 RETURN;
413 ELSIF p_frequency = 'A'
414 THEN
415 -- Annually
416 x_dpp := 360;
417 x_ppy := 1;
418 x_return_status := OKL_API.G_RET_STS_SUCCESS;
419 RETURN;
420 ELSE
421 -- Raise an Exception
422 RAISE OKL_API.G_EXCEPTION_ERROR;
423 END IF;
424 EXCEPTION
425 WHEN OKL_API.G_EXCEPTION_ERROR THEN
426 x_return_status := G_RET_STS_ERROR;
427 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
428 x_return_status := G_RET_STS_UNEXP_ERROR;
429 WHEN OTHERS THEN
430 OKL_API.SET_MESSAGE (
431 p_app_name => G_APP_NAME,
432 p_msg_name => G_DB_ERROR,
433 p_token1 => G_PROG_NAME_TOKEN,
434 p_token1_value => l_api_name,
435 p_token2 => G_SQLCODE_TOKEN,
436 p_token2_value => sqlcode,
437 p_token3 => G_SQLERRM_TOKEN,
438 p_token3_value => sqlerrm);
439 x_return_status := G_RET_STS_UNEXP_ERROR;
440 END get_dpp_ppy;
441
442 -- API to get the Item Category Details for a particular quick quote
443 PROCEDURE get_qq_item_cat_details(
444 p_api_version IN NUMBER,
445 p_init_msg_list IN VARCHAR2,
446 x_return_status OUT NOCOPY VARCHAR2,
447 x_msg_count OUT NOCOPY NUMBER,
448 x_msg_data OUT NOCOPY VARCHAR2,
449 p_qq_id IN NUMBER,
450 p_pricing_method IN VARCHAR2,
451 x_asset_amounts_tbl OUT NOCOPY so_asset_details_tbl_type)
452 AS
453 -- Cursor Declarations
454 CURSOR item_cat_csr( p_qq_id NUMBER )
455 IS
456 SELECT value
457 ,basis
458 ,nvl(nvl(end_of_term_value, end_of_term_value_default), 0) end_of_term_amount
459 ,percentage_of_total_cost
460 FROM OKL_QUICK_QUOTE_LINES_B qql
461 WHERE qql.quick_quote_id = p_qq_id
462 AND TYPE = G_ITEMCATEGORY_TYPE; -- Item Category Type
463 -- Cursor to fetch the EOT Type
464 CURSOR get_eot_type( p_qq_id NUMBER )
465 IS
466 SELECT qq.id
467 ,qq.reference_number
468 ,eot.end_of_term_name
469 ,eot.eot_type_code eot_type_code
470 ,eot.end_of_term_id end_of_term_id
471 ,eotversion.end_of_term_ver_id
472 FROM OKL_QUICK_QUOTES_B qq,
473 okl_fe_eo_term_vers eotversion,
474 okl_fe_eo_terms_all_b eot
475 WHERE qq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
476 AND eot.end_of_term_id = eotversion.end_of_term_id
477 AND qq.id = p_qq_id;
478 -- Local Variables
479 l_api_version CONSTANT NUMBER DEFAULT 1.0;
480 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_item_cat_details';
481 l_return_status VARCHAR2(1);
482 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
483 || G_PKG_NAME || '.' || UPPER(l_api_name);
484 l_debug_enabled VARCHAR2(10);
485 is_debug_procedure_on BOOLEAN;
486 is_debug_statement_on BOOLEAN;
487 -- Variables Declaration
488 l_asset_amounts_tbl so_asset_details_tbl_type;
489 ic_index NUMBER;
490 l_eot_type_code VARCHAR2(30);
491 BEGIN
492 l_return_status := OKL_API.G_RET_STS_SUCCESS;
493
494 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
495 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
496
497 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
498 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
499 -- check for logging on STATEMENT level
500 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
501 l_return_status := OKL_API.START_ACTIVITY(
502 p_api_name => l_api_name,
503 p_pkg_name => G_PKG_NAME,
504 p_init_msg_list => p_init_msg_list,
505 l_api_version => l_api_version,
506 p_api_version => p_api_version,
507 p_api_type => g_api_type,
508 x_return_status => x_return_status);
509 --Check if activity started successfully
510 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
511 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
512 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
513 RAISE OKL_API.G_EXCEPTION_ERROR;
514 END IF;
515 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
516 ': p_qq_id =' || p_qq_id );
517 -- Know the type of the EOT and then proceed with the values directly or calculate the amount
518 FOR t_rec IN get_eot_type( p_qq_id => p_qq_id )
519 LOOP
520 l_eot_type_code := t_rec.eot_type_code;
521 END LOOP;
522 ic_index := 1;
523 FOR t_rec in item_cat_csr( p_qq_id => p_qq_id )
524 LOOP
525 -- Store the Item Category Details in the Item Categories Table also
526 IF p_pricing_method = 'SF' -- Solve for Financed Amount
527 THEN
528 l_asset_amounts_tbl(ic_index).asset_cost := NULL;
529 ELSE
530 l_asset_amounts_tbl(ic_index).asset_cost := t_rec.value;
531 END IF;
532 l_asset_amounts_tbl(ic_index).value := t_rec.value;
533 l_asset_amounts_tbl(ic_index).basis := t_rec.basis;
534 l_asset_amounts_tbl(ic_index).percentage_of_total_cost := t_rec.percentage_of_total_cost;
535 IF l_eot_type_code = 'AMOUNT' OR l_eot_type_code = 'RESIDUAL_AMOUNT'
536 THEN
537 -- End of Term Amounts has been directly mentioned in this case
538 l_asset_amounts_tbl(ic_index).end_of_term_amount := t_rec.end_of_term_amount;
539 ELSIF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
540 THEN
541 -- End of Term Amounts are entered in terms of percentage here
542 IF p_pricing_method = 'SF'
543 THEN
544 -- Store the equivalent percentage of the EOT Amount interms of percentage only.
545 -- Note: Both percentage_of_total_cost and end_of_term_amount are
546 -- stored in terms of percentage
547 l_asset_amounts_tbl(ic_index).end_of_term_amount :=
548 (t_rec.percentage_of_total_cost / 100 ) * (t_rec.end_of_term_amount /100);
549 ELSE
550 -- Apply the End of Term Percentage on the Asset Cost to get the EOT Amount
551 l_asset_amounts_tbl(ic_index).end_of_term_amount :=
552 t_rec.end_of_term_amount * t_rec.value / 100;
553 END IF;
554 END IF;
555 -- Increment the ic_index
556 ic_index := ic_index + 1;
557 END LOOP;
558 -- Setting up the return variables
559 x_asset_amounts_tbl := l_asset_amounts_tbl;
560 x_return_status := l_return_status;
561 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
562 x_msg_data => x_msg_data);
563 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
564 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
565 EXCEPTION
566 WHEN OKL_API.G_EXCEPTION_ERROR THEN
567 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
568 p_api_name => l_api_name,
569 p_pkg_name => G_PKG_NAME,
570 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
571 x_msg_count => x_msg_count,
572 x_msg_data => x_msg_data,
573 p_api_type => g_api_type);
574 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
575 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
576 p_api_name => l_api_name,
577 p_pkg_name => G_PKG_NAME,
578 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
579 x_msg_count => x_msg_count,
580 x_msg_data => x_msg_data,
581 p_api_type => g_api_type);
582 WHEN OTHERS THEN
583 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
584 p_api_name => l_api_name,
585 p_pkg_name => G_PKG_NAME,
586 p_exc_name => 'OTHERS',
587 x_msg_count => x_msg_count,
588 x_msg_data => x_msg_data,
589 p_api_type => g_api_type);
590 END get_qq_item_cat_details;
591
592 PROCEDURE get_qq_asset_oec (
593 p_api_version IN NUMBER,
594 p_init_msg_list IN VARCHAR2,
595 x_return_status OUT NOCOPY VARCHAR2,
596 x_msg_count OUT NOCOPY NUMBER,
597 x_msg_data OUT NOCOPY VARCHAR2,
598 p_asset_cost IN NUMBER,
599 p_fin_adj_det_rec IN so_amt_details_rec_type,
600 x_oec OUT NOCOPY NUMBER)
601 AS
602 -- Local Variables
603 l_api_version CONSTANT NUMBER DEFAULT 1.0;
604 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_asset_oec';
605 l_return_status VARCHAR2(1);
606
607 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
608 || G_PKG_NAME || '.' || UPPER(l_api_name);
609 l_debug_enabled VARCHAR2(10);
610 is_debug_procedure_on BOOLEAN;
611 is_debug_statement_on BOOLEAN;
612
613 l_oec NUMBER;
614 l_item_cat_percent NUMBER;
615 BEGIN
616 l_return_status := OKL_API.G_RET_STS_SUCCESS;
617 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
618 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
619 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
620 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
621 -- check for logging on STATEMENT level
622 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
623 l_return_status := OKL_API.START_ACTIVITY(
624 p_api_name => l_api_name,
625 p_pkg_name => G_PKG_NAME,
626 p_init_msg_list => p_init_msg_list,
627 l_api_version => l_api_version,
628 p_api_version => p_api_version,
629 p_api_type => g_api_type,
630 x_return_status => x_return_status);
631 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
632 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
633 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
634 RAISE OKL_API.G_EXCEPTION_ERROR;
635 END IF;
636 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',':Start ' );
637 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'p_asset_cost=' || p_asset_cost );
638
639 l_oec := p_asset_cost;
640 l_item_cat_percent := 0;
641 -- Dealing with the downpayment amount
642 IF p_fin_adj_det_rec.down_payment_basis = G_FIXED_BASIS
643 THEN
644 l_oec := l_oec - p_fin_adj_det_rec.down_payment_amount;
645 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
646 'Down Payment Amount= '|| p_fin_adj_det_rec.down_payment_amount );
647 ELSIF p_fin_adj_det_rec.down_payment_basis = G_QQ_ASSET_COST_BASIS
648 THEN
649 l_item_cat_percent := nvl(l_item_cat_percent, 0 ) + p_fin_adj_det_rec.down_payment_value;
650 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
651 'Down payment percentage ' || p_fin_adj_det_rec.down_payment_value );
652 END IF;
653 IF p_fin_adj_det_rec.tradein_basis = G_FIXED_BASIS
654 THEN
655 l_oec := l_oec - p_fin_adj_det_rec.tradein_amount;
656 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
657 'Trade-in Amount= '|| p_fin_adj_det_rec.tradein_amount );
658 ELSIF p_fin_adj_det_rec.tradein_basis = G_QQ_ASSET_COST_BASIS
659 THEN
660 l_item_cat_percent := nvl(l_item_cat_percent, 0 ) + p_fin_adj_det_rec.tradein_value;
661 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
662 'Trade-in %age = ' || p_fin_adj_det_rec.tradein_value );
663 END IF;
664 IF p_fin_adj_det_rec.subsidy_basis_tbl IS NOT NULL AND
665 p_fin_adj_det_rec.subsidy_basis_tbl.COUNT > 0
666 THEN
667 FOR t in p_fin_adj_det_rec.subsidy_basis_tbl.FIRST ..
668 p_fin_adj_det_rec.subsidy_basis_tbl.LAST
669 LOOP
670 IF p_fin_adj_det_rec.subsidy_basis_tbl(t) = G_FIXED_BASIS
671 THEN
672 l_oec := l_oec - p_fin_adj_det_rec.subsidy_value_tbl(t);
673 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
674 'Subsidy Amount(' || t || ')= '|| p_fin_adj_det_rec.subsidy_value_tbl(t) );
675 ELSIF p_fin_adj_det_rec.subsidy_basis_tbl(t) = G_QQ_ASSET_COST_BASIS
676 THEN
677 l_item_cat_percent := nvl(l_item_cat_percent, 0 ) + p_fin_adj_det_rec.subsidy_value_tbl(t);
678 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
679 'Subsidy(' || t || ') %age =' || p_fin_adj_det_rec.subsidy_value_tbl(t) );
680 END IF;
681 END LOOP;
682 END IF;
683 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
684 'l_item_cat_percent=' || nvl( l_item_cat_percent,0) );
685 -- Calculate the final OEC of the Asset !
686 l_oec := l_oec - ( p_asset_cost * l_item_cat_percent / 100 );
687 IF l_oec > 0
688 THEN
689 -- Valid! Do Nothing!
690 NULL;
691 ELSE
692 -- Item OEC should be greater than zero !
693 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
694 ' Asset OEC should be greater than zero !! p_asset_cost= '|| p_asset_cost );
695 -- Show an error Message OKL_LP_FIN_ADJ_AMT_LESS
696 OKL_API.SET_MESSAGE (
697 p_app_name => G_APP_NAME,
698 p_msg_name => 'OKL_LP_FIN_ADJ_AMT_LESS');
699 RAISE OKL_API.G_EXCEPTION_ERROR;
700 END IF;
701 -- Setting up the retun values
702 x_oec := l_oec;
703 x_return_status := l_return_status;
704 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
705 x_msg_data => x_msg_data);
706 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
707 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
708 EXCEPTION
709 WHEN OKL_API.G_EXCEPTION_ERROR THEN
710 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
711 p_api_name => l_api_name,
712 p_pkg_name => G_PKG_NAME,
713 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
714 x_msg_count => x_msg_count,
715 x_msg_data => x_msg_data,
716 p_api_type => g_api_type);
717
718 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
719 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
720 p_api_name => l_api_name,
721 p_pkg_name => G_PKG_NAME,
722 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
723 x_msg_count => x_msg_count,
724 x_msg_data => x_msg_data,
725 p_api_type => g_api_type);
726
727 WHEN OTHERS THEN
728 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
729 p_api_name => l_api_name,
730 p_pkg_name => G_PKG_NAME,
731 p_exc_name => 'OTHERS',
732 x_msg_count => x_msg_count,
733 x_msg_data => x_msg_data,
734 p_api_type => g_api_type);
735 END get_qq_asset_oec;
736
737 -- API to get the Capital Cost, Subsidy Amount,
738 -- Down Payment Amount, Trade in Amount for a particular Quick Quote
739 -- Accepts quick quote id
740 PROCEDURE get_qq_fin_adj_details(
741 p_api_version IN NUMBER,
742 p_init_msg_list IN VARCHAR2,
743 x_return_status OUT NOCOPY VARCHAR2,
744 x_msg_count OUT NOCOPY NUMBER,
745 x_msg_data OUT NOCOPY VARCHAR2,
746 p_qq_id IN NUMBER,
747 p_pricing_method IN VARCHAR2,
748 p_item_category_amount IN NUMBER,
749 x_all_amounts_rec OUT NOCOPY so_amt_details_rec_type)
750 AS
751 -- Cursor to fetch the Quick Quote Financial Adjustment Details
752 -- like Down Payment, Tradein, Subsidy
753 CURSOR fin_adj_csr( p_qq_id NUMBER )
754 IS
755 SELECT type
756 ,basis
757 ,value
758 FROM OKL_QUICK_QUOTE_LINES_B qql
759 WHERE qql.quick_quote_id = p_qq_id
760 AND TYPE IN ( G_DOWNPAYMENT_TYPE, -- Down Payment Type
761 G_TRADEIN_TYPE, -- Trade in Type
762 G_SUBSIDY_TYPE -- Subsidy Type
763 )
764 ORDER BY TYPE;
765 -- Local Variables
766 l_all_amounts_rec so_amt_details_rec_type;
767 l_api_version CONSTANT NUMBER DEFAULT 1.0;
768 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_fin_adj_details';
769 l_return_status VARCHAR2(1);
770 l_module CONSTANT fnd_log_messages.module%TYPE
771 := 'LEASE.ACCOUNTING.PRICING.OKL_PRICING_UTILS_PVT.get_qq_fin_adjustments';
772 l_debug_enabled VARCHAR2(10);
773 is_debug_procedure_on BOOLEAN;
774 is_debug_statement_on BOOLEAN;
775
776 sub_index NUMBER;
777 BEGIN
778 l_return_status := OKL_API.G_RET_STS_SUCCESS;
779 l_debug_enabled := okl_debug_pub.check_log_enabled;
780 is_debug_procedure_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
781 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
782 'begin debug OKLRPIUB.pls call get_qq_fin_adjustments');
783 -- check for logging on STATEMENT level
784 is_debug_statement_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
785 -- Call START_ACTIVITY to create savepoint, check compatibility
786 -- and initialize message list
787 l_return_status := OKL_API.START_ACTIVITY(
788 p_api_name => l_api_name,
789 p_pkg_name => G_PKG_NAME,
790 p_init_msg_list => p_init_msg_list,
791 l_api_version => l_api_version,
792 p_api_version => p_api_version,
793 p_api_type => g_api_type,
794 x_return_status => x_return_status);
795 --Check if activity started successfully
796 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
797 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
798 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
799 RAISE OKL_API.G_EXCEPTION_ERROR;
800 END IF;
801 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',':Start ' );
802 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',' p_qq_id : ' || p_qq_id);
803 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',' p_pricing_method : ' || p_pricing_method );
804 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',' p_item_category_amount ' || p_item_category_amount);
805 sub_index := 1;
806 FOR t_rec in fin_adj_csr( p_qq_id => p_qq_id )
807 LOOP
808 IF t_rec.type = G_DOWNPAYMENT_TYPE
809 THEN
810 l_all_amounts_rec.down_payment_basis := t_rec.basis;
811 l_all_amounts_rec.down_payment_value := t_rec.value;
812 ELSIF t_rec.type = G_SUBSIDY_TYPE
813 THEN
814 l_all_amounts_rec.subsidy_basis_tbl(sub_index) := t_rec.basis;
815 l_all_amounts_rec.subsidy_value_tbl(sub_index) := t_rec.value;
816 -- Increment the sub_index
817 sub_index := sub_index + 1;
818 ELSIF t_rec.type = G_TRADEIN_TYPE
819 THEN
820 l_all_amounts_rec.tradein_basis := t_rec.basis;
821 l_all_amounts_rec.tradein_value := t_rec.value;
822 END IF;
823 END LOOP;
824 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
825 ' Looped on fin_adj_csr successfully ! ' );
826 -- Basis for Down Payment/Subsidy/Trade can be
827 -- FIXED : Amount directly
828 -- ASSET_COST : Percentage of Asset Cost
829 IF l_all_amounts_rec.down_payment_basis = G_FIXED_BASIS
830 THEN
831 -- Store the downpayment value directly in the downpayment_amount
832 l_all_amounts_rec.down_payment_amount := l_all_amounts_rec.down_payment_value;
833 ELSE
834 -- Basis will be ASSET_COST, so apply the %age in the value on the total items cost
835 IF p_pricing_method <> 'SF'
836 THEN
837 l_all_amounts_rec.down_payment_amount :=
838 p_item_category_amount * l_all_amounts_rec.down_payment_value / 100;
839 ELSE
840 -- What to do in this case
841 NULL;
842 END IF;
843 END IF;
844 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
845 ' Down Payment Details: Basis=' || l_all_amounts_rec.down_payment_basis
846 || ' | Value=' || l_all_amounts_rec.down_payment_value
847 || ' Amount=' || l_all_amounts_rec.down_payment_amount );
848 IF l_all_amounts_rec.subsidy_basis_tbl IS NOT NULL AND
849 l_all_amounts_rec.subsidy_basis_tbl.COUNT > 0
850 THEN
851 FOR t IN l_all_amounts_rec.subsidy_basis_tbl.FIRST ..
852 l_all_amounts_rec.subsidy_basis_tbl.LAST
853 LOOP
854 IF l_all_amounts_rec.subsidy_basis_tbl(t) = G_FIXED_BASIS
855 THEN
856 -- Store the downpayment value directly in the downpayment_amount
857 l_all_amounts_rec.subsidy_amount := nvl(l_all_amounts_rec.subsidy_amount, 0 ) +
858 l_all_amounts_rec.subsidy_value_tbl(t);
859 ELSE
860 IF p_pricing_method <> 'SF'
861 THEN
862 l_all_amounts_rec.subsidy_amount := nvl(l_all_amounts_rec.subsidy_amount, 0 ) +
863 (p_item_category_amount * l_all_amounts_rec.subsidy_value_tbl(t) / 100 );
864 ELSE
865 -- What to do in this case
866 NULL;
867 END IF;
868 END IF; -- IF l_all_amounts_rec.subsidy_basis = G_FIXED_BASIS
869 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
870 ' Subsidy Details: Basis=' || l_all_amounts_rec.subsidy_basis_tbl(t)
871 || ' | Value=' || l_all_amounts_rec.subsidy_value_tbl(t)
872 || ' Amount=' || l_all_amounts_rec.subsidy_amount );
873 END LOOP; -- Loop on the Subsidy Table
874 END IF;
875
876 IF l_all_amounts_rec.tradein_basis = G_FIXED_BASIS
877 THEN
878 -- Store the downpayment value directly in the downpayment_amount
879 l_all_amounts_rec.tradein_amount := l_all_amounts_rec.tradein_value;
880 ELSE
881 IF p_pricing_method <> 'SF'
882 THEN
883 l_all_amounts_rec.tradein_amount :=
884 p_item_category_amount * l_all_amounts_rec.tradein_value / 100;
885 ELSE
886 -- What to do in this case
887 NULL;
888 END IF;
889 END IF; --IF l_all_amounts_rec.tradein_basis = G_FIXED_BASIS
890 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
891 ' Trade-in Details: Basis=' || l_all_amounts_rec.tradein_basis
892 || ' | Value=' || l_all_amounts_rec.tradein_value
893 || ' Amount=' || l_all_amounts_rec.tradein_amount );
894 -- Return the values ..
895 x_all_amounts_rec := l_all_amounts_rec;
896 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
897 l_api_name || ':End ' );
898 x_return_status := l_return_status;
899 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count, x_msg_data => x_msg_data);
900 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
901 'end debug OKLRPIUB.pls call get_qq_details');
902 EXCEPTION
903 WHEN OKL_API.G_EXCEPTION_ERROR THEN
904 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
905 p_api_name => l_api_name,
906 p_pkg_name => G_PKG_NAME,
907 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
908 x_msg_count => x_msg_count,
909 x_msg_data => x_msg_data,
910 p_api_type => g_api_type);
911 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
912 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
913 p_api_name => l_api_name,
914 p_pkg_name => G_PKG_NAME,
915 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
916 x_msg_count => x_msg_count,
917 x_msg_data => x_msg_data,
918 p_api_type => g_api_type);
919 WHEN OTHERS THEN
920 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
921 p_api_name => l_api_name,
922 p_pkg_name => G_PKG_NAME,
923 p_exc_name => 'OTHERS',
924 x_msg_count => x_msg_count,
925 x_msg_data => x_msg_data,
926 p_api_type => g_api_type);
927 END get_qq_fin_adj_details;
928
929 PROCEDURE get_qq_sgt_day_convention(
930 p_api_version IN NUMBER,
931 p_init_msg_list IN VARCHAR2,
932 x_return_status OUT NOCOPY VARCHAR2,
933 x_msg_count OUT NOCOPY NUMBER,
934 x_msg_data OUT NOCOPY VARCHAR2,
935 p_qq_id IN NUMBER,
936 x_days_in_month OUT NOCOPY VARCHAR2,
937 x_days_in_year OUT NOCOPY VARCHAR2)
938 AS
939 -- Local Variables
940 l_api_version CONSTANT NUMBER DEFAULT 1.0;
941 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_sgt_day_convention';
942 l_return_status VARCHAR2(1);
943 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
944 || G_PKG_NAME || '.' || UPPER(l_api_name);
945 l_debug_enabled VARCHAR2(10);
946 is_debug_procedure_on BOOLEAN;
947 is_debug_statement_on BOOLEAN;
948 -- Cursor declarations
949 CURSOR get_sgt_day_convention_csr( p_qq_id NUMBER )
950 IS
951 SELECT gts.days_in_month_code days_in_month,
952 gts.days_in_yr_code days_in_year,
953 gts.id gts_id,
954 pdt.id pdt_id
955 FROM okl_fe_eo_terms_all_b eot
956 ,okl_fe_eo_term_vers eov
957 ,okl_quick_quotes_b qqh
958 ,okl_products pdt
959 ,okl_ae_tmpt_sets aes
960 ,okl_st_gen_tmpt_sets gts
961 WHERE qqh.end_of_term_option_id = eov.end_of_term_ver_id
962 AND eov.end_of_term_id = eot.end_of_term_id
963 AND eot.product_id = pdt.id
964 AND pdt.aes_id = aes.id
965 AND aes.gts_id = gts.id
966 AND qqh.id = p_qq_id;
967 get_sgt_day_convention_rec get_sgt_day_convention_csr%ROWTYPE;
968
969 BEGIN
970 l_return_status := OKL_API.G_RET_STS_SUCCESS;
971 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
972 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
973 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
974 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
975 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
976 l_return_status := OKL_API.START_ACTIVITY(
977 p_api_name => l_api_name,
978 p_pkg_name => G_PKG_NAME,
979 p_init_msg_list => p_init_msg_list,
980 l_api_version => l_api_version,
981 p_api_version => p_api_version,
982 p_api_type => g_api_type,
983 x_return_status => x_return_status);
984 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
985 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
986 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
987 RAISE OKL_API.G_EXCEPTION_ERROR;
988 END IF;
989 -- Fetch the day convention from the SGT assosiated to the QQ ..
990 l_return_status := OKL_API.G_RET_STS_ERROR;
991 FOR t_rec IN get_sgt_day_convention_csr( p_qq_id => p_qq_id )
992 LOOP
993 get_sgt_day_convention_rec := t_rec;
994 l_return_status := OKL_API.G_RET_STS_SUCCESS;
995 END LOOP;
996 IF l_return_status = OKL_API.G_RET_STS_ERROR
997 THEN
998 -- Show the error message and then error out ..
999 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1000 'Unable to pick the day convention from the SGT ');
1001 OKL_API.SET_MESSAGE (
1002 p_app_name => G_APP_NAME,
1003 p_msg_name => 'OKL_LP_INVALID_SGT');
1004 RAISE OKL_API.G_EXCEPTION_ERROR;
1005 END IF;
1006 -- Return the Days per month n Year ..
1007 x_days_in_month := get_sgt_day_convention_rec.days_in_month;
1008 x_days_in_year := get_sgt_day_convention_rec.days_in_year;
1009 -- Return the status ..
1010 x_return_status := l_return_status;
1011 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
1012 x_msg_data => x_msg_data);
1013 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1014 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
1015 EXCEPTION
1016 WHEN OKL_API.G_EXCEPTION_ERROR THEN
1017 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1018 p_api_name => l_api_name,
1019 p_pkg_name => G_PKG_NAME,
1020 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
1021 x_msg_count => x_msg_count,
1022 x_msg_data => x_msg_data,
1023 p_api_type => g_api_type);
1024 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
1025 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1026 p_api_name => l_api_name,
1027 p_pkg_name => G_PKG_NAME,
1028 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
1029 x_msg_count => x_msg_count,
1030 x_msg_data => x_msg_data,
1031 p_api_type => g_api_type);
1032 WHEN OTHERS THEN
1033 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1034 p_api_name => l_api_name,
1035 p_pkg_name => G_PKG_NAME,
1036 p_exc_name => 'OTHERS',
1037 x_msg_count => x_msg_count,
1038 x_msg_data => x_msg_data,
1039 p_api_type => g_api_type);
1040 END get_qq_sgt_day_convention;
1041
1042 PROCEDURE get_lq_sgt_day_convention(
1043 p_api_version IN NUMBER,
1044 p_init_msg_list IN VARCHAR2,
1045 x_return_status OUT NOCOPY VARCHAR2,
1046 x_msg_count OUT NOCOPY NUMBER,
1047 x_msg_data OUT NOCOPY VARCHAR2,
1048 p_lq_id IN NUMBER,
1049 x_days_in_month OUT NOCOPY VARCHAR2,
1050 x_days_in_year OUT NOCOPY VARCHAR2)
1051 AS
1052 -- Local Variables
1053 l_api_version CONSTANT NUMBER DEFAULT 1.0;
1054 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lq_sgt_day_convention';
1055 l_return_status VARCHAR2(1);
1056 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
1057 || G_PKG_NAME || '.' || UPPER(l_api_name);
1058 l_debug_enabled VARCHAR2(10);
1059 is_debug_procedure_on BOOLEAN;
1060 is_debug_statement_on BOOLEAN;
1061 -- Cursor declarations
1062 CURSOR get_sgt_day_convention_csr( p_lq_id NUMBER )
1063 IS
1064 SELECT gts.days_in_month_code days_in_month,
1065 gts.days_in_yr_code days_in_year,
1066 gts.id gts_id,
1067 pdt.id pdt_id
1068 FROM okl_lease_quotes_b lqh
1069 ,okl_products pdt
1070 ,okl_ae_tmpt_sets aes
1071 ,okl_st_gen_tmpt_sets gts
1072 WHERE lqh.product_id = pdt.id
1073 AND pdt.aes_id = aes.id
1074 AND aes.gts_id = gts.id
1075 AND lqh.id = p_lq_id;
1076 get_sgt_day_convention_rec get_sgt_day_convention_csr%ROWTYPE;
1077
1078 BEGIN
1079 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1080 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
1081 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
1082 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1083 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
1084 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
1085 l_return_status := OKL_API.START_ACTIVITY(
1086 p_api_name => l_api_name,
1087 p_pkg_name => G_PKG_NAME,
1088 p_init_msg_list => p_init_msg_list,
1089 l_api_version => l_api_version,
1090 p_api_version => p_api_version,
1091 p_api_type => g_api_type,
1092 x_return_status => x_return_status);
1093 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1094 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1095 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
1096 RAISE OKL_API.G_EXCEPTION_ERROR;
1097 END IF;
1098 -- Fetch the day convention from the SGT assosiated to the QQ ..
1099 l_return_status := OKL_API.G_RET_STS_ERROR;
1100 FOR t_rec IN get_sgt_day_convention_csr( p_lq_id => p_lq_id )
1101 LOOP
1102 get_sgt_day_convention_rec := t_rec;
1103 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1104 END LOOP;
1105 IF l_return_status = OKL_API.G_RET_STS_ERROR
1106 THEN
1107 -- Show the error message and then error out ..
1108 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1109 'Unable to pick the day convention from the SGT ');
1110 OKL_API.SET_MESSAGE (
1111 p_app_name => G_APP_NAME,
1112 p_msg_name => 'OKL_LP_INVALID_SGT');
1113 RAISE OKL_API.G_EXCEPTION_ERROR;
1114 END IF;
1115 -- Return the Days per month n Year ..
1116 x_days_in_month := get_sgt_day_convention_rec.days_in_month;
1117 x_days_in_year := get_sgt_day_convention_rec.days_in_year;
1118 -- Return the status ..
1119 x_return_status := l_return_status;
1120 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
1121 x_msg_data => x_msg_data);
1122 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1123 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
1124 EXCEPTION
1125 WHEN OKL_API.G_EXCEPTION_ERROR THEN
1126 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1127 p_api_name => l_api_name,
1128 p_pkg_name => G_PKG_NAME,
1129 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
1130 x_msg_count => x_msg_count,
1131 x_msg_data => x_msg_data,
1132 p_api_type => g_api_type);
1133 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
1134 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1135 p_api_name => l_api_name,
1136 p_pkg_name => G_PKG_NAME,
1137 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
1138 x_msg_count => x_msg_count,
1139 x_msg_data => x_msg_data,
1140 p_api_type => g_api_type);
1141 WHEN OTHERS THEN
1142 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1143 p_api_name => l_api_name,
1144 p_pkg_name => G_PKG_NAME,
1145 p_exc_name => 'OTHERS',
1146 x_msg_count => x_msg_count,
1147 x_msg_data => x_msg_data,
1148 p_api_type => g_api_type);
1149 END get_lq_sgt_day_convention;
1150
1151 -- API to get the Cash flows and Cash Flow Levels for Quick Quote
1152 -- when the pricing option is STRUCTURED PRICING
1153 PROCEDURE get_qq_cash_flows(
1154 p_api_version IN NUMBER,
1155 p_init_msg_list IN VARCHAR2,
1156 x_return_status OUT NOCOPY VARCHAR2,
1157 x_msg_count OUT NOCOPY NUMBER,
1158 x_msg_data OUT NOCOPY VARCHAR2,
1159 p_cf_source_type IN VARCHAR2,
1160 p_qq_id IN NUMBER, -- Can be QQ/LQ/Asset ID/Fee ID Id ..
1161 x_days_in_month OUT NOCOPY VARCHAR2,
1162 x_days_in_year OUT NOCOPY VARCHAR2,
1163 x_cash_flow_rec OUT NOCOPY so_cash_flows_rec_type,
1164 x_cash_flow_det_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
1165 AS
1166 -- Cursor Declarations
1167 -- Cursor to fetch the Quick Quotes Cash Flow Details
1168 CURSOR qq_cash_flows_csr( p_qq_id NUMBER )
1169 IS
1170 SELECT cf.id caf_id
1171 ,dnz_khr_id khr_id
1172 ,dnz_qte_id qte_id
1173 ,cfo_id cfo_id
1174 ,sts_code sts_code
1175 ,sty_id sty_id
1176 ,cft_code cft_code
1177 ,due_arrears_yn due_arrears_yn
1178 ,start_date start_date
1179 ,number_of_advance_periods number_of_advance_periods
1180 ,oty_code oty_code
1181 FROM OKL_CASH_FLOWS cf,
1182 OKL_CASH_FLOW_OBJECTS cfo
1183 WHERE cf.cfo_id = cfo.id
1184 AND cfo.source_table = p_cf_source_type
1185 AND cfo.source_id = p_qq_id
1186 AND cf.sts_code = 'CURRENT';
1187 -- Cursor to fetch the Cash Flow Details
1188 CURSOR qq_cash_flow_levels_csr( p_caf_id NUMBER )
1189 IS
1190 SELECT id cfl_id
1191 ,caf_id
1192 ,fqy_code
1193 ,rate -- No rate is defined at Cash Flows Level.. Need to confirm
1194 ,stub_days
1195 ,stub_amount
1196 ,number_of_periods
1197 ,amount
1198 ,start_date
1199 FROM OKL_CASH_FLOW_LEVELS
1200 WHERE caf_id = p_caf_id
1201 ORDER BY start_date;
1202 -- Cursor Declarations for fetching the Lease Quote ID
1203 CURSOR get_ass_lq_id_csr( p_ast_id NUMBER )
1204 IS
1205 SELECT ast.parent_object_id lq_id
1206 FROM okl_assets_b ast
1207 WHERE ast.id = p_ast_id;
1208 CURSOR get_fee_lq_id_csr( p_fee_id NUMBER )
1209 IS
1210 SELECT fee.parent_object_id lq_id
1211 FROM okl_fees_b fee
1212 WHERE fee.id = p_fee_id;
1213
1214 -- Local Variables
1215 l_api_version CONSTANT NUMBER DEFAULT 1.0;
1216 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_cash_flows';
1217 l_return_status VARCHAR2(1);
1218 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
1219 || G_PKG_NAME || '.' || UPPER(l_api_name);
1220 l_debug_enabled VARCHAR2(10);
1221 is_debug_procedure_on BOOLEAN;
1222 is_debug_statement_on BOOLEAN;
1223 -- Declarations
1224 l_cash_flow_rec so_cash_flows_rec_type;
1225 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
1226 cfl_index NUMBER;
1227 l_qq_id NUMBER;
1228 BEGIN
1229 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1230 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
1231 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
1232 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1233 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
1234 -- check for logging on STATEMENT level
1235 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
1236 -- Call START_ACTIVITY to create savepoint, check compatibility
1237 -- and initialize message list
1238 l_return_status := OKL_API.START_ACTIVITY(
1239 p_api_name => l_api_name,
1240 p_pkg_name => G_PKG_NAME,
1241 p_init_msg_list => p_init_msg_list,
1242 l_api_version => l_api_version,
1243 p_api_version => p_api_version,
1244 p_api_type => g_api_type,
1245 x_return_status => x_return_status);
1246 --Check if activity started successfully
1247 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1248 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1249 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
1250 RAISE OKL_API.G_EXCEPTION_ERROR;
1251 END IF;
1252 -- Use l_return_status as a flag
1253 -- Fetching the Cash Flows Information
1254 l_return_status := OKL_API.G_RET_STS_ERROR;
1255 FOR t_rec in qq_cash_flows_csr( p_qq_id )
1256 LOOP
1257 l_cash_flow_rec.caf_id := t_rec.caf_id;
1258 l_cash_flow_rec.khr_id := t_rec.khr_id;
1259 l_cash_flow_rec.khr_id := t_rec.khr_id;
1260 l_cash_flow_rec.qte_id := t_rec.qte_id;
1261 l_cash_flow_rec.cfo_id := t_rec.cfo_id;
1262 l_cash_flow_rec.sts_code := t_rec.sts_code;
1263 l_cash_flow_rec.sty_id := t_rec.sty_id;
1264 l_cash_flow_rec.cft_code := t_rec.cft_code;
1265 l_cash_flow_rec.due_arrears_yn := t_rec.due_arrears_yn;
1266 l_cash_flow_rec.start_date := t_rec.start_date;
1267 l_cash_flow_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
1268 -- Use l_retun_status as a flag
1269 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1270 END LOOP;
1271 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
1272 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
1273 THEN
1274 cfl_index := 1;
1275 -- Cash Flows exists. So, fetch the Cash Flow Levels
1276 FOR t_rec in qq_cash_flow_levels_csr( l_cash_flow_rec.caf_id )
1277 LOOP
1278 l_cash_flow_det_tbl(cfl_index).cfl_id := t_rec.cfl_id;
1279 l_cash_flow_det_tbl(cfl_index).caf_id := t_rec.caf_id;
1280 l_cash_flow_det_tbl(cfl_index).fqy_code := t_rec.fqy_code;
1281 l_cash_flow_det_tbl(cfl_index).rate := t_rec.rate;
1282 l_cash_flow_det_tbl(cfl_index).stub_days := t_rec.stub_days;
1283 l_cash_flow_det_tbl(cfl_index).stub_amount := t_rec.stub_amount;
1284 l_cash_flow_det_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
1285 l_cash_flow_det_tbl(cfl_index).amount := t_rec.amount;
1286 l_cash_flow_det_tbl(cfl_index).start_date := t_rec.start_date;
1287 -- Remember the flag whether its a stub payment or not
1288 IF t_rec.stub_days IS NOT NULL --and t_rec.stub_amount IS NOT NULL
1289 THEN
1290 -- Stub Payment
1291 l_cash_flow_det_tbl(cfl_index).is_stub := 'Y';
1292 ELSE
1293 -- Regular Periodic Payment
1294 l_cash_flow_det_tbl(cfl_index).is_stub := 'N';
1295 END IF;
1296 -- Use l_retun_status as a flag
1297 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1298 -- Increment i
1299 cfl_index := cfl_index + 1;
1300 END LOOP;
1301 ELSE
1302 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1303 END IF;
1304 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1305 'p_cf_source_type =' || p_cf_source_type || 'p_qq_id = ' || p_qq_id);
1306 IF p_cf_source_type = G_CF_SOURCE_QQ-- Quick Quote
1307 THEN
1308 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1309 'Fetching Quick Quote Day convention from the SGT' );
1310 -- Fetch the day convention from the Stream Generation Template ...
1311 get_qq_sgt_day_convention(
1312 p_api_version => p_api_version,
1313 p_init_msg_list => p_init_msg_list,
1314 x_return_status => l_return_status,
1315 x_msg_count => x_msg_count,
1316 x_msg_data => x_msg_data,
1317 p_qq_id => p_qq_id,
1318 x_days_in_month => x_days_in_month,
1319 x_days_in_year => x_days_in_year);
1320 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1321 'After get_qq_sgt_day_convention ' || l_return_status );
1322 ELSIF p_cf_source_type = G_CF_SOURCE_LQ OR-- Lease Quote
1323 p_cf_source_type = G_CF_SOURCE_LQ_ASS OR
1324 p_cf_source_type = G_CF_SOURCE_LQ_FEE
1325 THEN
1326 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1327 'Fetching Lease Quote Day convention from the SGT' );
1328 l_qq_id := p_qq_id;
1329 IF p_cf_source_type = G_CF_SOURCE_LQ_ASS
1330 THEN
1331 FOR t_rec IN get_ass_lq_id_csr( p_ast_id => l_qq_id )
1332 LOOP
1333 l_qq_id := t_rec.lq_id;
1334 END LOOP;
1335 ELSIF p_cf_source_type = G_CF_SOURCE_LQ_FEE
1336 THEN
1337 FOR t_rec IN get_fee_lq_id_csr( p_fee_id => l_qq_id )
1338 LOOP
1339 l_qq_id := t_rec.lq_id;
1340 END LOOP;
1341 END IF;
1342 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1343 'Fetched Lease Qutoe ID ' || l_qq_id );
1344 get_lq_sgt_day_convention(
1345 p_api_version => p_api_version,
1346 p_init_msg_list => p_init_msg_list,
1347 x_return_status => l_return_status,
1348 x_msg_count => x_msg_count,
1349 x_msg_data => x_msg_data,
1350 p_lq_id => l_qq_id,
1351 x_days_in_month => x_days_in_month,
1352 x_days_in_year => x_days_in_year);
1353 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1354 'After get_lq_sgt_day_convention ' || l_return_status );
1355 END IF;
1356 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1357 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1358 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
1359 RAISE OKL_API.G_EXCEPTION_ERROR;
1360 END IF;
1361 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1362 x_days_in_month || ' / ' || x_days_in_year);
1363 -- Setting the return variables ..
1364 x_cash_flow_rec := l_cash_flow_rec;
1365 x_cash_flow_det_tbl := l_cash_flow_det_tbl;
1366 x_return_status := l_return_status;
1367 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
1368 x_msg_data => x_msg_data);
1369 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1370 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
1371 EXCEPTION
1372 WHEN OKL_API.G_EXCEPTION_ERROR THEN
1373 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1374 p_api_name => l_api_name,
1375 p_pkg_name => G_PKG_NAME,
1376 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
1377 x_msg_count => x_msg_count,
1378 x_msg_data => x_msg_data,
1379 p_api_type => g_api_type);
1380 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
1381 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1382 p_api_name => l_api_name,
1383 p_pkg_name => G_PKG_NAME,
1384 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
1385 x_msg_count => x_msg_count,
1386 x_msg_data => x_msg_data,
1387 p_api_type => g_api_type);
1388 WHEN OTHERS THEN
1389 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1390 p_api_name => l_api_name,
1391 p_pkg_name => G_PKG_NAME,
1392 p_exc_name => 'OTHERS',
1393 x_msg_count => x_msg_count,
1394 x_msg_data => x_msg_data,
1395 p_api_type => g_api_type);
1396 END get_qq_cash_flows;
1397
1398 -- API to get the Cash flows and Cash Flow Levels for Fees and Services
1399 PROCEDURE get_fee_srvc_cash_flows(
1400 p_api_version IN NUMBER,
1401 p_init_msg_list IN VARCHAR2,
1402 x_return_status OUT NOCOPY VARCHAR2,
1403 x_msg_count OUT NOCOPY NUMBER,
1404 x_msg_data OUT NOCOPY VARCHAR2,
1405 p_hdr_rec IN so_hdr_rec_type,
1406 p_tot_item_cat_cost IN NUMBER,
1407 p_tot_rent_payment IN NUMBER,
1408 x_fee_srv_tbl OUT NOCOPY so_fee_srv_tbl_type)
1409 AS
1410 -- Cursor Declarations
1411 -- Cursor to fetch the Fees and Services Details !!
1412 -- like Expenses, Fee Payments, Services, Tax and Insurance !
1413 CURSOR fee_n_service_csr( p_qq_id NUMBER )
1414 IS
1415 SELECT qql.id qq_line_id
1416 ,qql.type type
1417 ,qql.basis basis
1418 ,qql.value value
1419 FROM OKL_QUICK_QUOTE_LINES_B qql
1420 WHERE qql.quick_quote_id = p_qq_id
1421 AND TYPE IN (G_QQ_FEE_EXPENSE,
1422 G_QQ_FEE_PAYMENT)
1423 ORDER BY TYPE;
1424 -- Cursor to fetch the Quick Quotes Cash Flow Details
1425 CURSOR qq_cash_flows_csr( p_qq_line_id NUMBER)
1426 IS
1427 SELECT cf.id caf_id
1428 ,dnz_khr_id khr_id
1429 ,dnz_qte_id qte_id
1430 ,cfo_id cfo_id
1431 ,sts_code sts_code
1432 ,sty_id sty_id
1433 ,cft_code cft_code
1434 ,due_arrears_yn due_arrears_yn
1435 ,start_date start_date
1436 ,number_of_advance_periods number_of_advance_periods
1437 ,oty_code oty_code
1438 FROM OKL_CASH_FLOWS cf,
1439 OKL_CASH_FLOW_OBJECTS cfo
1440 WHERE cf.cfo_id = cfo.id
1441 AND cfo.source_table = 'OKL_QUICK_QUOTE_LINES_B'
1442 AND cfo.source_id = p_qq_line_id;
1443 -- Cursor to fetch the Cash Flow Details
1444 CURSOR qq_cash_flow_levels_csr( p_caf_id NUMBER )
1445 IS
1446 SELECT id cfl_id
1447 ,caf_id
1448 ,fqy_code
1449 ,rate
1450 ,stub_days
1451 ,stub_amount
1452 ,number_of_periods
1453 ,amount
1454 ,start_date
1455 FROM OKL_CASH_FLOW_LEVELS
1456 WHERE caf_id = p_caf_id
1457 ORDER BY start_date;
1458 -- Local Variables
1459 l_api_version CONSTANT NUMBER DEFAULT 1.0;
1460 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_fee_srvc_cash_flows';
1461 l_return_status VARCHAR2(1);
1462 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
1463 || G_PKG_NAME || '.' || UPPER(l_api_name);
1464 l_debug_enabled VARCHAR2(10);
1465 is_debug_procedure_on BOOLEAN;
1466 is_debug_statement_on BOOLEAN;
1467 -- Declarations
1468 l_fee_srv_tbl so_fee_srv_tbl_type;
1469 l_cash_flow_rec so_cash_flows_rec_type;
1470 l_cash_flow_level_tbl so_cash_flow_details_tbl_type;
1471 fin_index NUMBER; -- Index for the l_fee_srv_tbl
1472 cfl_index NUMBER; -- Index for the l_fee_srv_tbl.cash_flow_level_tbl
1473 l_hdr_rec so_hdr_rec_type;
1474 l_fee_srv_tot_payment NUMBER;
1475 l_tot_item_cat_cost NUMBER;
1476 l_tot_rent_payment NUMBER;
1477 l_override_cf_amt BOOLEAN;
1478 l_tot_periods NUMBER;
1479 l_periodic_amt NUMBER;
1480 BEGIN
1481 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1482 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
1483 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
1484 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1485 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
1486 -- check for logging on STATEMENT level
1487 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
1488 -- Call START_ACTIVITY to create savepoint, check compatibility
1489 -- and initialize message list
1490 l_return_status := OKL_API.START_ACTIVITY(
1491 p_api_name => l_api_name,
1492 p_pkg_name => G_PKG_NAME,
1493 p_init_msg_list => p_init_msg_list,
1494 l_api_version => l_api_version,
1495 p_api_version => p_api_version,
1496 p_api_type => g_api_type,
1497 x_return_status => x_return_status);
1498 --Check if activity started successfully
1499 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1500 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1501 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
1502 RAISE OKL_API.G_EXCEPTION_ERROR;
1503 END IF;
1504 l_hdr_rec := p_hdr_rec;
1505 fin_index := 1; -- Initialize the fin_index .. !
1506 l_tot_item_cat_cost := p_tot_item_cat_cost;
1507 l_tot_rent_payment := p_tot_rent_payment;
1508 l_tot_periods := 0;
1509 FOR fin_rec IN fee_n_service_csr( p_qq_id => l_hdr_rec.id )
1510 LOOP
1511 -- Store the type, value, basis into l_fin_adj_table
1512 l_fee_srv_tbl(fin_index).type := fin_rec.type;
1513 l_fee_srv_tbl(fin_index).basis := fin_rec.basis;
1514 l_fee_srv_tbl(fin_index).value := fin_rec.value;
1515 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1516 ': Line ID | Line Type | Line Basis | Line Value ');
1517 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1518 fin_rec.qq_line_id || ' | ' || fin_rec.type || ' | ' ||
1519 fin_rec.basis || ' | ' || fin_rec.value);
1520 FOR cf_rec IN qq_cash_flows_csr( p_qq_line_id => fin_rec.qq_line_id )
1521 LOOP
1522 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1523 ': Fetched the Cash Flow Rec for Line ID ' ||fin_rec.qq_line_id );
1524 l_cash_flow_rec.caf_id := cf_rec.caf_id;
1525 l_cash_flow_rec.khr_id := cf_rec.khr_id;
1526 l_cash_flow_rec.khr_id := cf_rec.khr_id;
1527 l_cash_flow_rec.qte_id := cf_rec.qte_id;
1528 l_cash_flow_rec.cfo_id := cf_rec.cfo_id;
1529 l_cash_flow_rec.sts_code := cf_rec.sts_code;
1530 l_cash_flow_rec.sty_id := cf_rec.sty_id;
1531 l_cash_flow_rec.cft_code := cf_rec.cft_code;
1532 l_cash_flow_rec.due_arrears_yn := cf_rec.due_arrears_yn;
1533 l_cash_flow_rec.start_date := cf_rec.start_date;
1534 l_cash_flow_rec.number_of_advance_periods := cf_rec.number_of_advance_periods;
1535 -- Store the cash flow record @ index fin_index in table l_fee_srv_tbl
1536 l_fee_srv_tbl(fin_index).cash_flow_rec := l_cash_flow_rec;
1537 -- Retrieve the Cash flow levels ..
1538 cfl_index := 1; -- Initialize the cfl_index
1539 l_cash_flow_level_tbl.DELETE;
1540 -- Here we need to decide based on the basis type
1541 -- whether we can st. away use the amount mentioned in the DB Cash flow levels
1542 -- or ISG has to calculate the periodic payment amount !
1543 l_override_cf_amt := FALSE;
1544 l_fee_srv_tot_payment := NULL;
1545 IF ( l_fee_srv_tbl(fin_index).basis = 'RENT' ) AND
1546 ( ( l_hdr_rec.pricing_method = 'TR' AND l_hdr_rec.target_rate_type = 'IIR' )
1547 OR l_hdr_rec.pricing_method = 'SP'
1548 OR l_hdr_rec.pricing_method = 'RC' )
1549 THEN
1550 -- When the fee/srv. basis is %age of asset cost and
1551 -- pricing method is SP/TR/RC then we need to build the cash flow levels
1552 -- instead of using the existing cash flows in the DB.
1553 l_fee_srv_tot_payment := l_fee_srv_tbl(fin_index).value * 0.01 * l_tot_rent_payment;
1554 l_override_cf_amt := TRUE;
1555 ELSIF l_fee_srv_tbl(fin_index).basis = 'ASSET_COST' AND
1556 l_hdr_rec.pricing_method = 'SF'
1557 THEN
1558 -- When pricing method is SF, ISG wuld have solved for financed
1559 -- amount, so use this amount on which the %age will be applied.
1560 l_fee_srv_tot_payment := l_fee_srv_tbl(fin_index).value * 0.01 * l_tot_item_cat_cost ;
1561 l_override_cf_amt := TRUE;
1562 END IF;
1563 IF l_override_cf_amt
1564 THEN
1565 l_tot_periods := 0;
1566 FOR cfl_rec IN qq_cash_flow_levels_csr( p_caf_id => l_cash_flow_rec.caf_id )
1567 LOOP
1568 l_tot_periods := l_tot_periods + nvl( cfl_rec.number_of_periods, 0 );
1569 END LOOP;
1570 l_periodic_amt := l_fee_srv_tot_payment/l_tot_periods;
1571 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1572 ':******* Overriding the cash flow level amount ' || fin_rec.qq_line_id );
1573 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1574 'l_tot_item_cat_cost | l_tot_rent_payment | l_fee_srv_tot_payment | Periodic Amount' );
1575 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1576 round(l_tot_item_cat_cost, 4) || ' | ' ||
1577 round(l_tot_rent_payment, 4) || ' | ' ||
1578 round(l_fee_srv_tot_payment, 4) || ' | ' ||
1579 round(l_periodic_amt, 4));
1580 END IF;
1581
1582 FOR cfl_rec IN qq_cash_flow_levels_csr( p_caf_id => l_cash_flow_rec.caf_id )
1583 LOOP
1584 l_cash_flow_level_tbl(cfl_index).cfl_id := cfl_rec.cfl_id;
1585 l_cash_flow_level_tbl(cfl_index).caf_id := cfl_rec.caf_id;
1586 l_cash_flow_level_tbl(cfl_index).fqy_code := cfl_rec.fqy_code;
1587 l_cash_flow_level_tbl(cfl_index).locked_amt := 'Y'; -- For QQ Fee Expense/Payments always lock the amt.
1588 IF l_hdr_rec.pricing_method = 'TR' AND l_hdr_rec.target_rate_type = 'PIRR'
1589 THEN
1590 l_cash_flow_level_tbl(cfl_index).rate := l_hdr_rec.target_rate; -- Rate is being stored as %age
1591 ELSE
1592 l_cash_flow_level_tbl(cfl_index).rate := cfl_rec.rate;
1593 END IF;
1594 l_cash_flow_level_tbl(cfl_index).stub_days := cfl_rec.stub_days;
1595 l_cash_flow_level_tbl(cfl_index).stub_amount := cfl_rec.stub_amount;
1596 l_cash_flow_level_tbl(cfl_index).number_of_periods := cfl_rec.number_of_periods;
1597 IF l_override_cf_amt
1598 THEN
1599 -- Calculate the periodic amount, dividing by the number of periods
1600 l_cash_flow_level_tbl(cfl_index).amount := l_periodic_amt;
1601 ELSE
1602 l_cash_flow_level_tbl(cfl_index).amount := cfl_rec.amount;
1603 END IF;
1604 l_cash_flow_level_tbl(cfl_index).start_date := cfl_rec.start_date;
1605 -- Remember the flag whether its a stub payment or not
1606 IF cfl_rec.stub_days IS NOT NULL and cfl_rec.stub_amount IS NOT NULL
1607 THEN
1608 -- Stub Payment
1609 l_cash_flow_level_tbl(cfl_index).is_stub := 'Y';
1610 ELSE
1611 -- Regular Periodic Payment
1612 l_cash_flow_level_tbl(cfl_index).is_stub := 'N';
1613 END IF;
1614 END LOOP;
1615 -- Store the Cash flow levels table in the l_fee_srv_tbl(fin_index)
1616 l_fee_srv_tbl(fin_index).cash_flow_level_tbl := l_cash_flow_level_tbl;
1617 END LOOP;
1618 -- Increment fin_index
1619 fin_index := fin_index + 1;
1620 END LOOP;
1621 -- Setting the return variables ..
1622 x_fee_srv_tbl := l_fee_srv_tbl;
1623 x_return_status := l_return_status;
1624 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
1625 x_msg_data => x_msg_data);
1626 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1627 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
1628 EXCEPTION
1629 WHEN OKL_API.G_EXCEPTION_ERROR THEN
1630 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1631 p_api_name => l_api_name,
1632 p_pkg_name => G_PKG_NAME,
1633 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
1634 x_msg_count => x_msg_count,
1635 x_msg_data => x_msg_data,
1636 p_api_type => g_api_type);
1637 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
1638 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1639 p_api_name => l_api_name,
1640 p_pkg_name => G_PKG_NAME,
1641 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
1642 x_msg_count => x_msg_count,
1643 x_msg_data => x_msg_data,
1644 p_api_type => g_api_type);
1645 WHEN OTHERS THEN
1646 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
1647 p_api_name => l_api_name,
1648 p_pkg_name => G_PKG_NAME,
1649 p_exc_name => 'OTHERS',
1650 x_msg_count => x_msg_count,
1651 x_msg_data => x_msg_data,
1652 p_api_type => g_api_type);
1653 END get_fee_srvc_cash_flows;
1654
1655
1656 -- API to return the number of days per annum
1657 -- based on the start date of the business object being passed !
1658 -- Possible return values are 360/ 365 / 366
1659 FUNCTION get_days_per_annum(
1660 p_day_convention IN VARCHAR2,
1661 p_start_date IN DATE,
1662 p_cash_inflow_date IN DATE,
1663 x_return_status OUT NOCOPY VARCHAR2 )
1664 RETURN NUMBER
1665 AS
1666 l_start_year NUMBER;
1667 l_cf_year NUMBER;
1668 BEGIN
1669 x_return_status := OKL_API.G_RET_STS_SUCCESS;
1670 IF p_day_convention = 'ACTUAL'
1671 THEN
1672 l_start_year := TO_NUMBER( TO_CHAR( p_start_date, 'YYYY') );
1673 l_cf_year := TO_NUMBER( TO_CHAR( p_cash_inflow_date, 'YYYY') );
1674
1675 IF is_leap_year(l_cf_year)
1676 THEN
1677 -- Cash inflow is occuring in a leap year.
1678 IF to_date( '29-2-' || l_cf_year , 'DD-MM-YYYY') >= p_start_date
1679 THEN
1680 RETURN 366;
1681 ELSE
1682 RETURN 365;
1683 END IF;
1684 END IF;
1685 -- Since cash inflow is occuring in non-leap year, so .. return 365 days..
1686 RETURN 365;
1687 ELSIF p_day_convention = 'ACT365'
1688 THEN
1689 -- Number of days per annum doesnot depend on the year
1690 -- all years are assumed to be having 365 days
1691 RETURN 365;
1692 ELSE
1693 -- p_day_convention = 'THIRTY'
1694 -- Number of days per annum doesnot depend on the year ...
1695 -- all years are assumed to be having 360 days
1696 RETURN 360;
1697 END IF;
1698 x_return_status := OKL_API.G_RET_STS_SUCCESS;
1699 END get_days_per_annum;
1700
1701 -- Procedure to create stream elements for each cash flows level passed !
1702 -- Expecting the p_cfd_rec to have atleast the following
1703 -- fqy_code - Frequency
1704 -- rate - Rate
1705 -- stub_days - Stub days
1706 -- stub_amount - Stub Amount
1707 -- number_of_periods - Periods
1708 -- Amount - Regular Periodic amount
1709 -- is_stub - Is a Stub or not ..
1710 -- Added parameter p_recurrence_date by Durga Janaswamy for bug 6007644
1711 PROCEDURE gen_so_cf_strm_elements(
1712 p_start_date IN DATE,
1713 p_frequency IN VARCHAR2,
1714 p_advance_arrears IN VARCHAR2,
1715 p_periods IN NUMBER,
1716 p_amount IN NUMBER,
1717 p_stub_days IN NUMBER,
1718 p_stub_amount IN NUMBER,
1719 p_stub_flag IN VARCHAR2,
1720 x_cf_strm_elements_tbl OUT NOCOPY cash_inflows_tbl_type,
1721 x_return_status OUT NOCOPY VARCHAR2,
1722 p_recurrence_date IN DATE)
1723 IS
1724 l_months_factor NUMBER;
1725 l_first_ele_date DATE;
1726 l_cash_inflows_tbl cash_inflows_tbl_type;
1727 n_periods NUMBER; -- Index for the Cash Inflow elements Table
1728 -- Local Variables
1729 l_api_version CONSTANT NUMBER DEFAULT 1.0;
1730 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'gen_so_cf_strm_elements';
1731 l_return_status VARCHAR2(1);
1732 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.OKL_PRICING_UTILS_PVT.gen_so_cf_strm_elements';
1733 l_debug_enabled VARCHAR2(10);
1734 is_debug_procedure_on BOOLEAN;
1735 is_debug_statement_on BOOLEAN;
1736 l_period_start_date DATE;
1737 l_period_end_date DATE;
1738 BEGIN
1739 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1740 l_debug_enabled := okl_debug_pub.check_log_enabled;
1741 is_debug_procedure_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
1742 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1743 'begin debug OKLRPIUB.pls call gen_so_cf_strm_elements');
1744 -- check for logging on STATEMENT level
1745 is_debug_statement_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
1746 -- If its a stub payment only one cash_inflows will be returned
1747 IF p_stub_flag = 'Y'
1748 OR ( p_periods IS NULL AND p_stub_days IS NOT NULL )
1749 THEN
1750 -- This is a Stub Payment
1751 l_cash_inflows_tbl(1).is_stub := 'Y';
1752 l_cash_inflows_tbl(1).cf_amount := p_stub_amount;
1753 -- Bug 6660626 : Start
1754 l_cash_inflows_tbl(1).cf_days := p_stub_days;
1755 -- Bug 6660626 : End
1756 IF p_advance_arrears = 'ARREARS' OR p_advance_arrears = 'Y'
1757 THEN
1758 l_cash_inflows_tbl(1).is_arrears := 'Y';
1759 l_cash_inflows_tbl(1).cf_date := p_start_date + p_stub_days - 1;
1760 l_cash_inflows_tbl(1).cf_period_start_end_date
1761 := p_start_date;
1762 ELSE
1763 l_cash_inflows_tbl(1).is_arrears := 'N';
1764 l_cash_inflows_tbl(1).cf_date := p_start_date;
1765 l_cash_inflows_tbl(1).cf_period_start_end_date
1766 := p_start_date + p_stub_days - 1;
1767 END IF;
1768 ELSE
1769 -- This is a regular periodic Payment
1770 n_periods := p_periods;
1771 -- Get the month Factor
1772 -- okl_stream_generator_pvt.get_months_factor handle if frequence is passed one among M/Q/S/A
1773 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1774 'p_frequency_passed'||p_frequency);
1775
1776 If ( nvl(p_frequency, 'X') = 'X') Then
1777
1778 OKL_API.set_message(
1779 p_app_name => G_APP_NAME,
1780 p_msg_name => OKL_API.G_REQUIRED_VALUE,
1781 p_token1 => OKL_API.G_COL_NAME_TOKEN,
1782 p_token1_value => 'FREQUENCY');
1783
1784 RAISE OKL_API.G_EXCEPTION_ERROR;
1785
1786 End If;
1787
1788 l_months_factor := okl_stream_generator_pvt.get_months_factor(
1789 p_frequency => p_frequency,
1790 x_return_status => l_return_status);
1791 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1792 'p_months_factor'||l_months_factor);
1793
1794 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1795 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1796 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
1797 RAISE OKL_API.G_EXCEPTION_ERROR;
1798 END IF;
1799 -- Looping throug the Periods ..
1800 FOR i in 1 .. n_periods
1801 LOOP
1802 l_cash_inflows_tbl(i).is_stub := 'N';
1803 l_cash_inflows_tbl(i).cf_amount := p_amount;
1804 -- Bug 6660626 : Start
1805 l_cash_inflows_tbl(i).cf_days := null;
1806 -- Bug 6660626 : End
1807 -- Get the Stream Element date after i months from the p_start_date
1808 -- when the payments are ADVANCE
1809 -- Added parameter p_recurrence_date by Durga Janaswamy for bug 6007644
1810 okl_stream_generator_pvt.get_sel_date(
1811 p_start_date => p_start_date,
1812 p_advance_or_arrears => 'N',
1813 p_periods_after => i,
1814 p_months_per_period => l_months_factor,
1815 x_date => l_period_start_date,
1816 x_return_status => l_return_status,
1817 p_recurrence_date => p_recurrence_date);
1818 IF l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
1819 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1820 ELSIF l_return_status = OKL_API.G_RET_STS_ERROR THEN
1821 RAISE OKL_API.G_EXCEPTION_ERROR;
1822 END IF;
1823 -- Get the Stream Element date after i months from the p_start_date
1824 -- when the payments are ARREARS
1825 -- Added parameter p_recurrence_date by Durga Janaswamy for bug 6007644
1826 okl_stream_generator_pvt.get_sel_date(
1827 p_start_date => p_start_date,
1828 p_advance_or_arrears => 'Y',
1829 p_periods_after => i,
1830 p_months_per_period => l_months_factor,
1831 x_date => l_period_end_date,
1832 x_return_status => l_return_status,
1833 p_recurrence_date => p_recurrence_date);
1834 IF l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
1835 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1836 ELSIF l_return_status = OKL_API.G_RET_STS_ERROR THEN
1837 RAISE OKL_API.G_EXCEPTION_ERROR;
1838 END IF;
1839 -- Based on the payment type is 'ADVANCE' / 'ARREARS' do the assignment ..
1840 IF p_advance_arrears = 'ARREARS' OR p_advance_arrears = 'Y'
1841 THEN
1842 -- Streams for Arrear Payments
1843 l_cash_inflows_tbl(i).is_arrears := 'Y';
1844 l_cash_inflows_tbl(i).cf_date := l_period_end_date;
1845 l_cash_inflows_tbl(i).cf_period_start_end_date := l_period_start_date;
1846 ELSE
1847 -- Streams for advance payments
1848 l_cash_inflows_tbl(i).is_arrears := 'N';
1849 l_cash_inflows_tbl(i).cf_date := l_period_start_date;
1850 l_cash_inflows_tbl(i).cf_period_start_end_date := l_period_end_date;
1851 END IF;
1852 END LOOP;
1853 END IF;
1854 x_cf_strm_elements_tbl := l_cash_inflows_tbl;
1855 x_return_status := l_return_status;
1856 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1857 'end debug OKLRPIUB.pls call gen_cf_strm_elements');
1858 EXCEPTION
1859 WHEN OKL_API.G_EXCEPTION_ERROR THEN
1860 x_return_status := G_RET_STS_ERROR;
1861 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
1862 x_return_status := G_RET_STS_UNEXP_ERROR;
1863 WHEN OTHERS THEN
1864 OKL_API.SET_MESSAGE (
1865 p_app_name => G_APP_NAME,
1866 p_msg_name => G_DB_ERROR,
1867 p_token1 => G_PROG_NAME_TOKEN,
1868 p_token1_value => l_api_name,
1869 p_token2 => G_SQLCODE_TOKEN,
1870 p_token2_value => sqlcode,
1871 p_token3 => G_SQLERRM_TOKEN,
1872 p_token3_value => sqlerrm);
1873 x_return_status := G_RET_STS_UNEXP_ERROR;
1874 END gen_so_cf_strm_elements;
1875
1876 -- Procedure to generate the Streams
1877 -- based on the Cash Flow n Cash Flow Levels Infomration inputted.
1878 PROCEDURE gen_so_cf_strms(
1879 p_api_version IN NUMBER,
1880 p_init_msg_list IN VARCHAR2,
1881 x_return_status OUT NOCOPY VARCHAR2,
1882 x_msg_count OUT NOCOPY NUMBER,
1883 x_msg_data OUT NOCOPY VARCHAR2,
1884 p_cash_flow_rec IN so_cash_flows_rec_type,
1885 p_cf_details_tbl IN so_cash_flow_details_tbl_type,
1886 x_cash_inflow_strms_tbl OUT NOCOPY cash_inflows_tbl_type)
1887 IS
1888 -- Local Variables
1889 l_cf_strms_tbl cash_inflows_tbl_type;
1890 l_temp_cf_strms_tbl cash_inflows_tbl_type;
1891 l_api_version CONSTANT NUMBER DEFAULT 1.0;
1892 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'gen_so_cf_strms';
1893 l_return_status VARCHAR2(1);
1894 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.OKL_PRICING_UTILS_PVT.GEN_SO_CF_STRMS';
1895 l_debug_enabled VARCHAR2(10);
1896 is_debug_procedure_on BOOLEAN;
1897 is_debug_statement_on BOOLEAN;
1898 -- Local Variables
1899 i NUMBER;
1900 l_cf_count NUMBER;
1901 l_dpp NUMBER; -- Stores Days Per period for each Cash Inflow level
1902 l_ppy NUMBER; -- Stores Periods Per Year for each Cash Inflow Level
1903
1904 --Added by DJanaswa for bug 6007644
1905 l_recurrence_date DATE := NULL;
1906 --end DJANASWA
1907
1908 BEGIN
1909 l_return_status := OKL_API.G_RET_STS_SUCCESS;
1910 l_debug_enabled := okl_debug_pub.check_log_enabled;
1911 is_debug_procedure_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
1912 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
1913 'begin debug OKLRPIUB.pls call gen_so_cf_strms');
1914 -- check for logging on STATEMENT level
1915 is_debug_statement_on := okl_debug_pub.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
1916 -- Call START_ACTIVITY to create savepoint, check compatibility
1917 -- and initialize message list
1918 l_return_status := OKL_API.START_ACTIVITY(
1919 p_api_name => l_api_name,
1920 p_pkg_name => G_PKG_NAME,
1921 p_init_msg_list => p_init_msg_list,
1922 l_api_version => l_api_version,
1923 p_api_version => p_api_version,
1924 p_api_type => g_api_type,
1925 x_return_status => x_return_status);
1926 --Check if activity started successfully
1927 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1928 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1929 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
1930 RAISE OKL_API.G_EXCEPTION_ERROR;
1931 END IF;
1932 -- Actual logic Begins here
1933 -- Create the cash inflow streams table ..
1934 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1935 'Payment Levels =' || p_cf_details_tbl.COUNT );
1936 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1937 'Rate | Start Date| Frequency| Arrears | Periods | Amount | Stub Days | Stub Amount | Is Stub | Locked' );
1938 FOR i IN p_cf_details_tbl.FIRST..p_cf_details_tbl.LAST
1939 LOOP
1940 -- Validate whether the start_date is there or not
1941 IF p_cf_details_tbl(i).start_date IS NULL
1942 THEN
1943 -- Raise an Exception, cant proceed.
1944 OKL_API.SET_MESSAGE (
1945 p_app_name => G_APP_NAME,
1946 p_msg_name => 'OKL_NO_SLL_SDATE');
1947 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1948 END IF;
1949 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1950 p_cf_details_tbl(i).rate
1951 || ' | ' || p_cf_details_tbl(i).start_date
1952 || ' | ' || p_cf_details_tbl(i).fqy_code
1953 || ' | ' || p_cash_flow_rec.due_arrears_yn
1954 || ' | ' || p_cf_details_tbl(i).number_of_periods
1955 || ' | ' || p_cf_details_tbl(i).amount
1956 || ' | ' || p_cf_details_tbl(i).stub_days
1957 || ' | ' || p_cf_details_tbl(i).stub_amount
1958 || ' | ' || p_cf_details_tbl(i).is_stub
1959 || ' | ' || p_cf_details_tbl(i).locked_amt );
1960
1961 --Added by djanaswa for bug 6007644
1962 IF((p_cf_details_tbl(i).number_of_periods IS NULL) AND (p_cf_details_tbl(i).stub_days IS NOT NULL)) THEN
1963 --Set the recurrence date to null for stub payment
1964 l_recurrence_date := NULL;
1965 ELSIF(l_recurrence_date IS NULL) THEN
1966 --Set the recurrence date as periodic payment level start date
1967 l_recurrence_date := p_cf_details_tbl(i).start_date;
1968 END IF;
1969 --end djanaswa
1970
1971 -- Create the cash inflow streams
1972 -- Added parameter p_recurrence_date by djanaswa for bug6007644
1973 gen_so_cf_strm_elements(
1974 p_start_date => p_cf_details_tbl(i).start_date,
1975 p_frequency => p_cf_details_tbl(i).fqy_code,
1976 p_advance_arrears => p_cash_flow_rec.due_arrears_yn,
1977 p_periods => p_cf_details_tbl(i).number_of_periods,
1978 p_amount => p_cf_details_tbl(i).amount,
1979 p_stub_days => p_cf_details_tbl(i).stub_days,
1980 p_stub_amount => p_cf_details_tbl(i).stub_amount,
1981 p_stub_flag => p_cf_details_tbl(i).is_stub,
1982 x_cf_strm_elements_tbl => l_temp_cf_strms_tbl,
1983 x_return_status => l_return_status,
1984 p_recurrence_date => l_recurrence_date);
1985 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1986 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1987 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
1988 RAISE OKL_API.G_EXCEPTION_ERROR;
1989 END IF;
1990 -- Accumulate the Cash Inflow Streams created
1991 l_cf_count := nvl(l_cf_strms_tbl.COUNT, 0 );
1992 get_dpp_ppy(
1993 p_frequency => p_cf_details_tbl(i).fqy_code,
1994 x_dpp => l_dpp,
1995 x_ppy => l_ppy,
1996 x_return_status => l_return_status);
1997 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
1998 'l_dpp | l_ppy | l_cf_count | l_return_status ' );
1999 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2000 l_dpp || '|' || l_ppy || '|' || l_cf_count || '|' || l_return_status );
2001 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2002 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2003 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2004 RAISE OKL_API.G_EXCEPTION_ERROR;
2005 END IF;
2006 -- Append the l_temp_cf_strms_tbl to l_temp_cf_strms_tbl
2007 FOR j in l_temp_cf_strms_tbl.FIRST .. l_temp_cf_strms_tbl.LAST
2008 LOOP
2009 -- Make updations here for the stream elements generated here..
2010 l_temp_cf_strms_tbl(j).line_number := l_cf_count + j;
2011 -- Days per period
2012 l_temp_cf_strms_tbl(j).cf_dpp := l_dpp;
2013 -- Periods per Year
2014 l_temp_cf_strms_tbl(j).cf_ppy := l_ppy;
2015 -- We are not calculating the cf_days here .....
2016 -- cf_days will be calculated as and when needed based on the start_date
2017 -- Also, think about the logic to populate the payment amount
2018 -- Store the rate from the cash flow
2019 -- Rate in levels will be stored in terms of percentage !!
2020 l_temp_cf_strms_tbl(j).cf_rate := p_cf_details_tbl(i).rate / 100;
2021 IF l_temp_cf_strms_tbl(j).cf_amount IS NULL THEN
2022 l_temp_cf_strms_tbl(j).cf_miss_pay := 'Y';
2023 ELSE
2024 l_temp_cf_strms_tbl(j).cf_miss_pay := 'N';
2025 END IF;
2026 l_temp_cf_strms_tbl(j).locked_amt := p_cf_details_tbl(i).locked_amt; -- Populate the LOCKED Flag
2027 l_cf_strms_tbl( l_cf_count + j ) := l_temp_cf_strms_tbl(j);
2028 END LOOP;
2029 -- Delete the streams created ..
2030 l_temp_cf_strms_tbl.DELETE;
2031 END LOOP;
2032 -- For Debugging purpose
2033 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2034 'line_number|cf_amount|cf_date|cf_purpose|cf_dpp|cf_ppy|cf_days|cf_rate|cf_miss_pay|is_stub|is_arrears|cf_period_start_end_date|Locked');
2035 FOR t in l_cf_strms_tbl.FIRST .. l_cf_strms_tbl.LAST
2036 LOOP
2037 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2038 l_cf_strms_tbl(t).line_number || '|' || round(l_cf_strms_tbl(t).cf_amount,4)
2039 || '|' || l_cf_strms_tbl(t).cf_date || '|' || l_cf_strms_tbl(t).cf_purpose
2040 || '|' || l_cf_strms_tbl(t).cf_dpp || '|' || l_cf_strms_tbl(t).cf_ppy
2041 || '|' || l_cf_strms_tbl(t).cf_days || '|' || l_cf_strms_tbl(t).cf_rate
2042 || '|' || l_cf_strms_tbl(t).cf_miss_pay || '|' || l_cf_strms_tbl(t).is_stub
2043 || '|' || l_cf_strms_tbl(t).is_arrears || '|' || l_cf_strms_tbl(t).cf_period_start_end_date
2044 || '|' || l_cf_strms_tbl(t).locked_amt );
2045 END LOOP;
2046 -- Setting up the out parameters to return ....
2047 x_cash_inflow_strms_tbl := l_cf_strms_tbl;
2048 x_return_status := l_return_status;
2049 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count, x_msg_data => x_msg_data);
2050 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
2051 'end debug OKLRPIUB.pls call gen_so_cf_strms');
2052 EXCEPTION
2053 WHEN OKL_API.G_EXCEPTION_ERROR THEN
2054 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
2055 p_api_name => l_api_name,
2056 p_pkg_name => G_PKG_NAME,
2057 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
2058 x_msg_count => x_msg_count,
2059 x_msg_data => x_msg_data,
2060 p_api_type => g_api_type);
2061 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
2062 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
2063 p_api_name => l_api_name,
2064 p_pkg_name => G_PKG_NAME,
2065 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
2066 x_msg_count => x_msg_count,
2067 x_msg_data => x_msg_data,
2068 p_api_type => g_api_type);
2069 WHEN OTHERS THEN
2070 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
2071 p_api_name => l_api_name,
2072 p_pkg_name => G_PKG_NAME,
2073 p_exc_name => 'OTHERS',
2074 x_msg_count => x_msg_count,
2075 x_msg_data => x_msg_data,
2076 p_api_type => g_api_type);
2077 END gen_so_cf_strms;
2078
2079 -- Fetches the appropriate rate on a particular stream element date,
2080 -- looping through the inputted the cash inflows streams
2081 PROCEDURE get_rate(
2082 p_date IN DATE,
2083 p_cf_strms_tbl IN cash_inflows_tbl_type,
2084 x_rate OUT NOCOPY NUMBER,
2085 x_return_status OUT NOCOPY VARCHAR2)
2086 AS
2087 i NUMBER;
2088 l_prev_date DATE;
2089 l_curr_date DATE;
2090 l_prev_rate NUMBER;
2091 l_curr_rate NUMBER;
2092 l_api_name VARCHAR2(30) := 'get_rate';
2093 BEGIN
2094 -- Assumption: p_cf_strms_tbl sorted by cf_date in Ascending Order
2095 IF p_cf_strms_tbl.COUNT > 0
2096 THEN
2097 -- No problem can proceed !
2098 NULL;
2099 ELSE
2100 -- Cant proceed ! Raise an Exception ..
2101 RAISE OKL_API.G_EXCEPTION_ERROR;
2102 END IF;
2103 i := p_cf_strms_tbl.FIRST;
2104 l_prev_date := p_cf_strms_tbl(i).cf_date;
2105 -- In few Scenarios rate amount may be missing
2106 l_prev_rate := nvl(p_cf_strms_tbl(i).cf_rate, p_cf_strms_tbl(i).cf_amount );
2107 l_curr_rate := nvl(p_cf_strms_tbl(i).cf_rate, p_cf_strms_tbl(i).cf_amount );
2108 WHILE i <= p_cf_strms_tbl.LAST
2109 LOOP
2110 -- Assign dates and rates
2111 l_curr_date := p_cf_strms_tbl(i).cf_date;
2112 l_curr_rate := nvl(p_cf_strms_tbl(i).cf_rate, p_cf_strms_tbl(i).cf_amount );
2113 IF l_prev_date >= l_curr_date AND
2114 i <> p_cf_strms_tbl.FIRST -- Should not execute for first element
2115 THEN
2116 -- Stream Elements should be in ascending chronological order
2117 RAISE OKL_API.G_EXCEPTION_ERROR;
2118 END IF; -- If for l_prev_date
2119 IF p_date = p_cf_strms_tbl(i).cf_date
2120 THEN
2121 -- Dates matched exactly ..
2122 x_rate := nvl(p_cf_strms_tbl(i).cf_rate, p_cf_strms_tbl(i).cf_amount );
2123 RETURN;
2124 ELSIF p_date < p_cf_strms_tbl(i).cf_date
2125 AND p_cf_strms_tbl(i).is_arrears = 'Y'
2126 THEN
2127 -- Arrears Payment
2128 x_rate := l_curr_rate;
2129 RETURN;
2130 ELSIF p_date < p_cf_strms_tbl(i).cf_date
2131 AND p_cf_strms_tbl(i).is_arrears = 'N'
2132 THEN
2133 -- Advance Payment
2134 x_rate := l_prev_rate;
2135 RETURN;
2136 ELSE
2137 l_prev_rate := l_curr_rate;
2138 l_prev_date := l_curr_date;
2139 i := p_cf_strms_tbl.NEXT(i);
2140 END IF; -- If based on p_cf_strms_tbl(i).cf_date
2141 END LOOP; -- While i <= p_cf_strms_tbl.LAST
2142 x_rate := l_prev_rate;
2143 x_return_status := G_RET_STS_SUCCESS;
2144 EXCEPTION
2145 WHEN OKL_API.G_EXCEPTION_ERROR THEN
2146 x_return_status := G_RET_STS_ERROR;
2147 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
2148 x_return_status := G_RET_STS_UNEXP_ERROR;
2149 WHEN OTHERS THEN
2150 OKL_API.SET_MESSAGE (
2151 p_app_name => G_APP_NAME,
2152 p_msg_name => G_DB_ERROR,
2153 p_token1 => G_PROG_NAME_TOKEN,
2154 p_token1_value => l_api_name,
2155 p_token2 => G_SQLCODE_TOKEN,
2156 p_token2_value => sqlcode,
2157 p_token3 => G_SQLERRM_TOKEN,
2158 p_token3_value => sqlerrm);
2159 x_return_status := G_RET_STS_UNEXP_ERROR;
2160 END get_rate;
2161
2162 -- Function to calculate the Difference between the
2163 -- start and End Dates inputted.
2164 FUNCTION GET_DAY_COUNT(
2165 p_days_in_month IN VARCHAR2,
2166 p_days_in_year IN VARCHAR2,
2167 p_start_date IN DATE,
2168 p_end_date IN DATE,
2169 p_arrears IN VARCHAR2,
2170 x_return_status OUT NOCOPY VARCHAR2,
2171 p_conversion_factor IN NUMBER DEFAULT NULL)
2172 RETURN NUMBER
2173 AS
2174 n_months NUMBER := 0;
2175 n_days NUMBER := 0;
2176 n_Years NUMBER := 0;
2177 l_start_year NUMBER;
2178 l_end_year NUMBER;
2179 l_start_month NUMBER;
2180 l_end_month NUMBER;
2181 l_start_day NUMBER;
2182 l_orig_start_day NUMBER;
2183 l_end_day NUMBER;
2184 l_start_date DATE;
2185 l_end_date DATE;
2186 l_temp_date DATE;
2187 n_leap_years NUMBER;
2188 l_day_convention VARCHAR2(10); -- Flag for 365 Year/360 Year based calculation
2189 l_mod_days NUMBER; -- Added by ssohal for Bug#6706568
2190 BEGIN
2191 x_return_status := OKL_API.G_RET_STS_SUCCESS;
2192 -- Validation: If Start Date cant be greater than End Date then return zero.
2193 l_start_date := trunc( p_start_date );
2194 l_end_date := trunc( p_end_date );
2195 IF( l_start_date > l_end_date )
2196 THEN
2197 RETURN 0;
2198 END IF;
2199 -- Based on p_day_convention calculate the days between Start and End dates
2200 IF p_days_in_month = 'ACTUAL' AND
2201 p_days_in_year = 'ACTUAL'
2202 THEN
2203 -- Calculations are based on the 365/366 Days/Year assumption
2204 n_days := floor( l_end_date - l_start_date );
2205
2206 ELSIF p_days_in_month = 'ACTUAL' AND
2207 p_days_in_year = '365'
2208 THEN
2209 -- Calculations are based on 365 days per year, even in a leap year
2210 -- Parse years ..
2211 l_start_year := to_char( p_start_date, 'YYYY' );
2212 --print( l_api_name || ': ' || 'l_start_year ' || l_start_year );
2213 IF MOD(l_start_year, 4) <> 0
2214 THEN
2215 -- Go to the next probable leap year
2216 l_start_year := l_start_year + ( 4 - MOD( l_start_year, 4 ) );
2217 END IF;
2218
2219 -- Check whether l_start_year is a leap year
2220 IF is_leap_year( l_start_year)
2221 THEN
2222 -- leap year, so leave it as it is
2223 NULL;
2224 ELSE
2225 l_start_year := l_start_year + 4;
2226 END IF;
2227 --print( l_api_name || ': ' || 'Starting with Leap Year ' || l_start_year );
2228 n_leap_years := 0;
2229 -- Form a date with 29-Feb-<l_start_year>
2230 l_temp_date := to_date( '29-02-' || to_char(l_start_year), 'DD-MM-YYYY' );
2231 --print( l_api_name || ': ' || 'l_temp_date ' || l_temp_date );
2232 WHILE l_temp_date >= l_start_date AND
2233 l_temp_date <= l_end_date
2234 LOOP
2235 -- Increment the Leap Year count
2236 n_leap_years := n_leap_years + 1;
2237 l_start_year := l_start_year + 4;
2238 -- Check whether l_start_year is a leap year
2239 IF is_leap_year( l_start_year )
2240 THEN
2241 -- leap year, so leave it as it is
2242 NULL;
2243 ELSE
2244 l_start_year := l_start_year + 4;
2245 END IF;
2246 -- Form a date with 29-Feb-<l_start_year>
2247 l_temp_date := to_date( '29-02-' || to_char(l_start_year), 'DD-MM-YYYY' );
2248 --print( l_api_name || ': ' || 'l_temp_date ' || l_temp_date );
2249 END LOOP;
2250 -- First, count the actual number of dates between l_start_date and l_end_date
2251 n_days := floor( l_end_date - l_start_date );
2252 -- Remove the number of leap years falling between
2253 n_days := n_days - n_leap_years;
2254
2255 --Bug# 13815781: start
2256 ELSIF ((p_days_in_month = '30' AND p_days_in_year = '360') OR
2257 (p_days_in_month = '30' AND p_days_in_year = '365'))
2258 THEN
2259
2260 --Bug# 14165508
2261 IF (p_conversion_factor IS NOT NULL AND p_conversion_factor <> OKL_API.G_MISS_NUM) THEN
2262
2263 n_days := round( ((l_end_date - l_start_date + 1) *
2264 p_conversion_factor),6);
2265
2266 ELSE
2267 -- Parse years ..
2268 l_start_year := to_char( p_Start_date, 'YYYY' );
2269 l_end_year := to_char( p_end_date, 'YYYY' );
2270 -- Parse months ..
2271 l_start_month := to_char( p_start_date, 'MM' );
2272 l_end_month := to_char( p_end_date, 'MM' );
2273 -- Parse days ..
2274 l_start_day := to_char( p_start_date, 'DD' );
2275 l_orig_start_day := l_start_day;
2276 l_end_day := to_char( p_end_date, 'DD' );
2277 -- Calculation is based on the assumption of 30 days per month.
2278 n_Years := l_end_year - l_start_year;
2279 n_Months := n_Years * 12 - l_start_month + l_end_month;
2280
2281 -- IF D1 is last day of February,
2282 -- then move D1 to 30
2283 -- If D2 is last day of February,
2284 -- Make D2 to 30
2285 -- If D2 is second last day of February,
2286 -- Make D2 to 29
2287 -- IF d1 is last day of the non-February month move d1 to 30
2288 -- IF d2 is last day of the non-February month move d2 to 30
2289
2290 IF l_start_month = 2 AND l_start_date = LAST_DAY( l_start_date )
2291 THEN
2292 -- Move D1 to 30
2293 l_start_day := 30;
2294 END IF;
2295
2296 IF l_end_month = 2 AND l_end_date = LAST_DAY( l_end_date )
2297 THEN
2298 -- Move D2 to 30
2299 l_end_day := 30;
2300 END IF;
2301
2302 IF l_end_month = 2 AND l_end_date = (LAST_DAY( l_end_date ) - 1)
2303 THEN
2304 -- Move D2 to 29
2305 l_end_day := 29;
2306 END IF;
2307
2308 IF l_start_month <> 2 AND l_start_date = LAST_DAY( l_start_date)
2309 THEN
2310 l_start_day := 30;
2311 END IF;
2312
2313 IF l_end_month <> 2 AND l_end_date = LAST_DAY( l_end_date)
2314 THEN
2315 l_end_day := 30;
2316 END IF;
2317 -- Calculate the number of days ...
2318 n_days := n_Months * 30 - l_start_day + l_end_day;
2319 --Bug# 13815781: end
2320 --Added by bkatraga for bug 13470626
2321 END IF;
2322 ELSIF p_days_in_month = 'ACTUAL' AND
2323 p_days_in_year = '360'
2324 THEN
2325 n_days := floor( l_end_date - l_start_date );
2326 --end bkatraga for bug 13470626
2327 ELSE
2328 x_return_Status := OKL_API.G_RET_STS_ERROR;
2329 RETURN 0;
2330 END IF;
2331
2332 -- Consider the last day incase of arrears Payments
2333 -- Start : Added by ssohal for Bug#6706568
2334 IF p_arrears = 'Y'
2335 THEN
2336 --Bug# 13815781: start
2337 IF (p_days_in_month = '30' AND
2338 p_days_in_year = '360')
2339 OR
2340 (p_days_in_month = '30' AND
2341 p_days_in_year = '365')
2342 THEN
2343 IF ( l_orig_start_day <> 31 )
2344 THEN
2345 n_days := n_days + 1;
2346 END IF;
2347 --Bug# 13815781: end
2348 ELSE
2349 n_days := n_days + 1;
2350 END IF;
2351 END IF;
2352 -- End : Added by ssohal for Bug#6706568
2353
2354 -- Set the OUT parameters and return
2355 x_return_status := 'S';
2356 RETURN n_days;
2357 EXCEPTION
2358 WHEN OKL_API.G_EXCEPTION_ERROR THEN
2359 x_return_status := G_RET_STS_ERROR;
2360 RETURN -1; -- get_day_count returns negative in case of error/failure
2361 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
2362 x_return_status := G_RET_STS_UNEXP_ERROR;
2363 RETURN -1; -- get_day_count returns negative in case of error/failure
2364 WHEN OTHERS THEN
2365 OKL_API.SET_MESSAGE (
2366 p_app_name => G_APP_NAME,
2367 p_msg_name => G_DB_ERROR,
2368 p_token1 => G_PROG_NAME_TOKEN,
2369 p_token1_value => 'GET_DAY_COUNT',
2370 p_token2 => G_SQLCODE_TOKEN,
2371 p_token2_value => sqlcode,
2372 p_token3 => G_SQLERRM_TOKEN,
2373 p_token3_value => sqlerrm);
2374 x_return_status := G_RET_STS_UNEXP_ERROR;
2375 RETURN -1; -- get_day_count returns negative in case of error/failure
2376 END get_day_count;
2377
2378 PROCEDURE compute_irr(
2379 p_api_version IN NUMBER,
2380 p_init_msg_list IN VARCHAR2,
2381 x_return_status OUT NOCOPY VARCHAR2,
2382 x_msg_count OUT NOCOPY NUMBER,
2383 x_msg_data OUT NOCOPY VARCHAR2,
2384 p_start_date IN DATE,
2385 p_day_count_method IN VARCHAR2,
2386 p_currency_code IN VARCHAR2,
2387 p_pricing_method IN VARCHAR2,
2388 p_initial_guess IN NUMBER,
2389 px_pricing_parameter_tbl IN OUT NOCOPY pricing_parameter_tbl_type,
2390 px_irr IN OUT NOCOPY NUMBER,
2391 x_payment OUT NOCOPY NUMBER)
2392 AS
2393 -- Local Variables
2394 l_api_version CONSTANT NUMBER DEFAULT 1.0;
2395 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_irr';
2396 l_return_status VARCHAR2(1);
2397 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
2398 || G_PKG_NAME || '.' || UPPER(l_api_name);
2399 l_debug_enabled VARCHAR2(10);
2400 is_debug_procedure_on BOOLEAN;
2401 is_debug_statement_on BOOLEAN;
2402 -- Cursor Definitions
2403 CURSOR get_precision_csr(p_currency_code VARCHAR2)
2404 IS
2405 SELECT NVL(cur.precision,0) precision
2406 FROM fnd_currencies cur
2407 WHERE cur.currency_code = p_currency_code;
2408 -- Local Variables/Constants Declaration
2409 l_cash_inflow_strms_tbl cash_inflows_tbl_type;
2410 l_cash_outflow_strms_tbl cash_inflows_tbl_type;
2411 l_residuals_tbl cash_inflows_tbl_type;
2412 l_days_in_month VARCHAR2(30);
2413 l_days_in_year VARCHAR2(30);
2414 cin_index NUMBER; -- Index for Cash Inflows
2415 cout_index NUMBER; -- Index for Cash Outflows
2416 res_index NUMBER; -- Index for Residuals Table
2417 l_time_zero_cost NUMBER;
2418 l_adv_inf_payment NUMBER;
2419 l_precision NUMBER;
2420 l_irr_limit NUMBER;
2421 l_irr NUMBER;
2422 l_npv NUMBER;
2423 l_npv_sign NUMBER;
2424 l_increment_rate NUMBER;
2425 l_abs_incr_rate NUMBER;
2426 n_iterations NUMBER;
2427 l_cf_dpp NUMBER;
2428 l_cf_ppy NUMBER;
2429 l_cf_amount NUMBER;
2430 l_cf_date DATE;
2431 l_days_in_future NUMBER;
2432 l_periods NUMBER;
2433 l_rate NUMBER;
2434 l_prev_irr NUMBER;
2435 l_prev_npv NUMBER;
2436 l_prev_npv_sign NUMBER;
2437 l_prev_incr_sign NUMBER;
2438 l_positive_npv_irr NUMBER;
2439 l_negative_npv_irr NUMBER;
2440 l_positive_npv NUMBER;
2441 l_negative_npv NUMBER;
2442 l_crossed_zero VARCHAR2(1);
2443 l_irr_decided VARCHAR2(1);
2444 l_temp_amount NUMBER; -- Debug Purpose
2445 l_disc_rate NUMBER; -- Debug Purpose
2446 l_term_interest NUMBER;
2447 l_acc_term_interest NUMBER;
2448 i NUMBER; -- Used as Index
2449 l_period_start_date DATE;
2450 l_period_end_date DATE;
2451 BEGIN
2452 l_return_status := OKL_API.G_RET_STS_SUCCESS;
2453 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
2454 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
2455
2456 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
2457 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
2458 -- check for logging on STATEMENT level
2459 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
2460 -- Call START_ACTIVITY to create savepoint, check compatibility and initialize message list
2461 l_return_status := OKL_API.START_ACTIVITY(
2462 p_api_name => l_api_name,
2463 p_pkg_name => G_PKG_NAME,
2464 p_init_msg_list => p_init_msg_list,
2465 l_api_version => l_api_version,
2466 p_api_version => p_api_version,
2467 p_api_type => g_api_type,
2468 x_return_status => x_return_status);
2469 --Check if activity started successfully
2470 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2471 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2472 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2473 RAISE OKL_API.G_EXCEPTION_ERROR;
2474 END IF;
2475 -- Validations here ..
2476 get_days_in_year_and_month(
2477 p_day_count_method => p_day_count_method,
2478 x_days_in_month => l_days_in_month,
2479 x_days_in_year => l_days_in_year,
2480 x_return_status => l_return_status);
2481 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2482 'After get_days_in_year_and_month ' || l_return_status);
2483 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2484 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2485 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2486 RAISE OKL_API.G_EXCEPTION_ERROR;
2487 END IF;
2488 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2489 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
2490
2491 -- 1/ Fetch the Start Date
2492 IF p_start_date IS NULL
2493 THEN
2494 -- Show the error message
2495 RAISE OKL_API.G_EXCEPTION_ERROR;
2496 END IF; -- IF p_start_date
2497 IF px_pricing_parameter_tbl.COUNT > 0
2498 THEN
2499 -- Do Nothing
2500 NULL;
2501 ELSE
2502 -- Cant proceed.
2503 RAISE OKL_API.G_EXCEPTION_ERROR;
2504 END IF; -- IF px_pricing_parameter_tbl.COUNT > 0
2505
2506 IF p_pricing_method = 'SY' OR
2507 p_pricing_method = 'TR'
2508 THEN
2509 -- Do Nothing
2510 NULL;
2511 ELSE
2512 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2513 'Compute_irr currently supports only Solve for Yields and Target Rate Pricing Scenarios only ' );
2514 RAISE OKL_API.G_EXCEPTION_ERROR;
2515 END IF;
2516 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2517 'Start Date =' || p_start_date );
2518 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2519 'Pricing Method =' || p_pricing_method );
2520 -- Starting to Initialize things .....
2521 l_time_zero_cost := 0; -- Time Zero Outflows
2522 l_adv_inf_payment := 0; -- Cash Inflow Amounts
2523 cin_index := 1;
2524 cout_index := 1;
2525 res_index := 1;
2526 -- Consolidate all the Cash and Residual Inflows per each
2527 -- pricing parameter record with line_type as FREE_FORM1 ..
2528 i := px_pricing_parameter_tbl.FIRST;
2529 WHILE i <= px_pricing_parameter_tbl.LAST
2530 LOOP
2531 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2532 'Time Zero Cost[SUM] | Financed Amount| Subsidy | Down Payment | Tradein | Capitalized Fee Amt' );
2533 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2534 round( l_time_zero_cost, 4) || '|' || round( px_pricing_parameter_tbl(i).financed_amount, 4 )
2535 || '|' || round( px_pricing_parameter_tbl(i).subsidy, 4 ) || '|' || round( px_pricing_parameter_tbl(i).down_payment, 4 )
2536 || '|' || round( px_pricing_parameter_tbl(i).trade_in, 4) || '|' || round( px_pricing_parameter_tbl(i).cap_fee_amount, 4) );
2537 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2538 'compute_irr: line_type ' || px_pricing_parameter_tbl(i).line_type );
2539 IF px_pricing_parameter_tbl(i).line_type = 'FREE_FORM1'
2540 THEN
2541 -- Handling the Cash inflows Details
2542 IF px_pricing_parameter_tbl(i).cash_inflows IS NOT NULL AND
2543 px_pricing_parameter_tbl(i).cash_inflows.COUNT > 0
2544 THEN
2545 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2546 'Cash Inflows: -------------------------------------------------------------' );
2547 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2548 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date | LOCKED');
2549 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2550 px_pricing_parameter_tbl(i).cash_inflows.LAST
2551 LOOP
2552 l_cash_inflow_strms_tbl( cin_index ) :=
2553 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2554 -- Need to calculate just the cf_days
2555 l_cash_inflow_strms_tbl(cin_index).cf_days :=
2556 get_day_count(
2557 p_days_in_month => l_days_in_month,
2558 p_days_in_year => l_days_in_year,
2559 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2560 p_end_date => l_cash_inflow_strms_tbl(cin_index).cf_date,
2561 p_arrears => l_cash_inflow_strms_tbl(cin_index).is_arrears,
2562 x_return_status => l_return_status);
2563 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2564 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2565 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2566 RAISE OKL_API.G_EXCEPTION_ERROR;
2567 END IF;
2568 -- cf_dpp, cf_ppy, cf_periods are being populated
2569 IF p_day_count_method <> 'THIRTY'
2570 THEN
2571 -- Pricing Day convention is not THIRTY day based !!
2572 -- So, override the existing the cf_dpp here !
2573 IF l_cash_inflow_strms_tbl(cin_index).is_arrears = 'Y'
2574 THEN
2575 -- cf_date represents end of the period
2576 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2577 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2578 ELSE
2579 -- cf_date represents start of the period
2580 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2581 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2582 END IF;
2583 l_cash_inflow_strms_tbl(cin_index).cf_dpp :=
2584 get_day_count(
2585 p_days_in_month => l_days_in_month,
2586 p_days_in_year => l_days_in_year,
2587 p_start_date => l_period_start_date, -- Start date mentioned in the Header rec
2588 p_end_date => l_period_end_date,
2589 p_arrears => 'Y',
2590 x_return_status => l_return_status);
2591 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2592 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2593 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2594 RAISE OKL_API.G_EXCEPTION_ERROR;
2595 END IF;
2596 END IF; -- If p_day_convention <> 'THIRTY'
2597 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2598 ROUND(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_date
2599 || '|' || round(l_cash_inflow_strms_tbl(cin_index).cf_amount,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_days
2600 || '|' || l_cash_inflow_strms_tbl(cin_index).is_Arrears || '|' || l_cash_inflow_strms_tbl(cin_index).is_stub
2601 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_dpp || '|' || l_cash_inflow_strms_tbl(cin_index).cf_ppy
2602 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date || ' | ' ||
2603 l_cash_inflow_strms_tbl(cin_index).locked_amt);
2604 -- Validations regarding either of the Payment amount or rate should be present
2605 -- can be placed here ... Think about it ..
2606 cin_index := cin_index + 1;
2607 END LOOP;
2608 END IF;
2609 -- Handling the Residual Inflows
2610 IF px_pricing_parameter_tbl(i).residual_inflows IS NOT NULL AND
2611 px_pricing_parameter_tbl(i).residual_inflows.COUNT > 0
2612 THEN
2613 -- Calculation of the Residual Value Inflow Amounts
2614 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2615 'Residuals: -----------------------------------' || px_pricing_parameter_tbl(i).residual_inflows.COUNT );
2616 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2617 'Rate | Date | Residual Amount | Days | Arrears | cf_dpp | cf_ppy | cf_period_start_end_date| LOCKED');
2618 FOR t_index IN px_pricing_parameter_tbl(i).residual_inflows.FIRST ..
2619 px_pricing_parameter_tbl(i).residual_inflows.LAST
2620 LOOP
2621 l_residuals_tbl( res_index ) :=
2622 px_pricing_parameter_tbl(i).residual_inflows(t_index);
2623 -- The wrapper API has to take the responsibility of passing the
2624 -- cf_date, cf_dpp, cf_ppy, cf_amount per each residual record
2625 get_rate(
2626 p_date => l_residuals_tbl(res_index).cf_date,
2627 p_cf_strms_tbl => px_pricing_parameter_tbl(i).cash_inflows,
2628 x_rate => l_residuals_tbl(res_index).cf_rate,
2629 x_return_status => l_return_status);
2630 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2631 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2632 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2633 RAISE OKL_API.G_EXCEPTION_ERROR;
2634 END IF;
2635 l_residuals_tbl(res_index).cf_days :=
2636 get_day_count(
2637 p_days_in_month => l_days_in_month,
2638 p_days_in_year => l_days_in_year,
2639 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2640 p_end_date => l_residuals_tbl(res_index).cf_date,
2641 p_arrears => 'Y', -- Residuals are always obtained at the end of the term
2642 x_return_status => l_return_status);
2643 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2644 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2645 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2646 RAISE OKL_API.G_EXCEPTION_ERROR;
2647 END IF;
2648
2649 IF p_day_count_method <> 'THIRTY'
2650 THEN
2651 -- Calculating the cf_dpp for the residual values
2652 l_period_end_date := l_residuals_tbl(res_index).cf_date;
2653 okl_stream_generator_pvt.add_months_new(
2654 p_start_date => l_period_end_date,
2655 p_months_after => -12 / l_residuals_tbl(res_index).cf_ppy, -- Will get the frequency for us
2656 x_date => l_period_start_date,
2657 x_return_status => l_return_status);
2658 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2659 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2660 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2661 RAISE OKL_API.G_EXCEPTION_ERROR;
2662 END IF;
2663
2664 l_period_start_date := l_period_start_date + 1;
2665 l_residuals_tbl(res_index).cf_period_start_end_date := l_period_start_date;
2666 -- Residual value will be calculated based on the
2667 -- number of days between the l_period_start_date and l_period_end_date !!
2668 l_residuals_tbl(res_index).cf_dpp :=
2669 get_day_count(
2670 p_days_in_month => l_days_in_month,
2671 p_days_in_year => l_days_in_year,
2672 p_start_date => l_period_start_date, -- Start date mentioned in the Header rec
2673 p_end_date => l_period_end_date,
2674 p_arrears => 'Y',
2675 x_return_status => l_return_status);
2676 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2677 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2678 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2679 RAISE OKL_API.G_EXCEPTION_ERROR;
2680 END IF;
2681 END IF; -- IF p_day_count_method = 'THIRTY'
2682 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2683 round(l_residuals_tbl(res_index).cf_rate,4) || '|' || l_residuals_tbl(res_index).cf_date
2684 || '|' || round(l_residuals_tbl(res_index).cf_amount,4) || '|' || l_residuals_tbl(res_index).cf_days
2685 || '|' || l_residuals_tbl(res_index).cf_purpose || '|' || l_residuals_tbl(res_index).is_Arrears
2686 || '|' || l_residuals_tbl(res_index).cf_dpp || '|' || l_residuals_tbl(res_index).cf_ppy
2687 || '|' || l_residuals_tbl(res_index).cf_period_start_end_date || '|' || l_residuals_tbl(res_index).locked_amt);
2688 -- Increment the res_index
2689 res_index := res_index + 1;
2690 END LOOP;
2691 END IF;
2692 l_time_zero_cost := l_time_zero_cost +
2693 nvl( px_pricing_parameter_tbl(i).financed_amount, 0 ) -
2694 nvl( px_pricing_parameter_tbl(i).subsidy, 0 ) -
2695 nvl( px_pricing_parameter_tbl(i).trade_in, 0 ) -
2696 nvl( px_pricing_parameter_tbl(i).down_payment, 0 ) +
2697 nvl( px_pricing_parameter_tbl(i).cap_fee_amount, 0 );
2698 -- Code to handle various possible fees/service other than the FREE_FORM1
2699 ELSIF px_pricing_parameter_tbl(i).payment_type = 'INCOME'
2700 THEN
2701 -- Assumption is that the outflow amount is placed in the
2702 -- financed_amount. And the inflows are being passed in the l_cash_inflow_strms_tbl
2703 l_time_zero_cost := l_time_zero_cost + nvl(px_pricing_parameter_tbl(i).financed_amount,0);
2704
2705 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',px_pricing_parameter_tbl(i).payment_type ||
2706 ' Inflows: -------------------------------------------------------------' );
2707 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2708 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date | LOCKED');
2709 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2710 px_pricing_parameter_tbl(i).cash_inflows.LAST
2711 LOOP
2712 l_cash_inflow_strms_tbl( cin_index ) :=
2713 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2714 -- Need to calculate just the cf_days
2715 l_cash_inflow_strms_tbl(cin_index).cf_days :=
2716 get_day_count(
2717 p_days_in_month => l_days_in_month,
2718 p_days_in_year => l_days_in_year,
2719 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2720 p_end_date => l_cash_inflow_strms_tbl(cin_index).cf_date,
2721 p_arrears => l_cash_inflow_strms_tbl(cin_index).is_arrears,
2722 x_return_status => l_return_status);
2723 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2724 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2725 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2726 RAISE OKL_API.G_EXCEPTION_ERROR;
2727 END IF;
2728 -- cf_dpp, cf_ppy, cf_periods are being populated
2729 IF p_day_count_method <> 'THIRTY'
2730 THEN
2731 -- Pricing Day convention is not THIRTY day based !!
2732 -- So, override the existing the cf_dpp here !
2733 IF l_cash_inflow_strms_tbl(cin_index).is_arrears = 'Y'
2734 THEN
2735 -- cf_date represents end of the period
2736 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2737 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2738 ELSE
2739 -- cf_date represents start of the period
2740 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2741 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2742 END IF;
2743 l_cash_inflow_strms_tbl(cin_index).cf_dpp :=
2744 get_day_count(
2745 p_days_in_month => l_days_in_month,
2746 p_days_in_year => l_days_in_year,
2747 p_start_date => l_period_start_date, -- Start date mentioned in the Header rec
2748 p_end_date => l_period_end_date,
2749 p_arrears => 'Y',
2750 x_return_status => l_return_status);
2751 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2752 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2753 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2754 RAISE OKL_API.G_EXCEPTION_ERROR;
2755 END IF;
2756 END IF; -- If p_day_convention <> 'THIRTY'
2757 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2758 round(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_date
2759 || '|' || round(l_cash_inflow_strms_tbl(cin_index).cf_amount,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_days
2760 || '|' || l_cash_inflow_strms_tbl(cin_index).is_Arrears || '|' || l_cash_inflow_strms_tbl(cin_index).is_stub
2761 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_dpp || '|' || l_cash_inflow_strms_tbl(cin_index).cf_ppy
2762 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date
2763 || '|' || l_cash_inflow_strms_tbl(cin_index).locked_amt);
2764 -- Validations regarding either of the Payment amount or rate should be present
2765 -- can be placed here ... Think about it ..
2766 cin_index := cin_index + 1;
2767 END LOOP; -- Loop on the px_pricing_parameter_tbl(i).cash_inflows
2768 -- Handling the Outflows
2769 ELSIF px_pricing_parameter_tbl(i).payment_type = 'EXPENSE'
2770 THEN
2771 -- One time expense amount is being passed in the financed_amount
2772 -- Recurring expenses are being passed as cash inflows. (Reverse the sign here)
2773 l_time_zero_cost := l_time_zero_cost + nvl(px_pricing_parameter_tbl(i).financed_amount,0);
2774 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', px_pricing_parameter_tbl(i).payment_type ||
2775 'Handling Outflows: -------------------------------------------------------------' );
2776 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2777 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date|LOCKED');
2778 IF px_pricing_parameter_tbl(i).cash_inflows.COUNT > 0
2779 THEN
2780 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2781 px_pricing_parameter_tbl(i).cash_inflows.LAST
2782 LOOP
2783 l_cash_outflow_strms_tbl( cout_index ) :=
2784 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2785 -- Checking that the amount should be negative, as they are expenses
2786 -- and expenses are always considered negative from Lessor perspective !!
2787 IF l_cash_outflow_strms_tbl(cout_index).cf_amount > 0
2788 THEN
2789 l_cash_outflow_strms_tbl(cout_index).cf_amount := -1 * l_cash_outflow_strms_tbl(cout_index).cf_amount;
2790 END IF;
2791 -- calculate the cf_days
2792 l_cash_outflow_strms_tbl(cout_index).cf_days :=
2793 get_day_count(
2794 p_days_in_month => l_days_in_month,
2795 p_days_in_year => l_days_in_year,
2796 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2797 p_end_date => l_cash_outflow_strms_tbl(cout_index).cf_date,
2798 p_arrears => l_cash_outflow_strms_tbl(cout_index).is_arrears,
2799 x_return_status => l_return_status);
2800 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2801 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2802 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2803 RAISE OKL_API.G_EXCEPTION_ERROR;
2804 END IF;
2805 -- cf_dpp, cf_ppy, cf_periods are being populated
2806 IF p_day_count_method <> 'THIRTY'
2807 THEN
2808 -- Pricing Day convention is not THIRTY day based !!
2809 -- So, override the existing the cf_dpp here !
2810 IF l_cash_outflow_strms_tbl(cout_index).is_arrears = 'Y'
2811 THEN
2812 -- cf_date represents end of the period
2813 l_period_start_date := l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date;
2814 l_period_end_date := l_cash_outflow_strms_tbl(cout_index).cf_date;
2815 ELSE
2816 -- cf_date represents start of the period
2817 l_period_start_date := l_cash_outflow_strms_tbl(cout_index).cf_date;
2818 l_period_end_date := l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date;
2819 END IF;
2820 l_cash_outflow_strms_tbl(cout_index).cf_dpp :=
2821 get_day_count(
2822 p_days_in_month => l_days_in_month,
2823 p_days_in_year => l_days_in_year,
2824 p_start_date => l_period_start_date,
2825 p_end_date => l_period_end_date,
2826 p_arrears => 'Y',
2827 x_return_status => l_return_status);
2828 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2829 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2830 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2831 RAISE OKL_API.G_EXCEPTION_ERROR;
2832 END IF;
2833 END IF; -- If p_day_convention <> 'THIRTY'
2834 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2835 ROUND(l_cash_outflow_strms_tbl(cout_index).cf_rate,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_date
2836 || '|' || round(l_cash_outflow_strms_tbl(cout_index).cf_amount,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_days
2837 || '|' || l_cash_outflow_strms_tbl(cout_index).is_Arrears || '|' || l_cash_outflow_strms_tbl(cout_index).is_stub
2838 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_dpp || '|' || l_cash_outflow_strms_tbl(cout_index).cf_ppy
2839 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date
2840 || '|' || l_cash_outflow_strms_tbl(cout_index).locked_amt);
2841 -- Validations regarding either of the Payment amount or rate should be present
2842 -- can be placed here ... Think about it ..
2843 cout_index := cout_index + 1;
2844 END LOOP; -- Loop on the px_pricing_parameter_tbl(i).cash_inflows
2845 END IF; -- If cash_inflows.count
2846 -- Handling the Outflows
2847 ELSIF px_pricing_parameter_tbl(i).line_type = 'SECDEPOSIT'
2848 THEN
2849 -- Security Deposit is a different kind of Fee. Need to handle that differently.
2850 -- Security Deposit is kind of payment, which is considered intially as inflow
2851 -- and at the end of the term, it is considered as outflow !!
2852 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2853 px_pricing_parameter_tbl(i).line_type ||
2854 'Handling Security Deposit Streams: -------------------------------------------------------------' );
2855 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2856 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date|LOCKED');
2857 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2858 px_pricing_parameter_tbl(i).cash_inflows.LAST
2859 LOOP
2860
2861 l_cash_inflow_strms_tbl( cin_index ) :=
2862 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2863 -- calculate the cf_days
2864 l_cash_inflow_strms_tbl(cin_index).cf_days :=
2865 get_day_count(
2866 p_days_in_month => l_days_in_month,
2867 p_days_in_year => l_days_in_year,
2868 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2869 p_end_date => l_cash_inflow_strms_tbl(cin_index).cf_date,
2870 p_arrears => 'N',
2871 x_return_status => l_return_status);
2872 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2873 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2874 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2875 RAISE OKL_API.G_EXCEPTION_ERROR;
2876 END IF;
2877
2878 -- cf_dpp, cf_ppy, cf_periods are being populated
2879 IF p_day_count_method <> 'THIRTY'
2880 THEN
2881 -- Pricing Day convention is not THIRTY day based !!
2882 -- So, override the existing the cf_dpp here !
2883 IF l_cash_inflow_strms_tbl(cin_index).is_arrears = 'Y'
2884 THEN
2885 -- cf_date represents end of the period
2886 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2887 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2888 ELSE
2889 -- cf_date represents start of the period
2890 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2891 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2892 END IF;
2893 l_cash_inflow_strms_tbl(cin_index).cf_dpp :=
2894 get_day_count(
2895 p_days_in_month => l_days_in_month,
2896 p_days_in_year => l_days_in_year,
2897 p_start_date => l_period_start_date,
2898 p_end_date => l_period_end_date,
2899 p_arrears => 'Y',
2900 x_return_status => l_return_status);
2901 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2902 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2903 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2904 RAISE OKL_API.G_EXCEPTION_ERROR;
2905 END IF;
2906 END IF; -- If p_day_convention <> 'THIRTY'
2907 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2908 ROUND(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_date
2909 || '|' || round(l_cash_inflow_strms_tbl(cin_index).cf_amount,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_days
2910 || '|' || l_cash_inflow_strms_tbl(cin_index).is_Arrears || '|' || l_cash_inflow_strms_tbl(cin_index).is_stub
2911 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_dpp || '|' || l_cash_inflow_strms_tbl(cin_index).cf_ppy
2912 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date
2913 || '|' || l_cash_inflow_strms_tbl(cin_index).locked_amt);
2914 l_cash_outflow_strms_tbl( cout_index ) :=
2915 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2916 -- Checking that the amount should be negative, as they are expenses
2917 -- and expenses are always considered negative from Lessor perspective !!
2918 IF l_cash_outflow_strms_tbl(cout_index).cf_amount > 0
2919 THEN
2920 l_cash_outflow_strms_tbl(cout_index).cf_amount := -1 * l_cash_outflow_strms_tbl(cout_index).cf_amount;
2921 END IF;
2922 -- calculate the cf_days
2923 l_cash_outflow_strms_tbl(cout_index).cf_days :=
2924 get_day_count(
2925 p_days_in_month => l_days_in_month,
2926 p_days_in_year => l_days_in_year,
2927 p_start_date => p_start_date,
2928 p_end_date => px_pricing_parameter_tbl(i).line_end_date,
2929 p_arrears => 'N',
2930 x_return_status => l_return_status);
2931 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2932 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2933 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2934 RAISE OKL_API.G_EXCEPTION_ERROR;
2935 END IF;
2936 -- Use the cash inflows cf_dpp as the cf_dpp for outflows too,
2937 -- instead of calculation of the cf_dpp for ACT365/ ACTUAL day count methods pricing
2938 l_cash_outflow_strms_tbl(cout_index).cf_dpp :=
2939 l_cash_inflow_strms_tbl(cin_index).cf_dpp;
2940 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2941 round(l_cash_outflow_strms_tbl(cout_index).cf_rate,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_date
2942 || '|' || round(l_cash_outflow_strms_tbl(cout_index).cf_amount,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_days
2943 || '|' || l_cash_outflow_strms_tbl(cout_index).is_Arrears || '|' || l_cash_outflow_strms_tbl(cout_index).is_stub
2944 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_dpp || '|' || l_cash_outflow_strms_tbl(cout_index).cf_ppy
2945 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date
2946 || '|' || l_cash_outflow_strms_tbl(cout_index).locked_amt);
2947 -- Increment the cin_index and cout_indexes
2948 cin_index := cin_index + 1;
2949 cout_index := cout_index + 1;
2950 END LOOP; -- Loop on the px_pricing_parameter_tbl(i).cash_inflows
2951 END IF; -- If on the line_type
2952 -- Increment index i ..
2953 i := px_pricing_parameter_tbl.NEXT(i);
2954 END LOOP;
2955 -- Loop thru' the inflows and sum the amount
2956 IF l_cash_inflow_strms_tbl.COUNT > 0
2957 THEN
2958 FOR t_in in l_cash_inflow_strms_tbl.FIRST .. l_cash_inflow_strms_tbl.LAST
2959 LOOP
2960 IF l_cash_inflow_strms_tbl(t_in).cf_date <= p_start_date
2961 THEN
2962 -- Sum the amount
2963 l_adv_inf_payment := l_adv_inf_payment + nvl( l_cash_inflow_strms_tbl(t_in).cf_amount, 0 );
2964 END IF;
2965 END LOOP;
2966 END IF;
2967 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2968 'Rent Inflows on or before the Start Date ' || round(l_adv_inf_payment,4) );
2969
2970 -- 20/ Validation: Sum of all the inflows should not exceed the Total Time zero cost
2971 IF l_adv_inf_payment >= l_time_zero_cost
2972 THEN
2973 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2974 'Unable to calculate the IRR l_adv_inf_payment= ' || round(l_adv_inf_payment, 4)
2975 || 'l_time_zero_cost = ' || round( l_time_zero_cost, 4) );
2976 OKL_API.SET_MESSAGE (
2977 p_app_name => G_APP_NAME,
2978 p_msg_name => 'OKL_IRR_CALC_INF_LOOP',
2979 p_token1 => 'ADV_AMOUNT',
2980 p_token1_value => l_adv_inf_payment,
2981 p_token2 => 'CAPITAL_AMOUNT',
2982 p_token2_value => l_time_zero_cost);
2983 RAISE OKL_API.G_EXCEPTION_ERROR;
2984 END IF;
2985 -- 30/ Validate Currency code and Precision ...
2986 IF p_currency_code IS NOT NULL
2987 THEN
2988 OPEN get_precision_csr(p_currency_code);
2989 FETCH get_precision_csr INTO l_precision;
2990 CLOSE get_precision_csr;
2991 END IF;
2992 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2993 'Precision=' || nvl(l_precision, 1) );
2994 -- If Precision is null throw error and return
2995 IF l_precision IS NULL
2996 THEN
2997 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2998 ': ' || 'Precision is not mentioned !' );
2999 OKL_API.set_message(
3000 p_app_name => G_APP_NAME,
3001 p_msg_name => OKL_API.G_REQUIRED_VALUE,
3002 p_token1 => OKL_API.G_COL_NAME_TOKEN,
3003 p_token1_value => 'CURRENCY_CODE');
3004 RAISE OKL_API.G_EXCEPTION_ERROR;
3005 END IF;
3006 -- Setting up all for the MAIN Loop ....
3007 -- Setting the IRR limit
3008 l_irr_limit := ROUND(NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000), 0)/100;
3009 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3010 ': ' || 'IRR Limit=' || l_irr_limit );
3011 -- n_iterations represent the number of Iteration we are in ..
3012 n_iterations := 0;
3013 l_acc_term_interest := 0;
3014 l_increment_rate := 0.1; -- 10% increment
3015 l_crossed_zero := 'N'; -- Y/N Flags
3016 l_irr_decided := 'N'; -- Y/N Flags
3017 l_irr := nvl(p_initial_guess,0.1);
3018 -- Forming the Equation (1)
3019 -- pvCF + pvR - ( C - S - D - T )= 0
3020 -- Until now l_time_zero_cost = C - S - D - T + Cap. Fee Amt, so negate l_time_zero_cost
3021 l_time_zero_cost := -1 * l_time_zero_cost;
3022 -- As we see in Equation (1) only pvR and pvCF are based on the rate we assume/calculate
3023 -- Hence we calculate them per loop with the current l_irr
3024 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3025 'Time Zero Cost ' || round(l_time_zero_cost,4) );
3026 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3027 'Advance Inflows Amount' || round(l_adv_inf_payment,4) );
3028 LOOP
3029 -- Increment the current iteration
3030 n_iterations := n_iterations + 1;
3031 -- Start with the Net Present value as the l_time_zero_cost
3032 l_npv := l_time_zero_cost;
3033 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','Iteration # ' || n_iterations);
3034 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','Net Present Value ' || round(l_npv,4) );
3035 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','l_irr ' || l_irr );
3036 -- Handling the Present Value of the Residuals
3037 IF l_residuals_tbl.COUNT > 0
3038 THEN
3039 res_index := l_residuals_tbl.FIRST;
3040 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3041 '--- Residual Values ------------------------------------------------------------' );
3042 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3043 'DPP | PPY | Days | Periods | Res. Amount | Rate | Discount Rate | Present Value' );
3044 WHILE res_index <= l_residuals_tbl.LAST
3045 LOOP
3046 l_cf_dpp := l_residuals_tbl(res_index).cf_dpp;
3047 l_cf_ppy := l_residuals_tbl(res_index).cf_ppy;
3048 l_cf_amount := l_residuals_tbl(res_index).cf_amount;
3049 l_cf_date := l_residuals_tbl(res_index).cf_date;
3050 l_days_in_future := l_residuals_tbl(res_index).cf_days;
3051 IF l_cf_dpp <> 0
3052 THEN
3053 l_periods := l_days_in_future / l_cf_dpp;
3054 ELSE
3055 l_periods := 0;
3056 END IF;
3057 -- This is the variable you will be change based on the Pricing Method ..
3058 -- Eg., For 'Target Payment' you will be using l_irr as l_rate
3059 -- For 'Target Rate' you will be using the l_residuals_tbl(res_index).cf_rate ..
3060 IF p_pricing_method = 'SY'
3061 THEN
3062 l_rate := l_irr;
3063 ELSE
3064 l_rate := l_residuals_tbl(res_index).cf_rate;
3065 END IF;
3066 -- Now, calculate the Present Value of the Residual Value Cash Inflow
3067 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3068 THEN
3069 OKL_API.SET_MESSAGE (
3070 p_app_name => G_APP_NAME,
3071 p_msg_name => 'OKL_IRR_ZERO_DIV');
3072 l_return_status := OKL_API.G_RET_STS_ERROR;
3073 RAISE OKL_API.G_EXCEPTION_ERROR;
3074 END IF;
3075 l_disc_rate := 1 / POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3076 l_temp_amount := l_cf_amount * l_disc_rate;
3077 l_npv := l_npv + nvl(l_temp_amount,0);
3078 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3079 round( l_cf_dpp,4) || ' | ' || l_cf_ppy || ' | ' || l_days_in_future
3080 || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3081 || ' | ' || round(l_rate,4) || ' | ' || round(l_disc_rate,4)
3082 || ' | ' || round(l_temp_amount, 4) );
3083 -- Increment the Index of the Residuals Table
3084 res_index := l_residuals_tbl.NEXT(res_index);
3085 END LOOP;
3086 END IF;
3087 -- Handling the Present Value of the Cash Inflows
3088 IF l_cash_inflow_strms_tbl.COUNT > 0
3089 THEN
3090 IF p_pricing_method = 'SY'
3091 THEN
3092 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3093 'Cash Inflows -------------------------------------------------------------' );
3094 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3095 'DPP | PPY | Periods | Inflow Amount | Rate | Discount Rate | Present Value' );
3096 ELSE
3097 -- Pricing Method is TR
3098 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3099 'Targetted Net Present Value: ' || round(l_npv,0) );
3100 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3101 'Cash Inflows ------------------------------------------' );
3102 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3103 '--- |---- |-------- |--------| Discount | Accumulated |' );
3104 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3105 'DPP | PPY | Days | Periods | Rate | Rate/Term | Interest |' );
3106 END IF;
3107 cin_index := l_cash_inflow_strms_tbl.FIRST;
3108 WHILE cin_index <= l_cash_inflow_strms_tbl.LAST
3109 LOOP
3110 l_cf_dpp := l_cash_inflow_strms_tbl(cin_index).cf_dpp;
3111 l_cf_ppy := l_cash_inflow_strms_tbl(cin_index).cf_ppy;
3112 l_cf_amount := l_cash_inflow_strms_tbl(cin_index).cf_amount;
3113 l_cf_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
3114 l_days_in_future := l_cash_inflow_strms_tbl(cin_index).cf_days;
3115 IF l_cf_dpp <> 0
3116 THEN
3117 l_periods := l_days_in_future / l_cf_dpp;
3118 ELSE
3119 l_periods := 0;
3120 END IF;
3121 -- This is the variable you will be changing based on the
3122 -- Pricing Method ..
3123 -- Say like for Target Payment you will be using l_irr as l_rate
3124 -- when for Target Rate you will be using the l_cash_inflow_strms_tbl(cin_index).cf_rate ..
3125 IF p_pricing_method = 'SY'
3126 THEN
3127 l_rate := l_irr;
3128 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3129 THEN
3130 OKL_API.SET_MESSAGE (
3131 p_app_name => G_APP_NAME,
3132 p_msg_name => 'OKL_IRR_ZERO_DIV');
3133 l_return_status := OKL_API.G_RET_STS_ERROR;
3134 RAISE OKL_API.G_EXCEPTION_ERROR;
3135 END IF;
3136 -- Now, calculate the Present Value of the Cash Inflows
3137 l_disc_rate := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3138 l_temp_amount := l_cf_amount * l_disc_rate;
3139 l_npv := l_npv + l_temp_amount;
3140 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3141 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || l_days_in_future
3142 || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3143 || ' | ' || round(l_rate,4) || ' | ' || round(l_disc_rate, 4)
3144 || ' | ' || round(l_temp_amount,4) );
3145 ELSIF p_pricing_method = 'TR'
3146 THEN
3147 IF nvl(l_cash_inflow_strms_tbl(cin_index).locked_amt, 'N') = 'N'
3148 THEN
3149 -- Rate given, need to solve for Payment
3150 l_rate := l_cash_inflow_strms_tbl(cin_index).cf_rate;
3151 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3152 THEN
3153 OKL_API.SET_MESSAGE (
3154 p_app_name => G_APP_NAME,
3155 p_msg_name => 'OKL_IRR_ZERO_DIV');
3156 l_return_status := OKL_API.G_RET_STS_ERROR;
3157 RAISE OKL_API.G_EXCEPTION_ERROR;
3158 END IF;
3159 l_term_interest := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3160 l_acc_term_interest := l_acc_term_interest + l_term_interest;
3161 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3162 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || l_days_in_future || ' | ' || round(l_periods,4)
3163 || ' | ' || round(l_rate,4) || ' | ' || round(l_term_interest, 4)
3164 || ' | ' || round(l_acc_term_interest,4) );
3165 ELSE
3166 -- The possible case is that the Quote Pricing method is TR and User has entered Income/Misc Fee with proper Amount.
3167 -- In such a case, pricing should consider the amount using the Rate which is being stored at the Cash flow levels of the Fees
3168 -- NOTE: Be sure that the fee streams has the Rate populated, may be pricing only needs to populate them
3169 -- as front end may not take the responsibility of updating the CFL with the target_rate.
3170 l_disc_rate := 1 / POWER((1 + l_cash_inflow_strms_tbl(cin_index).cf_rate /(l_cf_ppy)), l_periods);
3171 l_temp_amount := l_cf_amount * l_disc_rate;
3172 l_npv := l_npv + nvl(l_temp_amount,0);
3173 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3174 round( l_cf_dpp,4) || ' | ' || l_cf_ppy || ' | ' || l_days_in_future || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3175 || ' | ' || round(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || ' | ' || round(l_disc_rate,4) || ' | ' || round(l_temp_amount, 4) );
3176 END IF;
3177 END IF; -- IF based on Pricing method
3178 -- Increment the Index of the Residuals Table
3179 cin_index := l_cash_inflow_strms_tbl.NEXT(cin_index);
3180 END LOOP;
3181 END IF;
3182 -- Handling the Present Value of the Cash Outflows
3183 IF l_cash_outflow_strms_tbl.COUNT > 0
3184 THEN
3185 IF p_pricing_method = 'SY'
3186 THEN
3187 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3188 'Cash Outflows: -------------------------------------------------------------' );
3189 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3190 'DPP | PPY | Periods | Inflow Amount | Rate | Discount Rate | Present Value' );
3191 ELSE
3192 -- Pricing Method is TR
3193 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3194 'Targetted Net Present Value: ' || round(l_npv,0) );
3195 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3196 'Cash Outflows ------------------------------------------' );
3197 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3198 '--- |---- |-------- |--------| Discount | Accumulated |' );
3199 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3200 'DPP | PPY | Days | Periods | Rate | Rate/Term | Interest |' );
3201 END IF;
3202 cout_index := l_cash_outflow_strms_tbl.FIRST;
3203 WHILE cout_index <= l_cash_outflow_strms_tbl.LAST
3204 LOOP
3205 l_cf_dpp := l_cash_outflow_strms_tbl(cout_index).cf_dpp;
3206 l_cf_ppy := l_cash_outflow_strms_tbl(cout_index).cf_ppy;
3207 l_cf_amount := l_cash_outflow_strms_tbl(cout_index).cf_amount;
3208 l_cf_date := l_cash_outflow_strms_tbl(cout_index).cf_date;
3209 l_days_in_future := l_cash_outflow_strms_tbl(cout_index).cf_days;
3210 IF l_cf_dpp <> 0
3211 THEN
3212 l_periods := l_days_in_future / l_cf_dpp;
3213 ELSE
3214 l_periods := 0;
3215 END IF;
3216 IF p_pricing_method = 'SY'
3217 THEN
3218 l_rate := l_irr;
3219 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3220 THEN
3221 OKL_API.SET_MESSAGE (
3222 p_app_name => G_APP_NAME,
3223 p_msg_name => 'OKL_IRR_ZERO_DIV');
3224 l_return_status := OKL_API.G_RET_STS_ERROR;
3225 RAISE OKL_API.G_EXCEPTION_ERROR;
3226 END IF;
3227 -- Now, calculate the Present Value of the Cash Inflows
3228 l_disc_rate := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3229 l_temp_amount := l_cf_amount * l_disc_rate;
3230 l_npv := l_npv + l_temp_amount;
3231 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3232 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || l_days_in_future
3233 || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3234 || ' | ' || round(l_rate,4) || ' | ' || round(l_disc_rate, 4)
3235 || ' | ' || round(l_temp_amount,4) );
3236 ELSIF p_pricing_method = 'TR'
3237 THEN
3238 IF nvl(l_cash_outflow_strms_tbl(cout_index).locked_amt, 'N') = 'N'
3239 THEN
3240 -- Rate given, need to solve for Payment
3241 l_rate := l_cash_outflow_strms_tbl(cout_index).cf_rate;
3242 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3243 THEN
3244 OKL_API.SET_MESSAGE (
3245 p_app_name => G_APP_NAME,
3246 p_msg_name => 'OKL_IRR_ZERO_DIV');
3247 l_return_status := OKL_API.G_RET_STS_ERROR;
3248 RAISE OKL_API.G_EXCEPTION_ERROR;
3249 END IF;
3250 l_term_interest := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3251 l_acc_term_interest := l_acc_term_interest + l_term_interest;
3252 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3253 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || round(l_periods,4) || ' | ' || round(l_rate,4) || ' | ' || round(l_term_interest, 4)
3254 || ' | ' || round(l_acc_term_interest,4) );
3255 ELSE
3256 l_disc_rate := 1 / POWER((1 + l_cash_outflow_strms_tbl(cout_index).cf_rate /(l_cf_ppy)), l_periods);
3257 l_temp_amount := l_cf_amount * l_disc_rate;
3258 l_npv := l_npv + nvl(l_temp_amount,0);
3259 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3260 round( l_cf_dpp,4) || ' | ' || l_cf_ppy || ' | ' ||
3261 l_days_in_future || ' | ' || round(l_periods,4) || ' | ' ||
3262 round(l_cf_amount,4) || ' | ' || round(l_cash_outflow_strms_tbl(cout_index).cf_rate,4)
3263 || ' | ' || round(l_disc_rate,4) || ' | ' || round(l_temp_amount, 4) );
3264 END IF;
3265 END IF; -- IF based on Pricing method
3266 -- Increment the Index of the Residuals Table
3267 cout_index := l_cash_outflow_strms_tbl.NEXT(cout_index);
3268 END LOOP;
3269 END IF;
3270 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'NPV : ' || round(l_npv,4) );
3271 -- If Pricing Method is Solve for Payments ..
3272 IF p_pricing_method = 'SY'
3273 THEN
3274 -- With the current l_irr rate if the NPV is nearly zero ..
3275 -- then return the current rate as the final irr ...
3276 IF ROUND( l_npv, l_precision + 4 ) = 0
3277 THEN
3278 -- If the net present value is ZERO
3279 -------------------------------------------------------
3280 -- Need to place the code to return the payment too ...
3281 -------------------------------------------------------
3282 px_irr := l_irr;
3283 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3284 'INTERNAL RATE OF RETURN = ' || px_irr );
3285 EXIT;
3286 END IF;
3287 ELSIF p_pricing_method = 'TR'
3288 THEN
3289 -- Calculate the Payment and exit .. ..( NO LOOPING ...)
3290 IF ROUND( l_acc_term_interest, l_precision + 4 ) = 0
3291 THEN
3292 OKL_API.SET_MESSAGE (
3293 p_app_name => G_APP_NAME,
3294 p_msg_name => 'OKL_IRR_ZERO_DIV');
3295 l_return_status := OKL_API.G_RET_STS_ERROR;
3296 EXIT WHEN (l_return_status = OKL_API.G_RET_STS_ERROR);
3297 END IF;
3298 x_payment := -l_npv/ l_acc_term_interest;
3299 px_irr := l_irr;
3300 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3301 'CALCULATED PAYMENT AMOUNT = ' || round( x_payment,4) );
3302 EXIT;
3303 END IF; -- p_pricing_method IF
3304
3305 IF p_pricing_method = 'SY' THEN
3306 -- Determine whether we are having NPVs with different signs ..
3307 IF SIGN(l_npv) <> SIGN(l_prev_npv) AND
3308 l_crossed_zero = 'N' AND
3309 n_iterations > 1 THEN
3310 l_crossed_zero := 'Y';
3311 IF SIGN( l_npv) = 1 THEN
3312 l_positive_npv := l_npv;
3313 l_negative_npv := l_prev_npv;
3314 l_positive_npv_irr := l_irr;
3315 l_negative_npv_irr := l_prev_irr;
3316 ELSE
3317 l_positive_npv := l_prev_npv;
3318 l_negative_npv := l_npv;
3319 l_positive_npv_irr := l_prev_irr;
3320 l_negative_npv_irr := l_irr;
3321 END IF;
3322 END IF;
3323
3324 IF( SIGN(l_npv) = 1) THEN
3325 l_positive_npv := l_npv;
3326 l_positive_npv_irr := l_irr;
3327 ELSE
3328 l_negative_npv := l_npv;
3329 l_negative_npv_irr := l_irr;
3330 END IF;
3331 IF l_crossed_zero = 'Y'
3332 THEN
3333 -- Means First time we have got two opposite signed NPVs
3334 -- Introducing Interpolation approach instead of the Binary Method
3335 IF n_iterations > 1 then
3336 l_abs_incr_rate := abs(( l_positive_npv_irr - l_negative_npv_irr )
3337 / ( l_positive_npv - l_negative_npv ) * l_positive_npv) ;
3338 IF ( l_positive_npv_irr < l_negative_npv_irr ) THEN
3339 l_irr := l_positive_npv_irr + l_abs_incr_rate;
3340 ELSE
3341 l_irr := l_positive_npv_irr - l_abs_incr_rate;
3342 END IF;
3343 l_irr_decided := 'Y';
3344 ELSE
3345 -- Feel so we wont be here any time ..
3346 -- Use Binary Method to reach the desired IRR
3347 l_abs_incr_rate := ABS(l_increment_rate) / 2;
3348 END IF;
3349 ELSE
3350 -- If still not crossed zero, increment the rate with l_increment_rate as it is ..
3351 l_abs_incr_rate := ABS(l_increment_rate);
3352 END IF;
3353 IF n_iterations > 1 THEN
3354 IF SIGN(l_npv) <> SIGN(l_prev_npv) THEN
3355 IF l_prev_incr_sign = 1 THEN
3356 -- Change sign of the increment if the current and previous npvs are of different signs
3357 l_increment_rate := - l_abs_incr_rate;
3358 ELSE
3359 -- Proceed with the same increment if the current and previous npvs are of same sign
3360 l_increment_rate := l_abs_incr_rate;
3361 END IF; -- l_prev_incr_sign
3362 ELSE -- IF SIGN(l_npv) <> SIGN(l_prev_npv)
3363 -- Current and Previous npvs are of same signs
3364 IF l_prev_incr_sign = 1 THEN
3365 -- Proceed with the same increment
3366 l_increment_rate := l_abs_incr_rate;
3367 ELSE
3368 l_increment_rate := - l_abs_incr_rate;
3369 END IF;
3370 END IF;
3371 ELSE -- Else for n_iterations If ..
3372 -- First Iteration ...
3373 IF SIGN(l_npv) = -1
3374 THEN
3375 l_increment_rate := -l_increment_rate;
3376 END IF;
3377 END IF; -- n_iteratios if ..
3378 l_prev_irr := l_irr;
3379 IF l_irr_decided = 'N'
3380 THEN
3381 l_irr := l_irr + l_increment_rate;
3382 ELSE
3383 -- l_irr has been already decided .. just change the flag here ..
3384 l_irr_decided := 'N';
3385 END IF;
3386 -- If IRR exceeded the limit set in the profile, then raise an error
3387 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3388 'l_irr ' || round( l_irr, 4 ) );
3389 IF ABS(l_irr) > l_irr_limit THEN
3390 OKL_API.SET_MESSAGE (
3391 p_app_name => G_APP_NAME,
3392 p_msg_name => 'OKL_IRR_CALC_IRR_LIMIT',
3393 p_token1 => 'IRR_LIMIT',
3394 p_token1_value => l_irr_limit*100);
3395 x_return_status := OKL_API.G_RET_STS_ERROR;
3396 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3397 '---------------- IRR crossed the limit --------------------------- ' );
3398 RAISE OKL_API.G_EXCEPTION_ERROR;
3399 --EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3400 END IF;
3401 l_prev_incr_sign := SIGN(l_increment_rate);
3402 l_prev_npv_sign := SIGN(l_npv);
3403 l_prev_npv := l_npv;
3404 END IF;
3405 END LOOP; -- (Loop on n_iterations .. )
3406 -- Setting up the return variables
3407 x_return_status := l_return_status;
3408 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
3409 x_msg_data => x_msg_data);
3410 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3411 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
3412 EXCEPTION
3413 WHEN OKL_API.G_EXCEPTION_ERROR THEN
3414 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3415 p_api_name => l_api_name,
3416 p_pkg_name => G_PKG_NAME,
3417 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
3418 x_msg_count => x_msg_count,
3419 x_msg_data => x_msg_data,
3420 p_api_type => g_api_type);
3421 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
3422 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3423 p_api_name => l_api_name,
3424 p_pkg_name => G_PKG_NAME,
3425 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
3426 x_msg_count => x_msg_count,
3427 x_msg_data => x_msg_data,
3428 p_api_type => g_api_type);
3429 WHEN OTHERS THEN
3430 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3431 p_api_name => l_api_name,
3432 p_pkg_name => G_PKG_NAME,
3433 p_exc_name => 'OTHERS',
3434 x_msg_count => x_msg_count,
3435 x_msg_data => x_msg_data,
3436 p_api_type => g_api_type);
3437 END compute_irr;
3438 -- Procedure -- for solving the Financed Amount when EOTs
3439 -- are of type Percent !
3440 -- Please be sure that no down payments, Trade in , Subsidy are being
3441 -- passed in the pricing param recrod, they need to be handled irrespective
3442 -- whether they are direct amounts or percentage of Asset Cost.
3443 PROCEDURE compute_iir_sfp(
3444 p_api_version IN NUMBER,
3445 p_init_msg_list IN VARCHAR2,
3446 x_return_status OUT NOCOPY VARCHAR2,
3447 x_msg_count OUT NOCOPY NUMBER,
3448 x_msg_data OUT NOCOPY VARCHAR2,
3449 p_start_date IN DATE,
3450 p_day_count_method IN VARCHAR2,
3451 p_pricing_method IN VARCHAR2,
3452 p_initial_guess IN NUMBER,
3453 px_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type,
3454 px_iir IN OUT NOCOPY NUMBER,
3455 x_closing_balance OUT NOCOPY NUMBER,
3456 x_residual_percent OUT NOCOPY NUMBER,
3457 x_residual_int_factor OUT NOCOPY NUMBER)
3458 AS
3459 -- Local Variables
3460 l_api_version CONSTANT NUMBER DEFAULT 1.0;
3461 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_iir_sfp';
3462 l_return_status VARCHAR2(1);
3463
3464 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
3465 || G_PKG_NAME || '.' || UPPER(l_api_name);
3466 l_debug_enabled VARCHAR2(10);
3467 is_debug_procedure_on BOOLEAN;
3468 is_debug_statement_on BOOLEAN;
3469 l_days_in_month VARCHAR2(30);
3470 l_days_in_year VARCHAR2(30);
3471 l_start_date DATE;
3472 l_cash_inflows_tbl cash_inflows_tbl_type;
3473 l_asset_cost NUMBER;
3474 l_residual_amount NUMBER;
3475 l_next_cif_date DATE;
3476 l_residuals_tbl cash_inflows_tbl_type;
3477 cf_index NUMBER;
3478 res_index NUMBER;
3479 i NUMBER;
3480 l_opening_bal NUMBER;
3481 l_closing_bal NUMBER;
3482 l_rate NUMBER;
3483 l_iir NUMBER;
3484 l_days_per_annum NUMBER;
3485 l_interest_factor NUMBER;
3486 l_residual_percent NUMBER;
3487 BEGIN
3488 l_return_status := OKL_API.G_RET_STS_SUCCESS;
3489 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
3490 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
3491
3492 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3493 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
3494 -- check for logging on STATEMENT level
3495 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
3496 -- Call START_ACTIVITY to create savepoint, check compatibility
3497 -- and initialize message list
3498 l_return_status := OKL_API.START_ACTIVITY(
3499 p_api_name => l_api_name,
3500 p_pkg_name => G_PKG_NAME,
3501 p_init_msg_list => p_init_msg_list,
3502 l_api_version => l_api_version,
3503 p_api_version => p_api_version,
3504 p_api_type => g_api_type,
3505 x_return_status => x_return_status);
3506 --Check if activity started successfully
3507 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3508 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3509 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3510 RAISE OKL_API.G_EXCEPTION_ERROR;
3511 END IF;
3512 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','-Start' );
3513 get_days_in_year_and_month(
3514 p_day_count_method => p_day_count_method,
3515 x_days_in_month => l_days_in_month,
3516 x_days_in_year => l_days_in_year,
3517 x_return_status => l_return_status);
3518 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','After get_day_count_method ' || l_return_status);
3519 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3520 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3521 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3522 RAISE OKL_API.G_EXCEPTION_ERROR;
3523 END IF;
3524 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3525 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
3526 -- Initializations
3527 l_start_date := p_start_date;
3528 l_asset_cost := nvl(px_pricing_parameter_rec.financed_amount, 0);
3529 l_residuals_tbl := px_pricing_parameter_rec.residual_inflows;
3530 l_residual_amount := 0;
3531 -- Introducing new pricing method called SFR, to
3532 -- Handle the SF method when the Residual Amt is percentage of OEC
3533 IF p_pricing_method <> 'SFP'
3534 THEN
3535 -- Not handling other pricing scenarios as of now
3536 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3537 'Compute_iir_sfp currently supports only Solve for Financed Amount EOT Percent Pricing method only' );
3538 OKL_API.SET_MESSAGE (
3539 p_app_name => G_APP_NAME,
3540 p_msg_name => 'OKL_LP_INVALID_PRICING_METHOD');
3541 RAISE OKL_API.G_EXCEPTION_ERROR;
3542 END IF;
3543 IF px_pricing_parameter_rec.cash_inflows IS NOT NULL AND
3544 px_pricing_parameter_rec.cash_inflows.COUNT > 0
3545 THEN
3546 cf_index := px_pricing_parameter_rec.cash_inflows.FIRST;
3547 i := 1; -- Store inflows as an 1-Based Array
3548 l_next_cif_date := p_start_date;
3549 -- Loop thorugh the Cash Inflows ..
3550 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3551 'Cash Inflows: --------------------------------------------------- ' );
3552 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3553 'Date | Amount | Days | Purpose| Arrears | Interest Acc. on Capital |l_next_cif_date ' );
3554 WHILE cf_index <= px_pricing_parameter_rec.cash_inflows.LAST
3555 LOOP
3556 -- Copy a record from px_table to l_cash_inflows_tbl ..
3557 -- rate, cf_date, is_arrears, cf_miss_pay, amount .. will be copied
3558 l_cash_inflows_tbl(i) := px_pricing_parameter_rec.cash_inflows(cf_index);
3559 l_cash_inflows_tbl(i).cf_days := GET_DAY_COUNT(
3560 p_days_in_month => l_days_in_month,
3561 p_days_in_year => l_days_in_year,
3562 p_start_date => l_next_cif_date,
3563 p_end_date => l_cash_inflows_tbl(i).cf_date,
3564 p_arrears => l_cash_inflows_tbl(i).is_arrears,
3565 x_return_status => l_return_status);
3566 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3567 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3568 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3569 RAISE OKL_API.G_EXCEPTION_ERROR;
3570 END IF;
3571 IF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_PRINCIPAL_PAYMENT')
3572 THEN
3573 l_cash_inflows_tbl(i).cf_purpose := 'P';
3574 ELSIF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_INTEREST_PAYMENT')
3575 THEN
3576 l_cash_inflows_tbl(i).cf_purpose := 'I';
3577 ELSE
3578 l_cash_inflows_tbl(i).cf_purpose := 'B';
3579 END IF;
3580 -- Interest calculated for l_next_cif_date to l_cash_inflows_tbl(i).cf_date
3581 l_days_per_annum := get_days_per_annum(
3582 p_day_convention => p_day_count_method,
3583 p_start_date => p_start_date,
3584 p_cash_inflow_date => l_cash_inflows_tbl(i).cf_date,
3585 x_return_status => l_return_status );
3586 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3587 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3588 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3589 RAISE OKL_API.G_EXCEPTION_ERROR;
3590 END IF;
3591 -- Sum the Interest based on the capitalized amount
3592 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3593 l_cash_inflows_tbl(i).cf_date || '|' || round(l_cash_inflows_tbl(i).cf_amount,4)
3594 || '|' || l_cash_inflows_tbl(i).cf_days || '|' || l_cash_inflows_tbl(i).cf_purpose
3595 || '|' || l_cash_inflows_tbl(i).is_Arrears || '|' || '--'
3596 || '|' || l_next_cif_date);
3597 -- Incrementing the Start Date for next period
3598 l_next_cif_date := l_cash_inflows_tbl(cf_index).cf_date;
3599 IF l_cash_inflows_tbl(cf_index).is_arrears = 'Y'
3600 THEN
3601 l_next_cif_date := l_next_cif_date + 1;
3602 END IF;
3603 -- Increment the indexes
3604 cf_index := px_pricing_parameter_rec.cash_inflows.NEXT(cf_index);
3605 i := i + 1;
3606 END LOOP; -- End While Looping on px_cash_inflow_tbl
3607 END IF; -- If px_cash_inflow_tbl
3608 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3609 'Residuals: -------------------------------------' );
3610 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3611 'Date | Residual Amount | Days | Purpose| Arrears' );
3612 -- Handling Residual Value Streams
3613 IF l_residuals_tbl.COUNT > 0
3614 THEN
3615 res_index := l_residuals_tbl.FIRST;
3616 WHILE res_index <= l_residuals_tbl.LAST
3617 LOOP
3618 l_residual_amount := l_residual_amount + l_residuals_tbl(res_index).cf_amount;
3619 -- To get rate, instead of using the get_rate api, we can directly take the rate from the
3620 -- last inflow ..
3621 l_residuals_tbl(res_index).cf_rate := l_cash_inflows_tbl(l_cash_inflows_tbl.LAST).cf_rate;
3622 IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
3623 THEN
3624 l_residuals_tbl(res_index).cf_days := 0;
3625 ELSE
3626 l_residuals_tbl(res_index).cf_days := GET_DAY_COUNT(
3627 p_days_in_month => l_days_in_month,
3628 p_days_in_year => l_days_in_year,
3629 p_start_date => l_next_cif_date,
3630 p_end_date => l_residuals_tbl(res_index).cf_date,
3631 p_arrears => 'Y',
3632 x_return_status => l_return_status);
3633 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3634 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3635 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3636 RAISE OKL_API.G_EXCEPTION_ERROR;
3637 END IF;
3638 END IF; -- IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
3639 l_next_cif_date := l_residuals_tbl( res_index ).cf_date;
3640 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3641 l_residuals_tbl(res_index).cf_date || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
3642 || '|' || l_residuals_tbl(res_index).cf_days || '|' || l_residuals_tbl(res_index).cf_purpose
3643 || '|' || l_residuals_tbl(res_index).is_Arrears);
3644 -- Increment the Residual Table Index
3645 res_index := l_residuals_tbl.NEXT( res_index );
3646 END LOOP;
3647 END IF;
3648 -- Compute_iir can directly calculate the Financed Amount/Subsidy/Down payment/Trade in Amount
3649 -- without any iterations !!
3650 IF p_pricing_method = 'SFP'
3651 THEN
3652 -- Pricing Logic for Solve for Financed Amount/ Solve for Subsidy
3653 l_opening_bal := 0;
3654 l_closing_bal := 0; -- Targetting l_closing_bal as zero
3655 l_rate := 0;
3656 l_interest_factor := 1;
3657 l_residual_percent := 0;
3658 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3659 'Targeting Closing Balance: ' || l_closing_bal );
3660 IF l_residuals_tbl IS NOT NULL AND
3661 l_residuals_tbl.COUNT > 0
3662 THEN
3663 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3664 'Residual Details: -----------------------------------------------------------------' );
3665 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3666 'Days/Annum | Rate | Closing Balance|Days|Residual Amount|Interest Factor on Res. Amount|Opening Balance' );
3667 res_index := l_residuals_tbl.COUNT;
3668 WHILE res_index >= 1
3669 LOOP
3670 IF p_pricing_method = 'SFP'
3671 THEN
3672 l_days_per_annum := get_days_per_annum(
3673 p_day_convention => p_day_count_method,
3674 p_start_date => p_start_date,
3675 p_cash_inflow_date => l_residuals_tbl(res_index).cf_date,
3676 x_return_status => l_return_status );
3677 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3678 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3679 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3680 RAISE OKL_API.G_EXCEPTION_ERROR;
3681 END IF;
3682 -- Sum the Residual Percentage. Cf_amount will be storing the percentages
3683 -- instead of directly the amounts
3684 l_residual_percent := l_residual_percent + nvl( l_residuals_tbl(res_index).cf_amount, 0);
3685 l_rate := 1 + ( l_residuals_tbl(res_index).cf_days *
3686 l_residuals_tbl(res_index).cf_rate /l_days_per_annum );
3687 -- Multiply this interest factor
3688 l_interest_factor := l_interest_factor * l_rate;
3689 END IF;
3690 -- Decrement the Iterator
3691 res_index := res_index - 1;
3692 END LOOP;
3693 ELSE
3694 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3695 'No Residual Amounts Passed !!! ' );
3696 END IF;
3697 IF l_cash_inflows_tbl IS NOT NULL AND
3698 l_cash_inflows_tbl.COUNT > 0
3699 THEN
3700 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3701 'Inflows Details: ------------------------------------------------------------------' );
3702 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3703 'Days/Annum | Rate | Closing Balance|Days|Inflow Amount|Interest Factor on Inflow Amount|Opening Balance' );
3704 -- Looping through Inflows in Reverse way
3705 cf_index := l_cash_inflows_tbl.COUNT;
3706 WHILE cf_index >= 1
3707 LOOP
3708 l_days_per_annum := get_days_per_annum(
3709 p_day_convention => p_day_count_method,
3710 p_start_date => p_start_date,
3711 p_cash_inflow_date => l_cash_inflows_tbl(cf_index).cf_date,
3712 x_return_status => l_return_status );
3713 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3714 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3715 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3716 RAISE OKL_API.G_EXCEPTION_ERROR;
3717 END IF;
3718 l_rate := 1 + ( l_cash_inflows_tbl(cf_index).cf_days *
3719 l_cash_inflows_tbl(cf_index).cf_rate /l_days_per_annum );
3720 -- Multiply this interest factor
3721 l_interest_factor := l_interest_factor * l_rate;
3722 l_opening_bal := ( l_closing_bal + l_cash_inflows_tbl(cf_index).cf_amount ) / l_rate;
3723 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3724 l_days_per_annum || '|' || l_cash_inflows_tbl(cf_index).cf_rate || ' | ' || round(l_closing_bal,4) || '|' || l_cash_inflows_tbl(cf_index).cf_days
3725 || '|' || round(l_cash_inflows_tbl(cf_index).cf_amount,4) || '|' || round( l_rate, 4 )
3726 || '|' || round(l_opening_bal,4));
3727 l_closing_bal := l_opening_bal;
3728 -- Decrement the Iterator
3729 cf_index := cf_index - 1;
3730 END LOOP;
3731 END IF; -- IF l_cash_inflow_tbl is not null
3732 -- Now, after looping through the Residuals and then the Rent Inflows,
3733 -- the Opening Balance is nothing but the Financed Amount.
3734 -- The opening balance is the amount represent which should be the starting
3735 -- Financed Amount such that at the end the closing balance is ZERO.
3736 -- The above logic is just nothing but the Reverse Approach !!
3737 -- Store the Financed Amount and return now !
3738 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3739 ' Closing Balance | Residual Percent | Residual Interest Factor ');
3740 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3741 ROUND( l_closing_bal, 4 ) || ' | ' || round(l_residual_percent, 4) || ' | ' || round(l_interest_factor, 4));
3742 -- Solve for Financed Amount Logic when the Residuals are percentage of OEC
3743 x_closing_balance := l_closing_bal; -- This is the OEC'
3744 x_residual_percent := l_residual_percent;
3745 x_residual_int_factor := l_interest_factor;
3746 END IF;
3747 -- Set ther return values and return them !!
3748 x_return_status := l_return_status;
3749 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
3750 x_msg_data => x_msg_data);
3751 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3752 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
3753 EXCEPTION
3754 WHEN OKL_API.G_EXCEPTION_ERROR THEN
3755 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3756 p_api_name => l_api_name,
3757 p_pkg_name => G_PKG_NAME,
3758 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
3759 x_msg_count => x_msg_count,
3760 x_msg_data => x_msg_data,
3761 p_api_type => g_api_type);
3762 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
3763 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3764 p_api_name => l_api_name,
3765 p_pkg_name => G_PKG_NAME,
3766 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
3767 x_msg_count => x_msg_count,
3768 x_msg_data => x_msg_data,
3769 p_api_type => g_api_type);
3770 WHEN OTHERS THEN
3771 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3772 p_api_name => l_api_name,
3773 p_pkg_name => G_PKG_NAME,
3774 p_exc_name => 'OTHERS',
3775 x_msg_count => x_msg_count,
3776 x_msg_data => x_msg_data,
3777 p_api_type => g_api_type);
3778 END compute_iir_sfp;
3779 -- Procedure: Calculation of the IIR
3780 PROCEDURE compute_iir(
3781 p_api_version IN NUMBER,
3782 p_init_msg_list IN VARCHAR2,
3783 x_return_status OUT NOCOPY VARCHAR2,
3784 x_msg_count OUT NOCOPY NUMBER,
3785 x_msg_data OUT NOCOPY VARCHAR2,
3786 p_start_date IN DATE,
3787 p_day_count_method IN VARCHAR2,
3788 p_pricing_method IN VARCHAR2,
3789 p_initial_guess IN NUMBER,
3790 px_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type,
3791 px_iir IN OUT NOCOPY NUMBER,
3792 x_payment OUT NOCOPY NUMBER)
3793 AS
3794 -- Local Variables
3795 l_api_version CONSTANT NUMBER DEFAULT 1.0;
3796 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_iir';
3797 l_return_status VARCHAR2(1);
3798
3799 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
3800 || G_PKG_NAME || '.' || UPPER(l_api_name);
3801 l_debug_enabled VARCHAR2(10);
3802 is_debug_procedure_on BOOLEAN;
3803 is_debug_statement_on BOOLEAN;
3804 l_days_in_month VARCHAR2(30);
3805 l_days_in_year VARCHAR2(30);
3806 l_start_date DATE;
3807 l_cash_inflows_tbl cash_inflows_tbl_type;
3808 l_asset_cost NUMBER;
3809 l_tradein_amt NUMBER;
3810 l_subsidy_amt NUMBER;
3811 l_downpayment_amt NUMBER;
3812 l_ast_cap_fee_amt NUMBER;
3813 l_residual_amount NUMBER;
3814 l_next_cif_date DATE;
3815 l_residuals_tbl cash_inflows_tbl_type;
3816 l_investment NUMBER;
3817 l_adv_amount NUMBER;
3818 l_interest NUMBER;
3819 cf_index NUMBER;
3820 res_index NUMBER;
3821 i NUMBER;
3822 n_iterations NUMBER;
3823 l_opening_bal NUMBER;
3824 l_closing_bal NUMBER;
3825 l_payment NUMBER;
3826 l_principal_payment NUMBER;
3827 l_diff NUMBER;
3828 l_prev_diff NUMBER;
3829 l_positive_diff_pay NUMBER := 0;
3830 l_negative_diff_pay NUMBER := 0;
3831 l_positive_diff NUMBER := 0;
3832 l_negative_diff NUMBER := 0;
3833 l_crossed_zero VARCHAR2(1);
3834 l_periodic_amount NUMBER;
3835 l_prev_periodic_amount NUMBER := 0;
3836 l_increment NUMBER;
3837 l_abs_incr NUMBER;
3838 l_prev_incr_sign NUMBER;
3839 l_prev_diff_sign NUMBER;
3840 l_rate NUMBER;
3841 l_iir NUMBER;
3842 l_prev_iir NUMBER;
3843 l_positive_diff_iir NUMBER;
3844 l_negative_diff_iir NUMBER;
3845 l_days_per_annum NUMBER;
3846 l_interest_factor NUMBER;
3847 l_residual_percent NUMBER;
3848 BEGIN
3849 l_return_status := OKL_API.G_RET_STS_SUCCESS;
3850 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
3851 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
3852
3853 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3854 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
3855 -- check for logging on STATEMENT level
3856 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
3857 -- Call START_ACTIVITY to create savepoint, check compatibility
3858 -- and initialize message list
3859 l_return_status := OKL_API.START_ACTIVITY(
3860 p_api_name => l_api_name,
3861 p_pkg_name => G_PKG_NAME,
3862 p_init_msg_list => p_init_msg_list,
3863 l_api_version => l_api_version,
3864 p_api_version => p_api_version,
3865 p_api_type => g_api_type,
3866 x_return_status => x_return_status);
3867 --Check if activity started successfully
3868 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3869 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3870 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3871 RAISE OKL_API.G_EXCEPTION_ERROR;
3872 END IF;
3873 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','-Start' );
3874 get_days_in_year_and_month(
3875 p_day_count_method => p_day_count_method,
3876 x_days_in_month => l_days_in_month,
3877 x_days_in_year => l_days_in_year,
3878 x_return_status => l_return_status);
3879 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','After get_day_count_method ' || l_return_status);
3880 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3881 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3882 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3883 RAISE OKL_API.G_EXCEPTION_ERROR;
3884 END IF;
3885 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3886 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
3887 -- Initializations
3888 l_start_date := p_start_date;
3889 l_asset_cost := nvl(px_pricing_parameter_rec.financed_amount, 0);
3890 l_tradein_amt := nvl(px_pricing_parameter_rec.trade_in, 0);
3891 l_subsidy_amt := nvl(px_pricing_parameter_rec.subsidy, 0);
3892 l_downpayment_amt := nvl(px_pricing_parameter_rec.down_payment, 0);
3893 l_ast_cap_fee_amt := nvl(px_pricing_parameter_rec.cap_fee_amount, 0);
3894 l_residuals_tbl := px_pricing_parameter_rec.residual_inflows;
3895 l_periodic_amount := 0;
3896 l_investment := 0;
3897 l_adv_amount := 0;
3898 l_interest := 0;
3899 l_residual_amount := 0;
3900 -- Introducing new pricing method called SFR, to
3901 -- Handle the SF method when the Residual Amt is percentage of OEC
3902 IF p_pricing_method <> 'SP' AND
3903 p_pricing_method <> 'SM' AND
3904 p_pricing_method <> 'SF' AND
3905 p_pricing_method <> 'SFP' AND
3906 p_pricing_method <> 'SS' AND
3907 p_pricing_method <> 'SY' AND
3908 p_pricing_method <> 'SI' AND -- Solve for Trade in
3909 p_pricing_method <> 'SD' AND
3910 p_pricing_method <> 'TR' AND
3911 p_pricing_method <> 'SPP'
3912 THEN
3913 -- Not handling other pricing scenarios as of now
3914 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3915 'Compute_iir currently supports only Solve for Payment, Solve for Financed Amount, ' );
3916 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3917 'Solve for Subsidy, Solve for Subsidy, Down Payment, Tradein, Missing Payment Pricing Scenarios only, Target Rate ( IIR) ' );
3918 OKL_API.SET_MESSAGE (
3919 p_app_name => G_APP_NAME,
3920 p_msg_name => 'OKL_LP_INVALID_PRICING_METHOD');
3921 RAISE OKL_API.G_EXCEPTION_ERROR;
3922 END IF;
3923 IF p_pricing_method = 'SP' OR
3924 p_pricing_method = 'SY' OR
3925 p_pricing_method = 'SM' OR
3926 p_pricing_method = 'TR' OR
3927 p_pricing_method = 'SPP'
3928 THEN
3929 -- Solve for Payment Scenario
3930 -- So, validate whether we have been given the Financed Amount,
3931 -- and Residual Value properly atleast
3932 IF px_pricing_parameter_rec.financed_amount IS NULL
3933 THEN
3934 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3935 'Financed Amount cannot be null .. Pricing Method '|| p_pricing_method );
3936 -- Raise an Error
3937
3938 RAISE OKL_API.G_EXCEPTION_ERROR;
3939 END IF;
3940 -- The cash inflows should have rate populated !
3941 FOR t IN px_pricing_parameter_rec.cash_inflows.FIRST ..
3942 px_pricing_parameter_rec.cash_inflows.LAST
3943 LOOP
3944 IF px_pricing_parameter_rec.cash_inflows(t).cf_rate IS NULL AND
3945 p_pricing_method <> 'SY'
3946 THEN
3947 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3948 'Streams Passed are not having the Rate. Pricing Method '|| p_pricing_method );
3949 -- Raise an Error
3950 OKL_API.set_message(
3951 G_APP_NAME,
3952 OKL_API.G_INVALID_VALUE,
3953 OKL_API.G_COL_NAME_TOKEN,
3954 'CF_RATE');
3955 RAISE OKL_API.G_EXCEPTION_ERROR;
3956 END IF;
3957 END LOOP;
3958 END IF;
3959 IF p_pricing_method = 'SF' AND
3960 p_pricing_method = 'SFP'
3961 THEN
3962 -- Place validations for Solve for Financed Amount, such that
3963 -- Rate and Amounts should be present for all inflows in the px_cash_inflow_tbl table
3964 -- Also, validations what we need to impose for this table is
3965 -- a/ The inflow elements table should be ordered by date
3966 NULL;
3967 END IF;
3968 IF p_pricing_method = 'SS'
3969 THEN
3970 -- Solve for Subsidy Scenario
3971 -- So, validate whether we have been given the Financed Amount, Cash Inflows
3972 -- and Residual Value properly atleast
3973 IF px_pricing_parameter_rec.financed_amount IS NULL
3974 THEN
3975 -- Raise an Error
3976 RAISE OKL_API.G_EXCEPTION_ERROR;
3977 END IF;
3978 END IF;
3979 -- Calculate the Investment ..
3980 -- C - S - D - T
3981 l_investment := l_asset_cost - l_tradein_amt - l_subsidy_amt - l_downpayment_amt + l_ast_cap_fee_amt;
3982 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3983 'Investment including the Cap. Fee for this Asset (l_investment) ' || l_investment );
3984 IF px_pricing_parameter_rec.cash_inflows IS NOT NULL AND
3985 px_pricing_parameter_rec.cash_inflows.COUNT > 0
3986 THEN
3987 cf_index := px_pricing_parameter_rec.cash_inflows.FIRST;
3988 i := 1; -- Store inflows as an 1-Based Array
3989 l_next_cif_date := p_start_date;
3990 -- Loop thorugh the Cash Inflows ..
3991 -- 1/ Calculate the days, average rate if rates are different ..
3992 -- 2/ Sum the amounts which you are getting on or before the p_start_date
3993 -- into l_adv_amount, so that we can later validate such that
3994 -- l_investment should be greater than the l_adv_amount
3995 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3996 'Cash Inflows: --------------------------------------------------- ' );
3997 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3998 'Date | Amount | Days | Purpose| Arrears | Interest Acc. on Capital |l_next_cif_date | cf_ratio ' );
3999 WHILE cf_index <= px_pricing_parameter_rec.cash_inflows.LAST
4000 LOOP
4001 -- Copy a record from px_table to l_cash_inflows_tbl ..
4002 -- rate, cf_date, is_arrears, cf_miss_pay, amount .. will be copied
4003 l_cash_inflows_tbl(i) := px_pricing_parameter_rec.cash_inflows(cf_index);
4004 l_cash_inflows_tbl(i).cf_days := GET_DAY_COUNT(
4005 p_days_in_month => l_days_in_month,
4006 p_days_in_year => l_days_in_year,
4007 p_start_date => l_next_cif_date,
4008 p_end_date => l_cash_inflows_tbl(i).cf_date,
4009 p_arrears => l_cash_inflows_tbl(i).is_arrears,
4010 x_return_status => l_return_status);
4011 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4012 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4013 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4014 RAISE OKL_API.G_EXCEPTION_ERROR;
4015 END IF;
4016 IF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_PRINCIPAL_PAYMENT')
4017 THEN
4018 l_cash_inflows_tbl(i).cf_purpose := 'P';
4019 ELSIF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_INTEREST_PAYMENT')
4020 THEN
4021 l_cash_inflows_tbl(i).cf_purpose := 'I';
4022 ELSE
4023 l_cash_inflows_tbl(i).cf_purpose := 'B';
4024 END IF;
4025 -- Sum the amounts, which we are getting on or before the Start Date
4026 IF l_cash_inflows_tbl(i).cf_date <= p_start_date
4027 THEN
4028 l_adv_amount := l_adv_amount + nvl( l_cash_inflows_tbl(i).cf_amount, 0 );
4029 END IF;
4030 -- Interest calculated for l_next_cif_date to l_cash_inflows_tbl(i).cf_date
4031 l_days_per_annum := get_days_per_annum(
4032 p_day_convention => p_day_count_method,
4033 p_start_date => p_start_date,
4034 p_cash_inflow_date => l_cash_inflows_tbl(i).cf_date,
4035 x_return_status => l_return_status );
4036 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4037 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4038 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4039 RAISE OKL_API.G_EXCEPTION_ERROR;
4040 END IF;
4041 -- Sum the Interest based on the capitalized amount
4042 l_interest := l_interest +
4043 (l_investment * l_cash_inflows_tbl(i).cf_rate * l_cash_inflows_tbl(i).cf_days / l_days_per_annum );
4044
4045 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4046 l_cash_inflows_tbl(i).cf_date || '|' || round(l_cash_inflows_tbl(i).cf_amount,4)
4047 || '|' || l_cash_inflows_tbl(i).cf_days || '|' || l_cash_inflows_tbl(i).cf_purpose
4048 || '|' || l_cash_inflows_tbl(i).is_Arrears || '|' || l_interest
4049 || '|' || l_next_cif_date || ' | ' || l_cash_inflows_tbl(i).cf_ratio);
4050 -- Incrementing the Start Date for next period
4051 l_next_cif_date := l_cash_inflows_tbl(cf_index).cf_date;
4052 IF l_cash_inflows_tbl(cf_index).is_arrears = 'Y'
4053 THEN
4054 l_next_cif_date := l_next_cif_date + 1;
4055 END IF;
4056 -- Increment the indexes
4057 cf_index := px_pricing_parameter_rec.cash_inflows.NEXT(cf_index);
4058 i := i + 1;
4059 END LOOP; -- End While Looping on px_cash_inflow_tbl
4060 END IF; -- If px_cash_inflow_tbl
4061 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4062 'Residuals: -------------------------------------' );
4063 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4064 'Date | Residual Amount | Days | Purpose| Arrears' );
4065 -- Handling Residual Value Streams
4066 IF l_residuals_tbl.COUNT > 0
4067 THEN
4068 res_index := l_residuals_tbl.FIRST;
4069 WHILE res_index <= l_residuals_tbl.LAST
4070 LOOP
4071 l_residual_amount := l_residual_amount + l_residuals_tbl(res_index).cf_amount;
4072 -- Get rate as on that date when residuals are returned
4073 -- Instead of using the get_rate api, we can directly take the rate from the
4074 -- last inflow .. Think over this !!!
4075 l_residuals_tbl(res_index).cf_rate := l_cash_inflows_tbl(l_cash_inflows_tbl.LAST).cf_rate;
4076 IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
4077 THEN
4078 l_residuals_tbl(res_index).cf_days := 0;
4079 ELSE
4080 l_residuals_tbl(res_index).cf_days := GET_DAY_COUNT(
4081 p_days_in_month => l_days_in_month,
4082 p_days_in_year => l_days_in_year,
4083 p_start_date => l_next_cif_date,
4084 p_end_date => l_residuals_tbl(res_index).cf_date,
4085 p_arrears => 'Y',
4086 x_return_status => l_return_status);
4087 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4088 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4089 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4090 RAISE OKL_API.G_EXCEPTION_ERROR;
4091 END IF;
4092 END IF; -- IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
4093 l_next_cif_date := l_residuals_tbl( res_index ).cf_date;
4094 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4095 l_residuals_tbl(res_index).cf_date || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
4096 || '|' || l_residuals_tbl(res_index).cf_days || '|' || l_residuals_tbl(res_index).cf_purpose
4097 || '|' || l_residuals_tbl(res_index).is_Arrears);
4098 -- Increment the Residual Table Index
4099 res_index := l_residuals_tbl.NEXT( res_index );
4100 END LOOP;
4101 END IF;
4102 -- Compute_iir can directly calculate the Financed Amount/Subsidy/Down payment/Trade in Amount
4103 -- without any iterations !!
4104 -- For solving the Payment/ Missing Payment/Yields compute_iir will use the
4105 -- iterative interpolation approach !
4106 IF p_pricing_method = 'SF' OR
4107 p_pricing_method = 'SS' OR
4108 p_pricing_method = 'SD' OR
4109 p_pricing_method = 'SI' OR -- Solve for Tradein
4110 p_pricing_method = 'SFP'
4111 THEN
4112 -- Pricing Logic for Solve for Financed Amount/ Solve for Subsidy
4113 l_opening_bal := 0;
4114 l_closing_bal := 0; -- Targetting l_closing_bal as zero
4115 l_rate := 0;
4116 l_interest_factor := 1;
4117 l_residual_percent := 0;
4118 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4119 'Targeting Closing Balance: ' || l_closing_bal );
4120 IF l_residuals_tbl IS NOT NULL AND
4121 l_residuals_tbl.COUNT > 0
4122 THEN
4123 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4124 'Residual Details: -----------------------------------------------------------------' );
4125 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4126 'Days/Annum | Rate | Closing Balance|Days|Residual Amount|Interest Factor on Res. Amount|Opening Balance' );
4127 res_index := l_residuals_tbl.COUNT;
4128 WHILE res_index >= 1
4129 LOOP
4130 IF p_pricing_method = 'SFP'
4131 THEN
4132 -- Sum the Residual Percentage. Cf_amount will be storing the percentages
4133 -- instead of directly the amounts
4134 l_residual_percent := l_residual_percent + nvl( l_residuals_tbl(res_index).cf_amount, 0);
4135 ELSE
4136 -- Interest calculated from p_start_date to l_residuals_tbl(res_index).cf_date
4137 l_days_per_annum := get_days_per_annum(
4138 p_day_convention => p_day_count_method,
4139 p_start_date => p_start_date,
4140 p_cash_inflow_date => l_residuals_tbl(res_index).cf_date,
4141 x_return_status => l_return_status );
4142 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4143 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4144 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4145 RAISE OKL_API.G_EXCEPTION_ERROR;
4146 END IF;
4147 l_rate := 1 + ( l_residuals_tbl(res_index).cf_days *
4148 l_residuals_tbl(res_index).cf_rate /l_days_per_annum );
4149 l_opening_bal := ( l_closing_bal + l_residuals_tbl(res_index).cf_amount ) / l_rate;
4150 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4151 l_days_per_annum || '|' || l_residuals_tbl(res_index).cf_rate || ' | ' || round(l_closing_bal,4)
4152 || '|' || l_residuals_tbl(res_index).cf_days || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
4153 || '|' || round( l_rate, 4 ) || '|' || round(l_opening_bal,4));
4154 l_closing_bal := l_opening_bal;
4155 END IF;
4156 -- Decrement the Iterator
4157 res_index := res_index - 1;
4158 END LOOP;
4159 ELSE
4160 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4161 'No Residual Amounts Passed !!! ' );
4162 END IF;
4163 IF l_cash_inflows_tbl IS NOT NULL AND
4164 l_cash_inflows_tbl.COUNT > 0
4165 THEN
4166 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4167 'Inflows Details: ------------------------------------------------------------------' );
4168 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4169 'Days/Annum | Rate | Closing Balance|Days|Inflow Amount|Interest Factor on Inflow Amount|Opening Balance' );
4170 -- Looping through Inflows in Reverse way
4171 cf_index := l_cash_inflows_tbl.COUNT;
4172 WHILE cf_index >= 1
4173 LOOP
4174 -- Interest calculated from p_start_date to l_residuals_tbl(res_index).cf_date
4175 l_days_per_annum := get_days_per_annum(
4176 p_day_convention => p_day_count_method,
4177 p_start_date => p_start_date,
4178 p_cash_inflow_date => l_cash_inflows_tbl(cf_index).cf_date,
4179 x_return_status => l_return_status );
4180 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4181 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4182 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4183 RAISE OKL_API.G_EXCEPTION_ERROR;
4184 END IF;
4185 l_rate := 1 + ( l_cash_inflows_tbl(cf_index).cf_days *
4186 l_cash_inflows_tbl(cf_index).cf_rate /l_days_per_annum );
4187 -- Multiply this interest factor
4188 IF p_pricing_method = 'SFP'
4189 THEN
4190 l_interest_factor := l_interest_factor * l_rate;
4191 END IF;
4192 l_opening_bal := ( l_closing_bal + l_cash_inflows_tbl(cf_index).cf_amount ) / l_rate;
4193 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4194 l_days_per_annum || '|' || l_cash_inflows_tbl(cf_index).cf_rate || ' | ' || round(l_closing_bal,4) || '|' || l_cash_inflows_tbl(cf_index).cf_days
4195 || '|' || round(l_cash_inflows_tbl(cf_index).cf_amount,4) || '|' || round( l_rate, 4 )
4196 || '|' || round(l_opening_bal,4));
4197 l_closing_bal := l_opening_bal;
4198 -- Decrement the Iterator
4199 cf_index := cf_index - 1;
4200 END LOOP;
4201 END IF; -- IF l_cash_inflow_tbl is not null
4202 -- Now, after looping through the Residuals and then the Rent Inflows,
4203 -- the Opening Balance is nothing but the Financed Amount.
4204 -- The opening balance is the amount represent which should be the starting
4205 -- Financed Amount such that at the end the closing balance is ZERO.
4206 -- The above logic is just nothing but the Reverse Approach !!
4207 -- Store the Financed Amount and return now !
4208 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4209 'l_closing_bal | l_investment ' );
4210 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4211 ROUND( l_closing_bal, 4 ) || ' | ' || ROUND( l_investment, 4) );
4212 IF p_pricing_method = 'SF'
4213 THEN
4214 -- Solve for Financed Amount Logic
4215 px_pricing_parameter_rec.financed_amount := l_closing_bal - l_investment;
4216 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4217 'The Financed Amount should be: ' || round(px_pricing_parameter_rec.financed_amount, 4) );
4218 ELSIF p_pricing_method = 'SFP'
4219 THEN
4220 -- Solve for Financed Amount Logic when the Residuals are percentage of OEC
4221 px_pricing_parameter_rec.financed_amount := l_closing_bal - l_investment; -- This is the OEC'
4222 -- RV pays for that part of OEC that is not paid out by the payments.
4223 -- Hence, the present value of RV is infact the component of OEC that is not paid by the payments.
4224 -- so, RV component of OEC = RV / interest rate factor
4225 -- Hence, OEC = RV component of OEC + payments component of OEC ( OEC' )
4226 -- OEC = RV / interest rate factor + OEC'
4227 -- OEC = OEC' * interest_factor / ( interest_factor - residual_percent )
4228 IF l_residual_percent > 0 AND
4229 (l_interest_factor - l_residual_percent ) <> 0
4230 THEN
4231 -- If there was any residual percentage declared then only the
4232 -- RV Component of OEC will be present.
4233 -- Also, px_pricing_parameter_rec.financed_amount by now holds the OEC'
4234 px_pricing_parameter_rec.financed_amount :=
4235 (px_pricing_parameter_rec.financed_amount * l_interest_factor ) /
4236 ( l_interest_factor - l_residual_percent);
4237 END IF;
4238 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4239 'The Financed Amount should be: ' || round(px_pricing_parameter_rec.financed_amount, 4) );
4240 ELSIF p_pricing_method = 'SS'
4241 THEN
4242 -- Solve for Subsidy Amount
4243 px_pricing_parameter_rec.subsidy := l_investment - l_closing_bal;
4244 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4245 'Subsidy Amount ' || ROUND( px_pricing_parameter_rec.subsidy, 4) );
4246 ELSIF p_pricing_method = 'SI' -- Solve for Trade-in
4247 THEN
4248 -- Solve for Trade in amount ..
4249 px_pricing_parameter_rec.trade_in := l_investment - l_closing_bal;
4250 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4251 'Tradein Amount ' || ROUND( px_pricing_parameter_rec.trade_in, 4) );
4252 ELSIF p_pricing_method = 'SD'
4253 THEN
4254 -- Solve for Down payment amount ...
4255 px_pricing_parameter_rec.down_payment := l_investment - l_closing_bal;
4256 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4257 'Down Payment Amount ' || ROUND( px_pricing_parameter_rec.down_payment, 4) );
4258 END IF; -- IF p_pricing_method
4259 -- End of Pricing Logic for Solve for Financed Amount/Solve for Subsidy
4260 ELSIF p_pricing_method = 'SP' OR
4261 p_pricing_method = 'SY' OR
4262 p_pricing_method = 'SM' OR -- Solve for Missing Payment Amount !
4263 p_pricing_method = 'TR' OR
4264 p_pricing_method = 'SPP'
4265 THEN
4266 -- Initial Guess for the Payment Amount
4267 -- Formula is based on the Simple Interest Calculation ..
4268 -- Payment = (l_investment + interest for l_investment based on avg rate - Residual Value )
4269 -- / Number of Periods
4270 IF p_pricing_method = 'SP' OR
4271 p_pricing_method = 'SM' OR
4272 p_pricing_method = 'TR' OR
4273 p_pricing_method = 'SPP'
4274 THEN
4275 l_periodic_amount := ( l_investment + l_interest - l_residual_amount ) / l_cash_inflows_tbl.COUNT ;
4276 l_increment := l_periodic_amount / 2;
4277 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4278 'l_investment | l_interest | l_residual_value | Number of Terms| l_periodic_payment | First Increment' );
4279 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4280 round(l_investment, 4) || '|' || round(l_interest, 4) || '|' ||
4281 round(l_residual_amount, 4) || '|' || round(l_cash_inflows_tbl.COUNT ) || '|' ||
4282 round(l_periodic_amount, 4) || '|' || round(l_increment, 4));
4283 ELSE
4284 l_iir := nvl( p_initial_guess, 0.1 );
4285 l_increment := 0.1;
4286 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4287 'l_investment | l_residual_value | Initial IIR | First Increment' );
4288 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4289 round(l_investment, 4) || '|' || round(l_residual_amount, 4) || '|' ||
4290 round(l_iir, 4) || '|' || l_increment);
4291 END IF;
4292 -- Logic for Solve for Payments
4293 n_iterations := 1;
4294 l_crossed_zero := 'N';
4295 LOOP
4296 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Iteration # ' || n_iterations );
4297 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4298 'Cash Inflows: ----------------------------------------------------------------------------' );
4299 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4300 'Days/Annum|Rate|Days|Opening Balance|Payment Amount|Interest Income|Principal Payment|Closing Balance' );
4301 l_opening_bal := l_investment;
4302 FOR cf_index in l_cash_inflows_tbl.FIRST .. l_cash_inflows_tbl.LAST
4303 LOOP
4304 IF p_pricing_method = 'SP' OR
4305 p_pricing_method = 'TR'
4306 THEN
4307 l_payment := l_periodic_amount;
4308 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4309 ELSIF p_pricing_method = 'SPP'
4310 THEN
4311 l_payment := l_periodic_amount * nvl(l_cash_inflows_tbl(cf_index).cf_ratio,1);
4312 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4313 ELSIF p_pricing_method = 'SM'
4314 THEN
4315 IF l_cash_inflows_tbl(cf_index).cf_rate IS NOT NULL AND
4316 l_cash_inflows_tbl(cf_index).cf_amount IS NULL
4317 THEN
4318 -- Payment level for which the amount is being calculated iteratively !
4319 l_payment := l_periodic_amount;
4320 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4321 ELSE
4322 l_payment := l_cash_inflows_tbl(cf_index).cf_amount;
4323 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4324 END IF;
4325 ELSE
4326 l_payment := l_cash_inflows_tbl(cf_index).cf_amount;
4327 l_rate := l_iir;
4328 END IF;
4329 -- Interest calculated for p_start_date to l_cash_inflows_tbl(i).cf_date
4330 l_days_per_annum := get_days_per_annum(
4331 p_day_convention => p_day_count_method,
4332 p_start_date => p_start_date,
4333 p_cash_inflow_date => l_cash_inflows_tbl(cf_index).cf_date,
4334 x_return_status => l_return_status );
4335 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4336 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4337 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4338 RAISE OKL_API.G_EXCEPTION_ERROR;
4339 END IF;
4340 IF ( l_cash_inflows_tbl(cf_index).cf_purpose = 'B' )
4341 THEN
4342 l_interest := l_opening_bal * l_cash_inflows_tbl(cf_index).cf_days
4343 * l_rate /l_days_per_annum;
4344 ELSIF ( l_cash_inflows_tbl(cf_index).cf_purpose = 'P' )
4345 THEN
4346 l_interest := 0;
4347 ELSIF ( l_cash_inflows_tbl(cf_index).cf_purpose = 'I' )
4348 THEN
4349 l_interest := l_principal_payment;
4350 END IF;
4351 l_principal_payment := l_payment - l_interest;
4352 l_closing_bal := l_opening_bal - l_principal_payment;
4353 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4354 l_days_per_annum || '|' || round(l_rate,4)
4355 || '|' || l_cash_inflows_tbl(cf_index).cf_days
4356 || '|' || round(l_opening_bal,4) || '|' || round(l_payment,4)
4357 || '|' || round(l_interest,4) || '|' || round(l_principal_payment,4)
4358 || '|' || round(l_closing_bal,4) );
4359 l_opening_bal := l_closing_bal;
4360 END LOOP;
4361 IF l_residuals_tbl IS NOT NULL AND
4362 l_residuals_tbl.COUNT > 0
4363 THEN
4364 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','Residuals: ---------- ' );
4365 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4366 'Rate|Days|Opening Balance|Residual Amount|Interest Income|Principal Payment|Closing Balance' );
4367
4368 FOR res_index in l_residuals_tbl.FIRST .. l_residuals_tbl.LAST
4369 LOOP
4370 l_payment := l_residuals_tbl(res_index).cf_amount;
4371 IF p_pricing_method = 'SP' OR
4372 p_pricing_method = 'SM' OR
4373 p_pricing_method = 'TR' OR
4374 p_pricing_method = 'SPP'
4375 THEN
4376 l_rate := l_residuals_tbl(res_index).cf_rate;
4377 ELSE
4378 l_rate := l_iir;
4379 END IF;
4380 -- Interest calculated for p_start_date to l_cash_inflows_tbl(i).cf_date
4381 l_days_per_annum := get_days_per_annum(
4382 p_day_convention => p_day_count_method,
4383 p_start_date => p_start_date,
4384 p_cash_inflow_date => l_residuals_tbl(res_index).cf_date,
4385 x_return_status => l_return_status );
4386 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4387 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4388 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4389 RAISE OKL_API.G_EXCEPTION_ERROR;
4390 END IF;
4391 l_interest := l_opening_bal * l_residuals_tbl(res_index).cf_days
4392 * l_rate /l_days_per_annum;
4393 l_principal_payment := l_payment - l_interest;
4394 l_closing_bal := l_opening_bal - l_principal_payment;
4395 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4396 l_days_per_annum || '|' || l_rate || '|' || l_residuals_tbl(res_index).cf_days
4397 || '|' || round(l_opening_bal,4) || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
4398 || '|' || round(l_interest,4) || '|' || round(l_principal_payment, 4)
4399 || '|' || round(l_closing_bal,4) );
4400 l_opening_bal := l_closing_bal;
4401 END LOOP;
4402 END IF;
4403 l_diff := l_opening_bal;
4404 IF ROUND( l_diff, 4 ) = 0
4405 THEN
4406 IF p_pricing_method = 'SP' OR
4407 p_pricing_method = 'SM' OR
4408 p_pricing_method = 'TR' OR
4409 p_pricing_method = 'SPP'
4410 THEN
4411 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4412 'CALCULATED PAYMENT AMOUNT = ' || l_periodic_amount );
4413 x_payment := l_periodic_amount;
4414 ELSE
4415 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4416 'IMPLICIT INTEREST RATE =' || l_iir );
4417 px_iir := l_iir;
4418 END IF;
4419 x_return_status := OKL_API.G_RET_STS_SUCCESS;
4420
4421 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
4422 x_msg_data => x_msg_data);
4423 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4424 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
4425 EXIT;
4426 END IF; -- If ROUND(L_DIFF, 4) = 0
4427 -- Else Use the Interpolation method
4428 IF n_iterations > 1 AND
4429 SIGN(l_diff) <> SIGN(l_prev_diff) AND
4430 l_crossed_zero = 'N'
4431 THEN
4432 l_crossed_zero := 'Y';
4433 IF ( SIGN( l_diff) = 1 )
4434 THEN
4435 -- Positive Diff ones
4436 l_positive_diff := l_diff;
4437 l_negative_diff := l_prev_diff;
4438 IF p_pricing_method = 'SP' OR
4439 p_pricing_method = 'SM' OR
4440 p_pricing_method = 'TR' OR
4441 p_pricing_method = 'SPP'
4442 THEN
4443 l_positive_diff_pay := l_periodic_amount;
4444 l_negative_diff_pay := l_prev_periodic_amount;
4445 ELSE
4446 l_positive_diff_iir := l_iir;
4447 l_negative_diff_iir := l_prev_iir;
4448 END IF;
4449 ELSE
4450 -- Negative Diff ones
4451 l_positive_diff := l_prev_diff;
4452 l_negative_diff := l_diff;
4453 IF p_pricing_method = 'SP' OR
4454 p_pricing_method = 'SM' OR
4455 p_pricing_method = 'TR' OR
4456 p_pricing_method = 'SPP'
4457 THEN
4458 l_positive_diff_pay := l_prev_periodic_amount;
4459 l_negative_diff_pay := l_periodic_amount;
4460 ELSE
4461 l_positive_diff_iir := l_prev_iir;
4462 l_negative_diff_iir := l_iir;
4463 END IF;
4464 END IF; -- IF SIGN(L_DIFF) = 1
4465 END IF; -- n_iterations > 1 IF
4466 -- Else if this is the first time store in appropriate variables
4467 IF( SIGN(l_diff) = 1)
4468 THEN
4469 l_positive_diff := l_diff;
4470 IF p_pricing_method = 'SP' OR
4471 p_pricing_method = 'SM' OR
4472 p_pricing_method = 'TR' OR
4473 p_pricing_method = 'SPP'
4474 THEN
4475 l_positive_diff_pay := l_periodic_amount;
4476 ELSE
4477 l_positive_diff_iir := l_iir;
4478 END IF;
4479 ELSE
4480 l_negative_diff := l_diff;
4481 IF p_pricing_method = 'SP' OR
4482 p_pricing_method = 'SM' OR
4483 p_pricing_method = 'TR' OR
4484 p_pricing_method = 'SPP'
4485 THEN
4486 l_negative_diff_pay := l_periodic_amount;
4487 ELSE
4488 l_negative_diff_iir := l_iir;
4489 END IF;
4490 END IF;
4491 IF l_crossed_zero = 'Y' THEN
4492 -- Use interpolation method ...
4493 IF n_iterations > 1
4494 THEN
4495 IF p_pricing_method = 'SP' OR
4496 p_pricing_method = 'SM' OR
4497 p_pricing_method = 'TR' OR
4498 p_pricing_method = 'SPP'
4499 THEN
4500 l_abs_incr := abs(( l_positive_diff_pay - l_negative_diff_pay ) /
4501 ( l_positive_diff - l_negative_diff ) * l_diff);
4502 ELSE
4503 l_abs_incr := abs(( l_positive_diff_iir - l_negative_diff_iir ) /
4504 ( l_positive_diff - l_negative_diff ) * l_diff);
4505 END IF;
4506 ELSE
4507 l_abs_incr := ABS(l_increment) / 2;
4508 END IF;
4509 ELSE
4510 l_abs_incr := ABS(l_increment);
4511 END IF;
4512
4513 IF n_iterations > 1 THEN
4514 IF SIGN(l_diff) <> l_prev_diff_sign THEN
4515 IF l_prev_incr_sign = 1 THEN
4516 l_increment := -l_abs_incr;
4517 ELSE
4518 l_increment := l_abs_incr;
4519 END IF;
4520 ELSE
4521 IF l_prev_incr_sign = 1 THEN
4522 l_increment := l_abs_incr;
4523 ELSE
4524 l_increment := - l_abs_incr;
4525 END IF;
4526 END IF;
4527 ELSE -- First Iteration
4528 IF p_pricing_method = 'SP' OR
4529 p_pricing_method = 'SM' OR
4530 p_pricing_method = 'TR' OR
4531 p_pricing_method = 'SPP'
4532 THEN
4533 l_increment := -l_increment;
4534 END IF;
4535 IF SIGN(l_diff) = 1 THEN
4536 l_increment := -l_increment;
4537 ELSE
4538 l_increment := l_increment;
4539 END IF;
4540 END IF;
4541 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4542 'l_diff ' || round(l_diff,4) );
4543 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4544 'l_prev_diff ' || round(l_prev_diff,4) );
4545 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4546 'l_crossed_zero ' || l_crossed_zero );
4547 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4548 'l_abs_incr ' || l_abs_incr );
4549 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4550 'l_increment ' || l_increment );
4551 IF p_pricing_method = 'SP' OR
4552 p_pricing_method = 'SM' OR
4553 p_pricing_method = 'TR' OR
4554 p_pricing_method = 'SPP'
4555 THEN
4556 l_prev_periodic_amount := l_periodic_amount;
4557 l_periodic_amount := l_periodic_amount + l_increment;
4558 ELSE
4559 l_prev_iir := l_iir;
4560 l_iir := l_iir + l_increment;
4561 END IF;
4562 IF n_iterations > 100
4563 THEN
4564 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
4565 p_msg_name => 'OKL_IIR_CALC_IIR_LIMIT',
4566 p_token1 => 'IIR_LIMIT',
4567 p_token1_value => 100);
4568 RAISE OKL_API.G_EXCEPTION_ERROR;
4569 END IF;
4570 l_prev_incr_sign := SIGN(l_increment);
4571 l_prev_diff_sign := SIGN(l_diff);
4572 l_prev_diff := l_diff;
4573 -- Increment the n_iterations index ..
4574 n_iterations := n_iterations + 1;
4575 END LOOP; -- Loop on n_iterations
4576 -- End of the Pricing Logic for Solve for Payments
4577 END IF; -- IF p_pricing_method ...
4578 -- Set ther return values and return them !!
4579 x_return_status := l_return_status;
4580 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
4581 x_msg_data => x_msg_data);
4582 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4583 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
4584 EXCEPTION
4585 WHEN OKL_API.G_EXCEPTION_ERROR THEN
4586 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4587 p_api_name => l_api_name,
4588 p_pkg_name => G_PKG_NAME,
4589 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
4590 x_msg_count => x_msg_count,
4591 x_msg_data => x_msg_data,
4592 p_api_type => g_api_type);
4593 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
4594 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4595 p_api_name => l_api_name,
4596 p_pkg_name => G_PKG_NAME,
4597 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
4598 x_msg_count => x_msg_count,
4599 x_msg_data => x_msg_data,
4600 p_api_type => g_api_type);
4601 WHEN OTHERS THEN
4602 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4603 p_api_name => l_api_name,
4604 p_pkg_name => G_PKG_NAME,
4605 p_exc_name => 'OTHERS',
4606 x_msg_count => x_msg_count,
4607 x_msg_data => x_msg_data,
4608 p_api_type => g_api_type);
4609 END compute_iir;
4610
4611 -- Validates whether for a particular object ( Eg. Quick Quote )
4612 -- the inputed pricing method is valid or not ( Eg. SY, TR, SP, SF .. etc )
4613 FUNCTION validate_pricing_method(
4614 p_pricing_method IN VARCHAR2,
4615 p_object_type IN VARCHAR2,
4616 x_return_status IN OUT NOCOPY VARCHAR2)
4617 RETURN BOOLEAN
4618 IS
4619 l_valid BOOLEAN;
4620 BEGIN
4621 l_valid := FALSE;
4622 --print( 'validate_pricing_method: p_pricing_method = ' || p_pricing_method );
4623 IF 'RC|SF|SP|SS|SY|TR' LIKE '%'||p_pricing_method||'%' AND
4624 p_object_type = 'QQ'
4625 THEN
4626 l_valid := TRUE;
4627 END IF;
4628 x_return_status := OKL_API.G_RET_STS_SUCCESS;
4629 RETURN l_valid;
4630 EXCEPTION
4631 WHEN OKL_API.G_EXCEPTION_ERROR
4632 THEN
4633 x_return_status := G_RET_STS_ERROR;
4634 RETURN false;
4635 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR
4636 THEN
4637 x_return_status := G_RET_STS_UNEXP_ERROR;
4638 RETURN false;
4639 WHEN OTHERS
4640 THEN
4641 OKL_API.SET_MESSAGE (
4642 p_app_name => G_APP_NAME,
4643 p_msg_name => G_DB_ERROR,
4644 p_token1 => G_PROG_NAME_TOKEN,
4645 p_token1_value => 'validate_pricing_method',
4646 p_token2 => G_SQLCODE_TOKEN,
4647 p_token2_value => sqlcode,
4648 p_token3 => G_SQLERRM_TOKEN,
4649 p_token3_value => sqlerrm);
4650
4651 x_return_status := G_RET_STS_UNEXP_ERROR;
4652 RETURN false;
4653 END validate_pricing_method;
4654
4655
4656 -- API which accepts the Lease Rate Set id
4657 -- and returns all the Lease Rate set Details, Factors, and Levels
4658 -- based on the term and end of term %age passeed.
4659 PROCEDURE get_lease_rate_factors(
4660 p_api_version IN NUMBER,
4661 p_init_msg_list IN VARCHAR2,
4662 x_return_status OUT NOCOPY VARCHAR2,
4663 x_msg_count OUT NOCOPY NUMBER,
4664 x_msg_data OUT NOCOPY VARCHAR2,
4665 p_lrt_id IN NUMBER, -- Assuming LRS ID Header
4666 p_start_date IN DATE,
4667 p_term_in_months IN NUMBER,
4668 p_eot_percentage IN NUMBER,
4669 x_lrs_details OUT NOCOPY lrs_details_rec_type,
4670 x_lrs_factor OUT NOCOPY lrs_factor_rec_type,
4671 x_lrs_levels OUT NOCOPY lrs_levels_tbl_type)
4672 IS
4673 -- Cursor Declarations
4674 CURSOR lrs_version_details_csr(
4675 p_lrs_version_id IN okl_ls_rt_fctr_sets_v.ID%TYPE,
4676 p_date IN DATE )
4677 IS
4678 SELECT
4679 hdr.id header_id,
4680 ver.rate_set_version_id version_id,
4681 hdr.NAME name,
4682 hdr.lrs_type_code lrs_type_code,
4683 hdr.FRQ_CODE frq_code,
4684 hdr.currency_code currency_code,
4685 ver.sts_code sts_code,
4686 ver.effective_from_date effective_from_date,
4687 ver.effective_to_date effective_to_date,
4688 ver.arrears_yn arrears_yn,
4689 ver.end_of_term_ver_id end_of_term_ver_id,
4690 ver.std_rate_tmpl_ver_id std_rate_tmpl_ver_id,
4691 ver.adj_mat_version_id adj_mat_version_id,
4692 ver.version_number version_number,
4693 ver.lrs_rate lrs_version_rate,
4694 ver.rate_tolerance rate_tolerance,
4695 ver.residual_tolerance residual_tolerance,
4696 ver.deferred_pmts deferred_pmts,
4697 ver.advance_pmts advance_pmts
4698 FROM okl_ls_rt_fctr_sets_v hdr,
4699 okl_fe_rate_set_versions_v ver
4700 WHERE ver.rate_set_id = hdr.id
4701 AND ver.rate_set_version_id = p_lrs_version_id
4702 AND trunc(ver.effective_from_date) <= p_date
4703 AND nvl(trunc(ver.effective_to_date), p_date) >= p_date;
4704
4705 CURSOR lrs_factors_csr(
4706 p_lrs_version_id IN NUMBER,
4707 p_term IN NUMBER,
4708 p_eot_percentage IN NUMBER,
4709 p_res_tolerance IN NUMBER -- From the version record
4710 )
4711 IS
4712 SELECT fac.id factor_id,
4713 fac.term_in_months term_in_months,
4714 fac.residual_value_percent residual_value_percent
4715 FROM okl_ls_rt_fctr_ents_v fac
4716 WHERE fac.rate_set_version_id = p_lrs_version_id
4717 AND fac.term_in_months = p_term
4718 AND p_eot_percentage BETWEEN fac.residual_value_percent - nvl(p_res_tolerance, 0) AND
4719 fac.residual_value_percent + nvl(p_res_tolerance, 0);
4720
4721
4722 CURSOR lrs_levels_csr( p_lrs_factor_id IN NUMBER )
4723 IS
4724 SELECT lvl.sequence_number sequence_number,
4725 lvl.periods periods,
4726 lvl.lease_rate_factor lease_rate_factor
4727 FROM okl_fe_rate_set_levels lvl
4728 WHERE lvl.rate_set_factor_id = p_lrs_factor_id
4729 ORDER BY sequence_number ASC;
4730
4731 -- Local Variables
4732 l_api_version CONSTANT NUMBER DEFAULT 1.0;
4733 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lease_rate_factors';
4734 l_return_status VARCHAR2(1);
4735 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
4736 || G_PKG_NAME || '.' || UPPER(l_api_name);
4737 l_debug_enabled VARCHAR2(10);
4738 is_debug_procedure_on BOOLEAN;
4739 is_debug_statement_on BOOLEAN;
4740 -- Variable Declarations
4741 lrs_details_rec lrs_details_rec_type;
4742 lrs_factor lrs_factor_rec_type;
4743 lrs_levels lrs_levels_tbl_type;
4744 lvl_index NUMBER;
4745 BEGIN
4746 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4747 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
4748 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
4749 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4750 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
4751 -- check for logging on STATEMENT level
4752 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
4753 -- Call START_ACTIVITY to create savepoint, check compatibility
4754 -- and initialize message list
4755 l_return_status := OKL_API.START_ACTIVITY(
4756 p_api_name => l_api_name,
4757 p_pkg_name => G_PKG_NAME,
4758 p_init_msg_list => p_init_msg_list,
4759 l_api_version => l_api_version,
4760 p_api_version => p_api_version,
4761 p_api_type => g_api_type,
4762 x_return_status => x_return_status);
4763 --Check if activity started successfully
4764 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4765 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4766 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4767 RAISE OKL_API.G_EXCEPTION_ERROR;
4768 END IF;
4769 -- Actual logic Begins here
4770 IF p_start_date IS NULL OR
4771 p_lrt_id IS NULL OR
4772 p_eot_percentage IS NULL OR
4773 p_term_in_months IS NULL
4774 THEN
4775 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4776 'Missing required input value ' );
4777
4778 RAISE OKL_API.G_EXCEPTION_ERROR;
4779 END IF;
4780 -- Start with fetching the Lease Rate Set Header n Version information
4781 l_return_status := OKL_API.G_RET_STS_ERROR;
4782 FOR t_rec IN lrs_version_details_csr(
4783 p_lrs_version_id => p_lrt_id,
4784 p_date => p_start_date)
4785 LOOP
4786 lrs_details_rec.header_id := t_rec.header_id;
4787 lrs_details_rec.version_id := t_rec.version_id;
4788 lrs_details_rec.name := t_rec.name;
4789 lrs_details_rec.lrs_type_code := t_rec.lrs_type_code;
4790 lrs_details_rec.frq_code := t_rec.frq_code;
4791 lrs_details_rec.currency_code := t_rec.currency_code;
4792 lrs_details_rec.sts_code := t_rec.sts_code;
4793 lrs_details_rec.effective_from_date := t_rec.effective_from_date;
4794 lrs_details_rec.effective_to_date := t_rec.effective_to_date ;
4795 lrs_details_rec.arrears_yn := t_rec.arrears_yn ;
4796 lrs_details_rec.end_of_term_ver_id := t_rec.end_of_term_ver_id ;
4797 lrs_details_rec.std_rate_tmpl_ver_id := t_rec.std_rate_tmpl_ver_id ;
4798 lrs_details_rec.adj_mat_version_id := t_rec.adj_mat_version_id ;
4799 lrs_details_rec.version_number := t_rec.version_number ;
4800 lrs_details_rec.lrs_version_rate := t_rec.lrs_version_rate ;
4801 lrs_details_rec.rate_tolerance := t_rec.rate_tolerance ;
4802 lrs_details_rec.residual_tolerance := t_rec.residual_tolerance ;
4803 lrs_details_rec.deferred_pmts := t_rec.deferred_pmts ;
4804 lrs_details_rec.advance_pmts := t_rec.advance_pmts ;
4805 -- Using l_return_status as a flag
4806 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4807 END LOOP;
4808 IF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4809 RAISE OKL_API.G_EXCEPTION_ERROR;
4810 END IF;
4811 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4812 ' Successfully fetched the Lease Rate Set Header n Version Details !' );
4813 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4814 ' p_term_in_months | p_eof_percentage | Residual Tolerance ' ||
4815 p_term_in_months || ' | ' || round(p_eot_percentage, 4)
4816 || ' | ' || round(lrs_details_rec.residual_tolerance, 4));
4817 -- Fetch the Factors Information
4818 l_return_status := OKL_API.G_RET_STS_ERROR;
4819 FOR t_rec IN lrs_factors_csr(
4820 p_lrs_version_id => lrs_details_rec.version_id,
4821 p_term => p_term_in_months,
4822 p_eot_percentage => p_eot_percentage,
4823 p_res_tolerance => lrs_details_rec.residual_tolerance)
4824 LOOP
4825 lrs_factor.factor_id := t_rec.factor_id;
4826 lrs_factor.term_in_months := t_rec.term_in_months;
4827 lrs_factor.residual_value_percent := t_rec.residual_value_percent;
4828 -- Using l_return_status as a flag
4829 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4830 END LOOP; -- lrs_factors
4831 IF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4832 RAISE OKL_API.G_EXCEPTION_ERROR;
4833 END IF;
4834 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4835 'Successfully fetched the Lesae Rate Set Factors !' );
4836 -- Fetch the levels Information
4837 l_return_status := OKL_API.G_RET_STS_ERROR;
4838 lvl_index := 1;
4839 FOR t_rec IN lrs_levels_csr( p_lrs_factor_id => lrs_factor.factor_id )
4840 LOOP
4841 lrs_levels(lvl_index).sequence_number := t_rec.sequence_number;
4842 lrs_levels(lvl_index).periods := t_rec.periods;
4843 lrs_levels(lvl_index).lease_rate_factor := t_rec.lease_rate_factor;
4844 -- Using l_return_status as a flag
4845 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4846 -- Increment the lvl_index
4847 lvl_index := lvl_index + 1;
4848 END LOOP; -- lrs_levels
4849 IF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4850 RAISE OKL_API.G_EXCEPTION_ERROR;
4851 END IF;
4852 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4853 'Successfully fetched the Lease Rate Factor Levels !' );
4854 -- Setting up the return variables ...
4855 x_lrs_details := lrs_details_rec;
4856 x_lrs_factor := lrs_factor;
4857 x_lrs_levels := lrs_levels;
4858 x_return_status := l_return_status;
4859 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
4860 x_msg_data => x_msg_data);
4861 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4862 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
4863 EXCEPTION
4864 WHEN OKL_API.G_EXCEPTION_ERROR THEN
4865 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4866 p_api_name => l_api_name,
4867 p_pkg_name => G_PKG_NAME,
4868 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
4869 x_msg_count => x_msg_count,
4870 x_msg_data => x_msg_data,
4871 p_api_type => g_api_type);
4872 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
4873 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4874 p_api_name => l_api_name,
4875 p_pkg_name => G_PKG_NAME,
4876 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
4877 x_msg_count => x_msg_count,
4878 x_msg_data => x_msg_data,
4879 p_api_type => g_api_type);
4880 WHEN OTHERS THEN
4881 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4882 p_api_name => l_api_name,
4883 p_pkg_name => G_PKG_NAME,
4884 p_exc_name => 'OTHERS',
4885 x_msg_count => x_msg_count,
4886 x_msg_data => x_msg_data,
4887 p_api_type => g_api_type);
4888 END get_lease_rate_factors;
4889
4890 -- API which accepts the standard rate template version id and
4891 -- returns all the SRT details !
4892 PROCEDURE get_standard_rates(
4893 p_api_version IN NUMBER,
4894 p_init_msg_list IN VARCHAR2,
4895 x_return_status OUT NOCOPY VARCHAR2,
4896 x_msg_count OUT NOCOPY NUMBER,
4897 x_msg_data OUT NOCOPY VARCHAR2,
4898 p_srt_id IN NUMBER, -- Version ID
4899 p_start_date IN DATE,
4900 x_srt_details OUT NOCOPY srt_details_rec_type)
4901 IS
4902 -- Cursor Declarations
4903 CURSOR srt_details_csr(
4904 p_srt_version_id IN NUMBER,
4905 p_date IN DATE )
4906 IS
4907 SELECT hdr.std_rate_tmpl_id srt_header_id,
4908 ver.std_rate_tmpl_ver_id srt_version_id,
4909 hdr.template_name template_name,
4910 hdr.currency_code currency_code,
4911 ver.version_number version_number,
4912 ver.effective_from_date effective_from_date,
4913 ver.effective_to_date effective_to_date,
4914 ver.sts_code sts_code,
4915 hdr.pricing_engine_code pricing_engine_code,
4916 hdr.rate_type_code rate_type_code,
4917 ver.srt_rate srt_rate,
4918 hdr.index_id index_id,
4919 ver.spread spread,
4920 ver.day_convention_code day_convention_code,
4921 hdr.frequency_code frequency_code,
4922 ver.adj_mat_version_id adj_mat_version_id,
4923 ver.min_adj_rate min_adj_rate,
4924 ver.max_adj_rate max_adj_rate
4925 FROM okl_fe_std_rt_tmp_v hdr,
4926 okl_fe_std_rt_tmp_vers ver
4927 WHERE ver.std_rate_tmpl_ver_id = p_srt_version_id AND
4928 hdr.std_rate_tmpl_id = ver.std_rate_tmpl_id AND
4929 ver.effective_from_date <= p_date AND
4930 nvl(ver.effective_to_date, p_date) >= p_date;
4931
4932 -- Fetch the Rate from the if the rate_type_code is INDEX.
4933 Cursor srt_index_rate_csr(
4934 p_srt_header_id IN NUMBER,
4935 p_date IN DATE)
4936 IS
4937 SELECT indx.value srt_rate
4938 FROM okl_fe_std_rt_tmp_all_b hdr,
4939 okl_index_values indx
4940 WHERE hdr.std_rate_tmpl_id = p_srt_header_id
4941 AND hdr.index_id = indx.idx_id
4942 AND p_date BETWEEN indx.datetime_valid AND NVL(indx.datetime_invalid,p_date+1);
4943 -- Local Variables
4944 l_api_version CONSTANT NUMBER DEFAULT 1.0;
4945 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_standard_rates';
4946 l_return_status VARCHAR2(1);
4947 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
4948 || G_PKG_NAME || '.' || UPPER(l_api_name);
4949 l_debug_enabled VARCHAR2(10);
4950 is_debug_procedure_on BOOLEAN;
4951 is_debug_statement_on BOOLEAN;
4952 srt_details srt_details_rec_type;
4953 BEGIN
4954 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4955 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
4956 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
4957
4958 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4959 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
4960 -- check for logging on STATEMENT level
4961 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
4962 -- Call START_ACTIVITY to create savepoint, check compatibility
4963 -- and initialize message list
4964 l_return_status := OKL_API.START_ACTIVITY(
4965 p_api_name => l_api_name,
4966 p_pkg_name => G_PKG_NAME,
4967 p_init_msg_list => p_init_msg_list,
4968 l_api_version => l_api_version,
4969 p_api_version => p_api_version,
4970 p_api_type => g_api_type,
4971 x_return_status => x_return_status);
4972 --Check if activity started successfully
4973 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4974 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4975 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4976 RAISE OKL_API.G_EXCEPTION_ERROR;
4977 END IF;
4978 IF p_start_date IS NULL
4979 THEN
4980 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4981 'Start Date is null !! ' );
4982 OKL_API.set_message(
4983 G_APP_NAME,
4984 OKL_API.G_INVALID_VALUE,
4985 OKL_API.G_COL_NAME_TOKEN,
4986 'EXPECTED START DATE');
4987 RAISE OKL_API.G_EXCEPTION_ERROR;
4988 END IF;
4989 IF p_srt_id IS NULL
4990 THEN
4991 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4992 'Standard Rate Template ID is required !! ' );
4993 OKL_API.set_message(
4994 G_APP_NAME,
4995 OKL_API.G_REQUIRED_VALUE,
4996 OKL_API.G_COL_NAME_TOKEN,
4997 'STANDARD RATE TEMPLATE ID');
4998 RAISE OKL_API.G_EXCEPTION_ERROR;
4999 END IF;
5000 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5001 ': p_srt_id= ' || p_srt_id );
5002 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5003 ': p_start_date= '|| p_start_date );
5004
5005 l_return_status := OKL_API.G_RET_STS_ERROR;
5006 FOR t_rec IN srt_details_csr(
5007 p_srt_version_id => p_srt_id,
5008 p_date => p_start_date )
5009 LOOP
5010 srt_details.srt_header_id := t_rec.srt_header_id;
5011 srt_details.srt_version_id := t_rec.srt_version_id;
5012 srt_details.template_name := t_rec.template_name;
5013 srt_details.currency_code := t_rec.currency_code;
5014 srt_details.version_number := t_rec.version_number;
5015 srt_details.effective_from_date := t_rec.effective_from_date;
5016 srt_details.effective_to_date := t_rec.effective_to_date;
5017 srt_details.sts_code := t_rec.sts_code;
5018 srt_details.pricing_engine_code := t_rec.pricing_engine_code;
5019 srt_details.rate_type_code := t_rec.rate_type_code;
5020 srt_details.srt_rate := t_rec.srt_rate;
5021 srt_details.index_id := t_rec.index_id;
5022 srt_details.spread := t_rec.spread;
5023 srt_details.day_convention_code := t_rec.day_convention_code;
5024 srt_details.frequency_code := t_rec.frequency_code;
5025 srt_details.adj_mat_version_id := t_rec.adj_mat_version_id;
5026 srt_details.min_adj_rate := t_rec.min_adj_rate;
5027 srt_details.max_adj_rate := t_rec.max_adj_rate;
5028 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5029 'Successfully fetched the SRT Header n Version Details ' );
5030 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5031 'SRT Rate Type Code | Min Adj Rate | Max. Adj Rate | Rate | Spread ');
5032 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5033 srt_details.rate_type_code || ' | ' || srt_details.min_adj_rate
5034 || ' | ' || srt_details.max_adj_rate || ' | ' || srt_details.srt_rate || ' | ' || srt_details.spread);
5035
5036 -- Using l_return_status as flag
5037 l_return_status := OKL_API.G_RET_STS_SUCCESS;
5038 END LOOP; -- srt_details_csr
5039 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5040 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5041 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5042 RAISE OKL_API.G_EXCEPTION_ERROR;
5043 END IF;
5044
5045 IF srt_details.rate_type_code = G_QQ_SRT_RATE_TYPE
5046 THEN
5047 -- Initialize l_return_status to 'E'
5048 l_return_status := OKL_API.G_RET_STS_ERROR;
5049 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5050 ': p_srt_header_id = ' || srt_details.srt_header_id );
5051 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5052 ': p_start_date=' || p_start_date );
5053 FOR t_rec IN srt_index_rate_csr(
5054 p_srt_header_id => srt_details.srt_header_id,
5055 p_date => p_start_date)
5056 LOOP
5057 srt_details.srt_rate := t_rec.srt_rate;
5058 -- Using l_return_status as flag
5059 l_return_status := OKL_API.G_RET_STS_SUCCESS;
5060 END LOOP; -- srt_index_rate_csr
5061 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5062 ': After srt_index_rate_csr ' || l_return_status );
5063 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5064 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5065 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5066 RAISE OKL_API.G_EXCEPTION_ERROR;
5067 END IF;
5068 END IF; -- IF srt_details.rate_type_code = 'INDEX'
5069 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5070 'Rate from the SRT ' || srt_details.srt_rate );
5071 -- Setting up the return variables ..
5072 x_srt_details := srt_details;
5073 x_return_status := OKL_API.G_RET_STS_SUCCESS;
5074 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
5075 x_msg_data => x_msg_data);
5076 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
5077 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
5078 EXCEPTION
5079 WHEN OKL_API.G_EXCEPTION_ERROR THEN
5080 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5081 p_api_name => l_api_name,
5082 p_pkg_name => G_PKG_NAME,
5083 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
5084 x_msg_count => x_msg_count,
5085 x_msg_data => x_msg_data,
5086 p_api_type => g_api_type);
5087 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
5088 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5089 p_api_name => l_api_name,
5090 p_pkg_name => G_PKG_NAME,
5091 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
5092 x_msg_count => x_msg_count,
5093 x_msg_data => x_msg_data,
5094 p_api_type => g_api_type);
5095 WHEN OTHERS THEN
5096 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5097 p_api_name => l_api_name,
5098 p_pkg_name => G_PKG_NAME,
5099 p_exc_name => 'OTHERS',
5100 x_msg_count => x_msg_count,
5101 x_msg_data => x_msg_data,
5102 p_api_type => g_api_type);
5103 END get_standard_rates;
5104
5105 PROCEDURE compute_bk_yield(
5106 p_api_version IN NUMBER,
5107 p_init_msg_list IN VARCHAR2,
5108 x_return_status OUT NOCOPY VARCHAR2,
5109 x_msg_count OUT NOCOPY NUMBER,
5110 x_msg_data OUT NOCOPY VARCHAR2,
5111 p_start_date IN DATE,
5112 p_day_count_method IN VARCHAR2,
5113 p_pricing_method IN VARCHAR2,
5114 p_initial_guess IN NUMBER,
5115 p_term IN NUMBER,
5116 px_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type,
5117 x_bk_yield IN OUT NOCOPY NUMBER,
5118 x_termination_tbl OUT NOCOPY cash_inflows_tbl_type,
5119 x_pre_tax_inc_tbl OUT NOCOPY cash_inflows_tbl_type
5120 -- Parameters for Prospective Rebooking
5121 ,p_prosp_rebook_flag IN VARCHAR2
5122 ,p_rebook_date IN DATE
5123 ,p_orig_income_streams IN cash_inflows_tbl_type
5124 )
5125 IS
5126 -- Local Variables
5127 l_api_version CONSTANT NUMBER DEFAULT 1.0;
5128 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_bk_yield';
5129 l_return_status VARCHAR2(1);
5130 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
5131 || G_PKG_NAME || '.' || UPPER(l_api_name);
5132 l_debug_enabled VARCHAR2(10);
5133 is_debug_procedure_on BOOLEAN;
5134 is_debug_statement_on BOOLEAN;
5135 l_start_date DATE;
5136 l_end_date DATE;
5137 i NUMBER;
5138 p NUMBER;
5139 t NUMBER;
5140 m NUMBER;
5141 l_days_in_month VARCHAR2(30);
5142 l_days_in_year VARCHAR2(30);
5143 cf_index NUMBER;
5144 l_se_date DATE;
5145 res_index NUMBER;
5146 l_days NUMBER;
5147 l_tmp_interest NUMBER;
5148 l_is_arrears VARCHAR2(1);
5149 l_is_res_arrears VARCHAR2(1);
5150 l_cf_inflows cash_inflows_tbl_type;
5151 l_residuals cash_inflows_tbl_type;
5152 l_termination_val_tbl cash_inflows_tbl_type;
5153 l_pre_tax_income_tbl cash_inflows_tbl_type;
5154 l_investment NUMBER := 0;
5155 l_residual_amount NUMBER := 0;
5156 l_termination_val NUMBER := 0;
5157 n_iterations NUMBER;
5158 l_k_start_date DATE;
5159 l_k_end_date DATE;
5160 l_k_se_date DATE;
5161 l_term_complete VARCHAR2(1) := 'N';
5162 l_crossed_zero VARCHAR2(1) := 'N';
5163 l_diff NUMBER;
5164 l_prev_diff NUMBER;
5165 l_prev_diff_sign NUMBER;
5166 l_prev_incr_sign NUMBER;
5167 l_positive_diff NUMBER;
5168 l_negative_diff NUMBER;
5169 l_bk_yield NUMBER;
5170 l_prev_bk_yeild NUMBER;
5171 l_increment NUMBER := 0.1;
5172 l_abs_incr NUMBER := 0;
5173 l_positive_diff_bk_yeild NUMBER := 0;
5174 l_negative_diff_bk_yeild NUMBER := 0;
5175 l_days_per_annum NUMBER := 0;
5176 -- Prospective Rebooking Enhancement
5177 l_prosp_rebook_flag VARCHAR2(30);
5178 l_last_accrued_date DATE;
5179 l_eff_investment_for_prb NUMBER;
5180 p_index NUMBER; -- Pre-Tax Income Stream Index
5181 t_index NUMBER; -- Termination Value Stream Index
5182 cf_index_start_prb NUMBER;
5183 l_opening_bal NUMBER;
5184 l_ending_bal NUMBER;
5185 l_period_start_date DATE;
5186 l_period_end_date DATE;
5187 l_sum_rent_in_curr_month NUMBER;
5188 l_orig_income_in_curr_month NUMBER;
5189 BEGIN
5190 l_return_status := OKL_API.G_RET_STS_SUCCESS;
5191 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
5192 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
5193 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
5194 'begin debug OKLRPIUB.pls call '|| LOWER(l_api_name));
5195 -- check for logging on STATEMENT level
5196 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
5197 -- Call START_ACTIVITY to create savepoint, check compatibility
5198 -- and initialize message list
5199 l_return_status := OKL_API.START_ACTIVITY(
5200 p_api_name => l_api_name,
5201 p_pkg_name => G_PKG_NAME,
5202 p_init_msg_list => p_init_msg_list,
5203 l_api_version => l_api_version,
5204 p_api_version => p_api_version,
5205 p_api_type => g_api_type,
5206 x_return_status => x_return_status);
5207 --Check if activity started successfully
5208 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5209 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5210 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5211 RAISE OKL_API.G_EXCEPTION_ERROR;
5212 END IF;
5213 -- Actual logic Begins here
5214 -- Validate the input parameters
5215 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5216 'COMPUTE_BK_YIELD -------------- Start !! ' );
5217 get_days_in_year_and_month(
5218 p_day_count_method => p_day_count_method,
5219 x_days_in_month => l_days_in_month,
5220 x_days_in_year => l_days_in_year,
5221 x_return_status => l_return_status);
5222 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5223 'After get_day_count_method ' || l_return_status);
5224 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5225 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5226 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5227 RAISE OKL_API.G_EXCEPTION_ERROR;
5228 END IF;
5229
5230 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5231 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
5232 IF p_start_date IS NULL OR
5233 p_term IS NULL OR p_term <= 0 OR
5234 px_pricing_parameter_rec.cash_inflows IS NULL OR
5235 px_pricing_parameter_rec.cash_inflows.COUNT <= 0 OR
5236 px_pricing_parameter_rec.line_end_date IS NULL
5237 THEN
5238 -- Show the error message and
5239 RAISE OKL_API.G_EXCEPTION_ERROR;
5240 END IF;
5241 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5242 'Input Parameters p_start_date, p_end_date, count(cash_inflows) = '
5243 || p_start_date || ',' || px_pricing_parameter_rec.line_end_date || ',' ||
5244 px_pricing_parameter_rec.cash_inflows.COUNT );
5245 -- Dealing with the Cash Inflows
5246 l_start_date := p_start_date;
5247 cf_index := 1;
5248 i := px_pricing_parameter_rec.cash_inflows.FIRST;
5249 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5250 'Date | Amount | Arrears | Purpose ' );
5251 WHILE i <= px_pricing_parameter_rec.cash_inflows.LAST
5252 LOOP
5253 l_cf_inflows(cf_index) := px_pricing_parameter_rec.cash_inflows(i);
5254 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5255 l_cf_inflows(cf_index).cf_date
5256 || ' | ' || l_cf_inflows(cf_index).cf_amount || ' | ' ||
5257 l_cf_inflows(cf_index).is_arrears || ' | ' ||
5258 l_cf_inflows(cf_index).cf_purpose );
5259 -- Increment the indexes
5260 i := px_pricing_parameter_rec.cash_inflows.NEXT( i );
5261 cf_index := cf_index + 1;
5262 END LOOP; -- WHILE cf_index <= l_cf_inflows.LAST
5263 -- Dealing with the Residual Inflows now .. :-;
5264 l_start_date := p_start_date;
5265 l_residual_amount := 0;
5266 res_index := 1;
5267 i := px_pricing_parameter_rec.residual_inflows.FIRST;
5268 WHILE i <= px_pricing_parameter_rec.residual_inflows.LAST
5269 LOOP
5270 l_residuals(res_index) := px_pricing_parameter_rec.residual_inflows(i);
5271 -- Store the total Residual Amount
5272 l_residual_amount := l_residual_amount + nvl( l_residuals(res_index).cf_amount, 0 );
5273 -- cf_amount, cf_date, is_stub, is_arrears, cf_dpp, cf_ppy, cf_days,( cf_rate ?? )
5274 -- would have been already populated.
5275 -- Increment the indexes
5276 i := l_residuals.NEXT( i );
5277 res_index := res_index + 1;
5278 END LOOP; -- WHILE cf_index <= l_cf_inflows.LAST
5279 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5280 'Total Residual Amount ' || round(l_residual_amount , 4) );
5281 -- Calculation of the Invested amount
5282 -- Investment = Item Original Cost ( Financed amount ) - Subsidy - Down Payment - Trade In;
5283 l_investment := nvl( px_pricing_parameter_rec.financed_amount, 0 ) -
5284 nvl( px_pricing_parameter_rec.subsidy, 0 ) -
5285 nvl( px_pricing_parameter_rec.down_payment, 0 ) -
5286 nvl( px_pricing_parameter_rec.trade_in, 0 );
5287 IF l_investment <= 0
5288 THEN
5289 -- Initial Investment itself cant be negative !!
5290 RAISE OKL_API.G_EXCEPTION_ERROR;
5291 END IF; -- IF l_investment ..
5292
5293 -- Initialize the things
5294 n_iterations := 0;
5295 l_k_start_date := p_start_date;
5296 l_bk_yield := nvl( p_initial_guess, 0 );
5297 l_increment := 0.1;
5298 -- Bug: Instead of assuming that the first cash flow is always RENT
5299 -- Loop on the cash inflows to fetch the first Rent Cash inflow and
5300 -- use the arrears flag and store it ..
5301 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5302 'Identifying the first Rent Stream Element to fetch the Advance/Arrears Flag ');
5303 FOR i IN l_cf_inflows.FIRST .. l_cf_inflows.LAST
5304 LOOP
5305 IF l_cf_inflows(i).cf_purpose = 'RENT'
5306 THEN
5307 l_is_arrears := l_cf_inflows(i).is_arrears;
5308 EXIT;
5309 END IF;
5310 END LOOP;
5311 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5312 'Advance/Arrears Flag for Rents Considered: ' || l_is_arrears );
5313 -- Fetch the end date
5314 /*
5315 okl_stream_generator_pvt.add_months_new(
5316 p_start_date => l_start_date,
5317 p_months_after => p_term,
5318 x_date => l_k_end_date,
5319 x_return_status => l_return_status);
5320 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5321 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5322 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5323 RAISE OKL_API.G_EXCEPTION_ERROR;
5324 END IF;
5325 l_k_end_date := l_k_end_date - 1;
5326 */
5327 -- Assume the line end date as passed in the .line_end_date
5328 l_k_end_date := px_pricing_parameter_rec.line_end_date;
5329
5330 -- Modifications for the Prospective Rebooking Enhancement
5331 l_prosp_rebook_flag := NVL(p_prosp_rebook_flag, 'N' );
5332 -- Validating the Prospective Rebooking flag
5333 IF l_prosp_rebook_flag= 'Y'
5334 THEN
5335 -- If Rebook Effective Date is on the Contract Start Date itself
5336 -- then its a Retrospective Rebooking only
5337 IF TRUNC(p_rebook_date) = TRUNC(p_start_date)
5338 THEN
5339 -- Contract Start Date <> Rebook Revision Date
5340 l_prosp_rebook_flag := 'N';
5341 END IF;
5342 -- Step: Derieve the Last Accrued Date
5343 -- Rule 1: Last Accrual Date is the date of the immediately preceding
5344 -- Lease/Interest Income stream element. This is the previous
5345 -- calendar month end.
5346 l_last_accrued_date := TRUNC(LAST_DAY( ADD_MONTHS(p_rebook_date, -1)));
5347 IF l_last_accrued_date < TRUNC(p_start_date)
5348 THEN
5349 -- Last Accrued Date is before the Contract Start Date itself
5350 -- Hence, rebooking should be Retrospective.
5351 l_prosp_rebook_flag := 'N';
5352 END IF;
5353 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5354 'Line Start Date= ' || p_start_date || ' | Rebook Date= ' || p_rebook_date ||
5355 ' | Last Accrued Date= ' || l_last_accrued_date ||
5356 ' | l_prosp_rebook_flag= ' || l_prosp_rebook_flag );
5357 END IF; -- IF l_prosp_rebook_flag= 'Y'
5358
5359 IF l_prosp_rebook_flag= 'Y' -- If Still its a Prospective Rebooking
5360 THEN
5361 -- Start Looping on for the Booking Yield from l_last_accrued_date + 1
5362 l_k_start_date := l_last_accrued_date + 1;
5363 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5364 'Rebook Date | Last Accrued Date | Loop Start Date' );
5365 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5366 p_rebook_date || ' | ' || l_last_accrued_date || ' | ' || l_k_start_date );
5367
5368 -- Derieve the Cash Flow Index after the Last Accrued Date
5369 IF l_cf_inflows.COUNT > 0
5370 THEN
5371 cf_index_start_prb := 0; -- p_orig_rent_streams.FIRST;
5372 FOR i in l_cf_inflows.FIRST .. l_cf_inflows.LAST
5373 LOOP
5374 IF l_cf_inflows(i).cf_date <= l_last_accrued_date
5375 THEN
5376 cf_index_start_prb := i;
5377 END IF;
5378 END LOOP;
5379 -- Increment the Cash flow Prospective Rebooking Index
5380 -- as cf_index_start_prb stored the last element index number, which is before
5381 -- the last accrued date
5382 cf_index_start_prb := cf_index_start_prb + 1;
5383 END IF; -- IF p_orig_rent_streams.COUNT > 0
5384 -- Derieve the Effective Investment on the Last Accrued Date + 1
5385 t_index := 1;
5386 l_opening_bal := l_investment;
5387 l_period_start_date := TRUNC(p_start_date);
5388 l_period_end_date := TRUNC( LAST_DAY( l_period_start_date) );
5389 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5390 'Period Start | Period End | Opening Bal | Interest Amount | Rent Amount | Ending Balance ' );
5391
5392 WHILE l_period_start_date <= l_last_accrued_date
5393 LOOP
5394 -- Find sum[rents of revised asset], till the end of this month
5395 l_sum_rent_in_curr_month := 0;
5396 FOR r_index IN l_cf_inflows.FIRST .. l_cf_inflows.LAST
5397 LOOP
5398 IF LAST_DAY(l_cf_inflows(r_index).cf_date) = l_period_end_date
5399 THEN
5400 -- Rent Payment falls in the Current Month, so sum the Rent
5401 l_sum_rent_in_curr_month := l_sum_rent_in_curr_month +
5402 l_cf_inflows(r_index).cf_amount;
5403 END IF;
5404 END LOOP;
5405 -- Find the Pre-Tax Income Amount for this Period from Original Contract
5406 l_orig_income_in_curr_month := 0;
5407 FOR in_index IN p_orig_income_streams.FIRST .. p_orig_income_streams.LAST
5408 LOOP
5409 IF LAST_DAY( p_orig_income_streams(in_index).cf_date) =
5410 l_period_end_date
5411 THEN
5412 -- Interest for the current period
5413 l_orig_income_in_curr_month := p_orig_income_streams(in_index).cf_amount;
5414 END IF;
5415 END LOOP;
5416 -- Calculate the Termination Value at the end of the Current Period
5417 l_ending_bal := l_opening_bal - l_sum_rent_in_curr_month + l_orig_income_in_curr_month;
5418 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5419 l_period_start_date || ' | ' ||
5420 l_period_end_date || ' | ' ||
5421 l_opening_bal || ' | ' ||
5422 l_orig_income_in_curr_month|| ' | ' ||
5423 l_sum_rent_in_curr_month || ' | ' ||
5424 l_ending_bal );
5425 -- Store the Ending Balance as the Termination Value at the end of the period
5426 x_termination_tbl(t_index).cf_date := l_period_end_date;
5427 x_termination_tbl(t_index).cf_amount := l_ending_bal;
5428 x_termination_tbl(t_index).line_number := t_index;
5429 -- Increment the p_index
5430 t_index := t_index + 1;
5431 -- Re-intialize to proceed for the next iteration
5432 l_opening_bal := l_ending_bal;
5433 l_period_start_date := l_period_end_date + 1;
5434 l_period_end_date := TRUNC( LAST_DAY( l_period_start_date) );
5435 -- Store the Last Effective Balance as the Effective Balance
5436 l_eff_investment_for_prb := NVL(l_ending_bal, 0);
5437 END LOOP; -- WHILE l_period_start_date <= l_last_accrued_date
5438 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5439 'Effective Investment as on the Last Accrued Date = ' || l_eff_investment_for_prb );
5440 ELSE
5441 -- Non-Prospective Rebooking Logic
5442 -- Effective Investment will be nothing but the l_investment
5443 l_eff_investment_for_prb := l_investment;
5444 cf_index_start_prb := 1;
5445 END IF; -- IF NVL( p_prosp_rebook_flag, 'N' ) = 'Y'
5446 -- If the current flow is not a prospective Rebooking
5447 -- use l_eff_investment_for_prb as l_investment
5448 -- Actual Logic for calculation of the Booking Yield.
5449 LOOP
5450 -- Incrementing the Iteration Index
5451 n_iterations := n_iterations + 1;
5452 -- Initialize the things
5453 l_pre_tax_income_tbl.DELETE;
5454 l_termination_val_tbl.DELETE;
5455 l_termination_val := l_eff_investment_for_prb; -- Effective Investment
5456 cf_index := cf_index_start_prb; -- Consider inflows only after the Last Accrued Date
5457 p := 1;
5458 t := 1;
5459 l_term_complete := 'N';
5460 l_crossed_zero := 'N';
5461 l_start_date := l_k_start_date;
5462 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5463 'Iteration # ' || n_iterations );
5464 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5465 'Booking |-Investment-|-Residual-|-Termination-|--------------|--------------|');
5466 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5467 '-Yield--|------------|--Value---|-----Value---|l_k_start_date| l_k_end_date |');
5468 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5469 round( l_bk_yield, 4 ) || '|' || round(l_eff_investment_for_prb , 4) || '|' || round(l_residual_amount , 4)
5470 || '|' || round(l_termination_val , 4) || '|' || l_k_start_date || '|' || l_k_end_date);
5471 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5472 'P/M | Bk. Yield | Arrears | Days/Annum | Start Date | End Date | Days | Interest | Payment Amount | Termination value ' );
5473 -- Main while loop ... !!! Loops until the term completes ;-)
5474 WHILE l_term_complete = 'N'
5475 LOOP
5476 -- There exists a possiblity during Prospective Rebooking that
5477 -- No Cashflows after the Last Accrued Date and hence, need to skip the following
5478 -- section and continue as is like all Payments are processed !
5479 -- Example: Prospective Rebooking: Yes
5480 -- Contract Start Date: 10-Jan-2009, One Asset, with One Annual Advance Payment
5481 -- and Rebook Happened on 15-Feb-2009
5482 -- As there are no payments till the end of the contract, we need to skip this section
5483 IF cf_index <= l_cf_inflows.LAST AND
5484 l_cf_inflows.exists(cf_index)
5485 THEN
5486 IF LAST_DAY( TRUNC(l_start_date) ) <>
5487 LAST_DAY( TRUNC(l_cf_inflows(cf_index).cf_date ) )
5488 THEN
5489 -- Handling till the end of the month ..
5490 -- Period: ( l_start_date, LAST_DAY(l_start_day) ]
5491 l_end_date := LAST_DAY( l_start_date );
5492 l_days := get_day_count(
5493 p_days_in_month => l_days_in_month,
5494 p_days_in_year => l_days_in_year,
5495 p_start_date => l_start_date,
5496 p_end_date => l_end_date,
5497 p_arrears => 'Y', -- Calculate until the end of the month !
5498 x_return_status => l_return_status);
5499 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5500 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5501 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5502 RAISE OKL_API.G_EXCEPTION_ERROR;
5503 END IF;
5504 -- Case when the start date and end date are as follows:
5505 -- Start Date = 31st of the Month
5506 -- End Date = 31st of the Month
5507 -- Day Count returns 0, but ..
5508 -- Say, when Payments are received every month end 31st in Advance
5509 -- we need to calculate the 1 day interest from 31st to 31st itself
5510 IF TO_CHAR( l_start_date, 'DD' ) = 31 -- RGOOTY: 8935347
5511 AND TO_CHAR( l_end_date, 'DD' ) = 31
5512 AND l_is_arrears = 'N' -- Advance Payments
5513 THEN
5514 -- Case when, Advance Payments and is being received on the month end
5515 l_days := 1;
5516 END IF;
5517 l_days_per_annum := get_days_per_annum(
5518 p_day_convention => p_day_count_method,
5519 p_start_date => p_start_date,
5520 p_cash_inflow_date => l_start_date,
5521 x_return_status => l_return_status );
5522 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5523 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5524 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5525 RAISE OKL_API.G_EXCEPTION_ERROR;
5526 END IF;
5527 l_tmp_interest := l_termination_val * l_days * l_bk_yield / l_days_per_annum;
5528 l_termination_val := l_termination_val + l_tmp_interest;
5529 l_termination_val_tbl(t).cf_amount := l_termination_val;
5530 -- Making the l_se_date to LAST_DAY(l_start_date)
5531 l_se_date := LAST_DAY(l_start_date);
5532 IF ( nvl(p_day_count_method, 'THIRTY') = 'THIRTY' AND
5533 TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' ) OR
5534 ( nvl(p_day_count_method, 'THIRTY' ) = '365' AND
5535 TO_CHAR(LAST_DAY(l_se_date), 'DD' ) = '29' AND
5536 TO_CHAR(l_se_date, 'MON' ) = 'FEB' )
5537 THEN
5538 l_se_date := l_se_date - 1;
5539 END IF;
5540 l_termination_val_tbl(t).cf_date := LAST_DAY(l_se_date);
5541 t := t + 1;
5542 -- If l_start_date = l_k_start_date OR
5543 -- l_start_date is first of the month then no need to accumulate the pretax income
5544 -- else accumulate the pre-tax income.
5545 IF TRUNC(l_start_date) = TRUNC(l_k_start_date) OR
5546 TO_NUMBER(TO_CHAR(l_start_date, 'DD' )) = 1
5547 THEN
5548 -- No need to accumulate
5549 l_pre_tax_income_tbl(p).cf_amount := l_tmp_interest;
5550 ELSE
5551 -- Accumulate
5552 l_pre_tax_income_tbl(p).cf_amount := nvl( l_pre_tax_income_tbl(p).cf_amount , 0)
5553 + l_tmp_interest;
5554 END IF;
5555 l_pre_tax_income_tbl(p).cf_date := l_se_date;
5556 p := p + 1;
5557 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5558 'M | ' || round( l_bk_yield, 4 ) || ' | ' || 'Y' || ' | ' || l_days_per_annum
5559 || ' | ' || l_start_date || ' | ' || l_end_date || ' | ' || l_days
5560 || ' | ' || round( l_tmp_interest, 4 ) || ' | - | ' || round(l_termination_val, 4 ) );
5561 -- Increment the things
5562 -- Change the start date to first of next month
5563 l_start_date := l_end_date + 1;
5564 ELSE
5565 -- Current month is having the payment ..
5566 -- Handling the period from ( l_start_date , l_cf_inflows(cf_index).cf_date )
5567 l_end_date := l_cf_inflows(cf_index).cf_date;
5568 l_days := get_day_count(
5569 p_days_in_month => l_days_in_month,
5570 p_days_in_year => l_days_in_year,
5571 p_start_date => l_start_date,
5572 p_end_date => l_end_date,
5573 p_arrears => l_cf_inflows(cf_index).is_arrears,
5574 x_return_status => l_return_status);
5575 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5576 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5577 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5578 RAISE OKL_API.G_EXCEPTION_ERROR;
5579 END IF;
5580 -- Based on the day convention, get the days/annum
5581 l_days_per_annum := get_days_per_annum(
5582 p_day_convention => p_day_count_method,
5583 p_start_date => p_start_date,
5584 p_cash_inflow_date => l_start_date,
5585 x_return_status => l_return_status );
5586 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5587 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5588 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5589 RAISE OKL_API.G_EXCEPTION_ERROR;
5590 END IF;
5591 -- Calculation of Interest
5592 l_tmp_interest := l_termination_val * l_days * l_bk_yield / l_days_per_annum;
5593 -- Termination value streams assignments
5594 l_termination_val := l_termination_val + l_tmp_interest;
5595 l_termination_val := l_termination_val - l_cf_inflows(cf_index).cf_amount;
5596 l_termination_val_tbl(t).cf_amount := l_termination_val;
5597 l_termination_val_tbl(t).cf_date := l_cf_inflows(cf_index).cf_date;
5598 -- Pre_tax streams assignments
5599 t := t + 1;
5600 IF l_pre_tax_income_tbl.exists(p)
5601 THEN
5602 l_pre_tax_income_tbl(p).cf_amount := nvl( l_pre_tax_income_tbl(p).cf_amount, 0 ) +
5603 l_tmp_interest;
5604 ELSE
5605 l_pre_tax_income_tbl(p).cf_amount := l_tmp_interest;
5606 END IF;
5607 -- Date for the Pre-Tax Income will be put above
5608 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5609 'P | ' || round( l_bk_yield, 4 ) || ' | ' || l_cf_inflows(cf_index).is_arrears || ' | ' || l_days_per_annum
5610 || ' | ' || l_start_date || ' | ' || l_end_date || ' | ' || l_days
5611 || ' | ' || round( l_tmp_interest, 4 ) || ' | ' ||
5612 round(l_cf_inflows(cf_index).cf_amount, 4) || ' | ' || round(l_termination_val, 4 ) );
5613 -- Increment the cf_index
5614 l_start_date := l_cf_inflows(cf_index).cf_date;
5615 IF l_cf_inflows(cf_index).is_arrears = 'Y' AND
5616 -- TRUNC(l_start_date) <> TRUNC(LAST_DAY( l_start_date)) AND
5617 l_start_date < l_k_end_date
5618 THEN
5619 l_start_date := l_start_date + 1;
5620 END IF;
5621 -- If the Current Period End Date and Next Period Start Date
5622 -- doesnot fall in the same month, then increment the Pre-Tax Income table index
5623 IF TRUNC(LAST_DAY(l_start_date)) > TRUNC(LAST_DAY(l_end_date))
5624 THEN
5625 -- Handling the Case when l_end_date = Calender end of the month
5626 -- and next payment starts only after the next month
5627 l_pre_tax_income_tbl(p).cf_date := l_end_date;
5628 p := p + 1;
5629 END IF;
5630 cf_index := cf_index + 1;
5631 END IF;
5632 END IF; -- If cf_index <= l_cf_inflows.LAST
5633 -- Check whether we have crossed the Stream Element dates or not???
5634 IF cf_index > l_cf_inflows.LAST
5635 THEN
5636 m := 1;
5637 -- Last Cash Inflow
5638 LOOP
5639 IF LAST_DAY(l_start_date) <> LAST_DAY(l_k_end_date) THEN
5640 l_end_date := LAST_DAY(l_start_date);
5641 ELSE
5642 l_end_date := l_k_end_date;
5643 END IF;
5644 -- Residual Amount is always considered as inflow at the
5645 -- very last momment of the Contract
5646 l_is_res_arrears := 'Y';
5647 -- But, In case, when Last Stream Element Date = Contract End Date
5648 -- and Payments are arrears, then Day Count should be equal to zero.
5649 IF l_start_date = l_end_date AND
5650 l_end_date = l_k_end_date AND
5651 l_is_arrears = 'Y'
5652 THEN
5653 l_is_res_arrears := 'N';
5654 END IF;
5655 l_days := get_day_count(
5656 p_days_in_month => l_days_in_month,
5657 p_days_in_year => l_days_in_year,
5658 p_start_date => l_start_date,
5659 p_end_date => l_end_date,
5660 p_arrears => l_is_res_arrears, -- Calculate until the end of the month/Contract End Date
5661 x_return_status => l_return_status);
5662 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5663 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5664 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5665 RAISE OKL_API.G_EXCEPTION_ERROR;
5666 END IF;
5667 -- But, In case, when Last Stream Element Date = Contract End Date
5668 -- and Payments are arrears, then Day Count should be equal to zero.
5669 IF TO_CHAR( p_start_date, 'DD') = 31 AND -- Contract Starting on 31st of Month
5670 l_end_date = l_k_end_date AND -- Handling the Last Residual Stream
5671 TO_CHAR(l_end_date, 'DD' ) = 30 AND -- Residual is coming on months 30 end
5672 TO_CHAR(l_start_date, 'DD' ) = 1 -- Last Handled Stream element was 31st
5673 THEN
5674 l_days := l_days - 1; -- Dont include the last day of the contract
5675 END IF;
5676 -- Case when the start date and end date are as follows:
5677 -- Start Date = 31st of the Month
5678 -- End Date = 31st of the Month
5679 -- Day Count returns 0, but ..
5680 -- Say, when Payments are received every month end 31st in Advance
5681 -- we need to calculate the 1 day interest from 31st to 31st itself
5682 IF TO_CHAR( l_start_date, 'DD' ) = 31 -- RGOOTY: 8935347
5683 AND TO_CHAR( l_end_date, 'DD' ) = 31
5684 AND l_is_arrears = 'N' -- Advance Payments
5685 THEN
5686 -- Case when, Advance Payments and is being received on the month end
5687 l_days := 1;
5688 END IF;
5689 --shagarg commented for bug 6604271
5690 /* IF l_is_arrears= 'Y' AND m = 1 AND l_days >= 1
5691 THEN
5692 l_days := l_days - 1;
5693 END IF;*/
5694 --shagarg bug 6604271 end
5695 -- Get days/annum based on the day count method
5696 l_days_per_annum := get_days_per_annum(
5697 p_day_convention => p_day_count_method,
5698 p_start_date => p_start_date,
5699 p_cash_inflow_date => l_start_date,
5700 x_return_status => l_return_status );
5701 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5702 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5703 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5704 RAISE OKL_API.G_EXCEPTION_ERROR;
5705 END IF;
5706 -- Interest Calculation
5707 l_tmp_interest := l_termination_val * l_days * l_bk_yield / l_days_per_annum;
5708 -- Termination value streams assignment
5709 l_termination_val := l_termination_val + l_tmp_interest;
5710 -- If the current month is the first one .. !
5711 IF m = 1
5712 THEN
5713 -- Accumulate the Pre-Tax Income
5714 IF l_pre_tax_income_tbl.exists(p)
5715 THEN
5716 l_pre_tax_income_tbl(p).cf_amount := NVL(l_pre_tax_income_tbl(p).cf_amount,0)
5717 + l_tmp_interest;
5718 ELSE
5719 l_pre_tax_income_tbl(p).cf_amount :=l_tmp_interest;
5720 END IF;
5721 ELSE
5722 -- Pre-Tax is calculated for entire month, hence, no need to accumulate.
5723 l_pre_tax_income_tbl(p).cf_amount := l_tmp_interest;
5724 END IF;
5725 l_pre_tax_income_tbl(p).cf_date := l_end_date;
5726 p := p + 1;
5727
5728 IF TRUNC(l_end_date) = TRUNC(l_k_end_date)
5729 THEN
5730 l_termination_val := l_termination_val - l_residual_amount;
5731 l_term_complete := 'Y';
5732 END IF;
5733 -- Termination value streams assignment
5734 l_termination_val_tbl(t).cf_amount := l_termination_val;
5735 l_termination_val_tbl(t).cf_date := l_end_date;
5736 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5737 'L | ' || round( l_bk_yield, 4 ) || ' | ' || 'Y' || ' | ' || l_days_per_annum
5738 || ' | ' || l_start_date || ' | ' || l_end_date || ' | ' || l_days
5739 || ' | ' || round( l_tmp_interest, 4 ) || ' | - | ' || round(l_termination_val_tbl(t).cf_amount, 4 ) );
5740 t := t + 1;
5741 EXIT WHEN TRUNC(l_end_date) = TRUNC(l_k_end_date);
5742 -- Increment the Start Date to Next Month First
5743 l_start_date := LAST_DAY(l_start_date) + 1;
5744 -- Increment m
5745 m := m + 1;
5746 END LOOP; -- Loop on m
5747 END IF; -- IF cf_index = l_cf_inflows.LAST
5748 END LOOP; -- Looping through the Inflows
5749 -- Assign the termination value at the end of the period to l_diff and proceed !!
5750 l_diff := l_termination_val;
5751 -- If the current bk_yield is making the termination value as zero at the end of the
5752 -- period, then we have attained the solution, hence return the termination value
5753 -- and pre_tax streams along with the bk_yield !!
5754 IF ROUND(l_diff, 4) = 0
5755 THEN
5756 IF NVL( p_prosp_rebook_flag, 'N' ) = 'Y' AND
5757 p_rebook_date <> p_start_date -- Contract Start Date <> Rebook Revision Date
5758 THEN
5759 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5760 ' !!! Returning Streams based on Prospective Rebooking Case !!!' );
5761 -- Prospective Rebooking Enhancement
5762 -- The Booking Yield Algorithm has been modified to generate the
5763 -- Lease Income Streams prospectively from the Last Accrued Date to the
5764 -- Contract End Date
5765 -- Hence, prepend the Before Revision Pre-Tax Income Streams
5766 -- to the l_pre_tax_income_tbl streams
5767 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5768 'Copying Pre-Tax Income Streams from Contract Start Date to Last Accrual Date' );
5769 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5770 ' # | Date | amount ' );
5771 p_index := 1;
5772 WHILE TRUNC(p_orig_income_streams(p_index).cf_date) <=
5773 TRUNC(l_last_accrued_date)
5774 LOOP
5775 x_pre_tax_inc_tbl(p_index).cf_date := TRUNC(p_orig_income_streams(p_index).cf_date);
5776 x_pre_tax_inc_tbl(p_index).cf_amount := p_orig_income_streams(p_index).cf_amount;
5777 x_pre_tax_inc_tbl(p_index).line_number := p_index;
5778 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5779 p_index || ' | ' ||
5780 x_pre_tax_inc_tbl(p_index).cf_date || ' | ' ||
5781 x_pre_tax_inc_tbl(p_index).cf_amount);
5782 -- Increment the p_index
5783 p_index := p_index + 1;
5784 END LOOP;
5785 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5786 'Appending Pre-Tax Income Streams from Contract Start Date to Last Accrual Date' );
5787 -- Append the Newly generated the Pre-Tax Income Streams
5788 FOR p in l_pre_tax_income_tbl.FIRST .. l_pre_tax_income_tbl.LAST
5789 LOOP
5790 x_pre_tax_inc_tbl(p_index).cf_date := TRUNC(l_pre_tax_income_tbl(p).cf_date);
5791 x_pre_tax_inc_tbl(p_index).cf_amount := l_pre_tax_income_tbl(p).cf_amount;
5792 x_pre_tax_inc_tbl(p_index).line_number := p_index;
5793 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5794 p_index || ' | ' ||
5795 x_pre_tax_inc_tbl(p_index).cf_date || ' | ' ||
5796 x_pre_tax_inc_tbl(p_index).cf_amount);
5797 -- Increment the p_index
5798 p_index := p_index + 1;
5799 END LOOP;
5800 -- The Termination Value Streams on or before Last Accrued Date
5801 -- are already calculated during the process to calculate
5802 -- the effective Investement as on the Effective Rebook Date [Last Accrued Date +1]
5803 -- Append the Newly generated the Pre-Tax Income Streams
5804 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5805 'Appending Termination Value Streams from Contract Start Date to Last Accrual Date' );
5806 FOR t in l_termination_val_tbl.FIRST .. l_termination_val_tbl.LAST
5807 LOOP
5808 x_termination_tbl(t_index).cf_date := TRUNC(l_termination_val_tbl(t).cf_date);
5809 x_termination_tbl(t_index).cf_amount := l_termination_val_tbl(t).cf_amount;
5810 x_termination_tbl(t_index).line_number := t_index;
5811 -- Increment the p_index
5812 t_index := t_index + 1;
5813 END LOOP;
5814 x_termination_tbl(x_termination_tbl.LAST).cf_amount := l_residual_amount;
5815 ELSE
5816 -- Copying back the Pre-Tax Income Streams
5817 FOR p in l_pre_tax_income_tbl.FIRST .. l_pre_tax_income_tbl.LAST
5818 LOOP
5819 x_pre_tax_inc_tbl(p).cf_date := trunc(l_pre_tax_income_tbl(p).cf_date);
5820 x_pre_tax_inc_tbl(p).cf_amount := l_pre_tax_income_tbl(p).cf_amount;
5821 x_pre_tax_inc_tbl(p).line_number := p;
5822 END LOOP;
5823 -- Copying back the Termination Value Streams
5824 FOR t in l_termination_val_tbl.FIRST .. l_termination_val_tbl.LAST
5825 LOOP
5826 x_termination_tbl(t).cf_date := trunc(l_termination_val_tbl(t).cf_date);
5827 x_termination_tbl(t).cf_amount := l_termination_val_tbl(t).cf_amount;
5828 x_termination_tbl(t).line_number := t;
5829 END LOOP;
5830 x_termination_tbl(x_termination_tbl.LAST).cf_amount := l_residual_amount;
5831 END IF;
5832 x_bk_yield := l_bk_yield;
5833 -- Achieved the booking yeild, now returning back
5834 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5835 'BOOKING YIELD = ' || round( x_bk_yield, 4));
5836 x_return_status := 'S';
5837 RETURN;
5838 END IF;
5839 -- Using Interpolation approach to estimate/increment the next
5840 -- propsed booking yield .. !
5841 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5842 'Inrementation Details:Before' );
5843 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5844 'n_iterations|l_crossed_zero|l_increment|l_abs_incr|l_prev_incr_sign|SIGN(l_diff)' ||
5845 'l_diff|l_positive_diff|l_negative_diff|l_prev_diff|' ||
5846 'l_bk_yield|l_prev_bk_yeild|l_positive_diff_bk_yeild|l_negative_diff_bk_yeild' );
5847 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5848 n_iterations||'|'||l_crossed_zero||'|'||l_increment||'|'||l_abs_incr||'|'||l_prev_incr_sign||'|'||SIGN(l_diff)||'|'||
5849 l_diff||'|'||l_positive_diff||'|'||l_negative_diff||'|'||l_prev_diff||'|'||
5850 l_bk_yield||'|'||l_prev_bk_yeild||'|'||l_positive_diff_bk_yeild||'|'||l_negative_diff_bk_yeild );
5851 IF n_iterations > 1 AND
5852 SIGN(l_diff) <> SIGN(l_prev_diff)
5853 AND l_crossed_zero = 'N'
5854 THEN
5855 l_crossed_zero := 'Y';
5856 IF (SIGN(l_diff) = 1)
5857 THEN
5858 l_positive_diff := l_diff;
5859 l_negative_diff := l_prev_diff;
5860 l_positive_diff_bk_yeild := l_bk_yield;
5861 l_negative_diff_bk_yeild := l_prev_bk_yeild;
5862 ELSE
5863 l_positive_diff := l_prev_diff;
5864 l_negative_diff := l_diff;
5865 l_positive_diff_bk_yeild := l_prev_bk_yeild;
5866 l_negative_diff_bk_yeild := l_bk_yield;
5867 END IF;
5868 END IF;
5869 IF (SIGN(l_diff) = 1)
5870 THEN
5871 l_positive_diff := l_diff;
5872 l_positive_diff_bk_yeild := l_bk_yield;
5873 ELSE
5874 l_negative_diff := l_diff;
5875 l_negative_diff_bk_yeild := l_bk_yield;
5876 END IF;
5877 IF l_crossed_zero = 'Y'
5878 THEN
5879 IF n_iterations > 1
5880 THEN
5881 l_abs_incr := abs((l_positive_diff_bk_yeild - l_negative_diff_bk_yeild) /
5882 (l_positive_diff - l_negative_diff) * l_diff);
5883 ELSE
5884 l_abs_incr := ABS(l_increment) / 2;
5885 END IF;
5886 ELSE
5887 l_abs_incr := ABS(l_increment);
5888 END IF;
5889 IF n_iterations > 1
5890 THEN
5891 IF SIGN(l_diff) <> l_prev_diff_sign
5892 THEN
5893 IF l_prev_incr_sign = 1
5894 THEN
5895 l_increment := - l_abs_incr;
5896 ELSE
5897 l_increment := l_abs_incr;
5898 END IF;
5899 ELSE
5900 IF l_prev_incr_sign = 1
5901 THEN
5902 l_increment := l_abs_incr;
5903 ELSE
5904 l_increment := - l_abs_incr;
5905 END IF;
5906 END IF;
5907 ELSE
5908 IF SIGN(l_diff) = 1
5909 THEN
5910 l_increment := - l_increment;
5911 ELSE
5912 l_increment := l_increment;
5913 END IF;
5914 END IF;
5915 l_prev_bk_yeild := l_bk_yield;
5916 l_bk_yield := l_bk_yield + l_increment;
5917 l_prev_incr_sign := SIGN(l_increment);
5918 l_prev_diff_sign := SIGN(l_diff);
5919 l_prev_diff := l_diff;
5920 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5921 'Inrementation Details: After Calculations' );
5922 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5923 n_iterations||'|'||l_crossed_zero||'|'||l_increment||'|'||l_abs_incr||'|'||l_prev_incr_sign||'|'||SIGN(l_diff)||'|'||
5924 l_diff||'|'||l_positive_diff||'|'||l_negative_diff||'|'||l_prev_diff||'|'||
5925 l_bk_yield||'|'||l_prev_bk_yeild||'|'||l_positive_diff_bk_yeild||'|'||l_negative_diff_bk_yeild );
5926 END LOOP; -- Loop on n_iterations
5927 -- Actual logic Ends here
5928 x_return_status := l_return_status;
5929 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
5930 x_msg_data => x_msg_data);
5931 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
5932 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
5933 EXCEPTION
5934 WHEN OKL_API.G_EXCEPTION_ERROR THEN
5935 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5936 p_api_name => l_api_name,
5937 p_pkg_name => G_PKG_NAME,
5938 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
5939 x_msg_count => x_msg_count,
5940 x_msg_data => x_msg_data,
5941 p_api_type => g_api_type);
5942 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
5943 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5944 p_api_name => l_api_name,
5945 p_pkg_name => G_PKG_NAME,
5946 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
5947 x_msg_count => x_msg_count,
5948 x_msg_data => x_msg_data,
5949 p_api_type => g_api_type);
5950 WHEN OTHERS THEN
5951 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5952 p_api_name => l_api_name,
5953 p_pkg_name => G_PKG_NAME,
5954 p_exc_name => 'OTHERS',
5955 x_msg_count => x_msg_count,
5956 x_msg_data => x_msg_data,
5957 p_api_type => g_api_type);
5958 END compute_bk_yield;
5959
5960 PROCEDURE get_qq_rc_cash_flows(
5961 p_api_version IN NUMBER,
5962 p_init_msg_list IN VARCHAR2,
5963 x_return_status OUT NOCOPY VARCHAR2,
5964 x_msg_count OUT NOCOPY NUMBER,
5965 x_msg_data OUT NOCOPY VARCHAR2,
5966 p_qq_hdr_rec IN so_hdr_rec_type,
5967 x_days_in_month OUT NOCOPY VARCHAR2,
5968 x_days_in_year OUT NOCOPY VARCHAR2,
5969 x_item_cat_cf_tbl OUT NOCOPY item_cat_cf_tbl_type)
5970 IS
5971 l_api_version CONSTANT NUMBER DEFAULT 1.0;
5972 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_rc_cash_flows';
5973 l_return_status VARCHAR2(1);
5974 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
5975 || G_PKG_NAME || '.' || UPPER(l_api_name);
5976 l_debug_enabled VARCHAR2(10);
5977 is_debug_procedure_on BOOLEAN;
5978 is_debug_statement_on BOOLEAN;
5979 -- Cursor Declarations
5980 CURSOR item_cat_csr( p_qq_id NUMBER )
5981 IS
5982 SELECT id
5983 ,item_category_id
5984 ,value
5985 ,basis
5986 ,nvl(nvl(end_of_term_value, end_of_term_value_default), 0) end_of_term_amount
5987 ,lease_rate_factor
5988 FROM OKL_QUICK_QUOTE_LINES_B qql
5989 WHERE qql.quick_quote_id = p_qq_id
5990 AND TYPE = G_ITEMCATEGORY_TYPE; -- Item Category Type
5991
5992 CURSOR get_cat_name(p_category_id IN NUMBER) IS
5993 SELECT category_concat_segs name,
5994 description
5995 FROM mtl_categories_v
5996 WHERE category_id = p_category_id;
5997 cat_rec get_cat_name%ROWTYPE;
5998
5999 -- Cursor to get the Financial Adjustments defined @ QQ Level
6000 CURSOR fin_adj_csr( p_qq_id NUMBER, p_tot_item_cost IN NUMBER )
6001 IS
6002 SELECT TYPE type
6003 ,SUM(CASE basis
6004 WHEN 'FIXED' THEN value
6005 WHEN 'ASSET_COST' THEN value * p_tot_item_cost * .01
6006 END ) AS fin_value
6007 FROM OKL_QUICK_QUOTE_LINES_B qql
6008 WHERE qql.quick_quote_id = p_qq_id
6009 AND TYPE IN ( G_DOWNPAYMENT_TYPE, -- Down Payment Type
6010 G_TRADEIN_TYPE, -- Trade in Type
6011 G_SUBSIDY_TYPE ) -- Subsidy Type
6012 GROUP BY TYPE
6013 ORDER BY TYPE;
6014
6015 -- Cursor to fetch the End of Term Option Type
6016 CURSOR get_eot_type( p_qq_id NUMBER )
6017 IS
6018 SELECT qq.id
6019 ,qq.reference_number
6020 ,eot.end_of_term_name
6021 ,eot.eot_type_code eot_type_code
6022 ,eot.end_of_term_id end_of_term_id
6023 ,eotversion.end_of_term_ver_id
6024 FROM OKL_QUICK_QUOTES_B qq,
6025 okl_fe_eo_term_vers eotversion,
6026 okl_fe_eo_terms_all_b eot
6027 WHERE qq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
6028 AND eot.end_of_term_id = eotversion.end_of_term_id
6029 AND qq.id = p_qq_id;
6030 -- Local Variables
6031 l_lrs_details lrs_details_rec_type;
6032 l_lrs_factor lrs_factor_rec_type;
6033 l_lrs_levels lrs_levels_tbl_type;
6034 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
6035 l_adj_factor NUMBER;
6036 l_got_adj_factor BOOLEAN;
6037 l_eot_percentage NUMBER;
6038 l_asset_fin_amt NUMBER;
6039 l_months_per_period NUMBER;
6040 l_months_after NUMBER;
6041 l_item_cat_cf_tbl item_cat_cf_tbl_type;
6042 cf_index NUMBER; -- Using as an index for Cash flow levels
6043 i NUMBER; -- Using as an index for Item Categories
6044 l_periods NUMBER;
6045 l_sum_fin_amt NUMBER; -- Sum of Financed Amount
6046 l_tot_down_payment NUMBER;
6047 l_tot_tradein NUMBER;
6048 l_tot_subsidy NUMBER;
6049 l_eot_type_code VARCHAR2(30);
6050 BEGIN
6051 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6052 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
6053 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
6054 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6055 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
6056 -- check for logging on STATEMENT level
6057 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
6058 l_return_status := OKL_API.START_ACTIVITY(
6059 p_api_name => l_api_name,
6060 p_pkg_name => G_PKG_NAME,
6061 p_init_msg_list => p_init_msg_list,
6062 l_api_version => l_api_version,
6063 p_api_version => p_api_version,
6064 p_api_type => g_api_type,
6065 x_return_status => x_return_status);
6066 --Check if activity started successfully
6067 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6068 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6069 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6070 RAISE OKL_API.G_EXCEPTION_ERROR;
6071 END IF;
6072 -- Know the type of the EOT and then proceed with the values directly or calculate the amount
6073 FOR t_rec IN get_eot_type(p_qq_id => p_qq_hdr_rec.id)
6074 LOOP
6075 l_eot_type_code := t_rec.eot_type_code;
6076 END LOOP;
6077 -- First of all, Calculate the Total OEC for all the Assets.
6078 l_sum_fin_amt := 0;
6079 i := 1;
6080 FOR t_rec IN item_cat_csr( p_qq_id => p_qq_hdr_rec.id )
6081 LOOP
6082 l_sum_fin_amt := l_sum_fin_amt + t_rec.value;
6083 -- Populate the Item Cat PL/SQL Table for calculation of the Proportionated Financial Adjustments
6084 l_item_cat_cf_tbl(i).line_id := t_rec.id;
6085 l_item_cat_cf_tbl(i).item_category_id := t_rec.item_category_id;
6086 -- Returning the Asset COST in the Financed Amount COLUMN, remember we are not returning C-S-D-T here !!
6087 l_item_cat_cf_tbl(i).financed_amount := t_rec.value; -- Populating the Cash Flow Record
6088 -- Increment i
6089 i := i + 1;
6090 END LOOP;
6091 -- Fetch the Financial adjustments, Down Payment/Tradein/Subsidy defined @ QQ level ..
6092 FOR t_rec IN fin_adj_csr( p_qq_id => p_qq_hdr_rec.id
6093 ,p_tot_item_cost => l_sum_fin_amt )
6094 LOOP
6095 IF t_rec.type = G_DOWNPAYMENT_TYPE
6096 THEN
6097 l_tot_down_payment := t_rec.fin_value;
6098 ELSIF t_rec.type = G_TRADEIN_TYPE
6099 THEN
6100 l_tot_tradein := t_rec.fin_value;
6101 ELSIF t_rec.type = G_SUBSIDY_TYPE
6102 THEN
6103 l_tot_subsidy := t_rec.fin_value;
6104 END IF;
6105 END LOOP;
6106 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6107 'TOTALS: p_qq_id | p_tot_item_cost | Tot Down Payment | Trade in | Subsidy ');
6108 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6109 p_qq_hdr_rec.id || ' | ' || round(l_sum_fin_amt, 4) || ' | ' ||
6110 round( l_tot_down_payment, 4) || ' | ' || round( l_tot_tradein, 4) || ' | ' || round( l_tot_subsidy, 4) );
6111 -- Code for distributing the fin. adj. @ QQ level to individual item categories !
6112 -- Approach is to proportionate the financial adjustments entered @ Header level
6113 -- based on the item category cost
6114 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6115 'PROPORTIONATED AMOUNTS: Item ID | Financed Amount | Down Payment | Trade in | Subsidy ');
6116 FOR t IN l_item_cat_cf_tbl.FIRST .. l_item_cat_cf_tbl.LAST
6117 LOOP
6118 l_item_cat_cf_tbl(t).down_payment := nvl(l_tot_down_payment * l_item_cat_cf_tbl(t).financed_amount/l_sum_fin_amt, 0);
6119 l_item_cat_cf_tbl(t).subsidy := nvl(l_tot_subsidy * l_item_cat_cf_tbl(t).financed_amount/l_sum_fin_amt, 0);
6120 l_item_cat_cf_tbl(t).trade_in := nvl(l_tot_tradein * l_item_cat_cf_tbl(t).financed_amount/l_sum_fin_amt, 0);
6121 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6122 l_item_cat_cf_tbl(t).line_id || ' | ' || round(l_item_cat_cf_tbl(t).financed_amount, 4) || ' | ' ||
6123 round( l_item_cat_cf_tbl(t).down_payment, 4) || ' | ' || round( l_item_cat_cf_tbl(t).trade_in, 4) || ' | ' || round( l_item_cat_cf_tbl(t).subsidy, 4) );
6124 END LOOP;
6125 -- 1/ Check for the structured_pricing column in p_qq_hdr_rec.structured_pricing
6126 -- IF 'N' then fetch the lease rate factor levels for each item category
6127 IF p_qq_hdr_rec.structured_pricing IS NULL OR
6128 p_qq_hdr_rec.structured_pricing = 'N'
6129 THEN
6130 l_got_adj_factor := FALSE;
6131 i := 1;
6132 FOR t_rec IN item_cat_csr( p_qq_id => p_qq_hdr_rec.id )
6133 LOOP
6134 -- Calculate EOT %age. FORMULA: EOT %age = EOT of the Asset / Assets OEC * 100
6135 IF l_eot_type_code = 'AMOUNT' OR l_eot_type_code = 'RESIDUAL_AMOUNT'
6136 THEN
6137 l_eot_percentage := (t_rec.end_of_term_amount / t_rec.VALUE ) * 100;
6138 l_item_cat_cf_tbl(i).eot_amount := t_rec.end_of_term_amount;
6139 ELSE
6140 -- End of Term Amount is representing actually the percentage
6141 l_eot_percentage := t_rec.end_of_term_amount;
6142 l_item_cat_cf_tbl(i).eot_amount := (t_rec.end_of_term_amount * t_rec.VALUE ) / 100;
6143 END IF;
6144 -- Loop through all the assets and fetch the corresponding LRF and payment amounts !
6145 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6146 'Extracting the information from Lease Rate Set ' );
6147 l_lrs_levels.DELETE;
6148 -- Extract the data from the Lease Rate Set !
6149 get_lease_rate_factors(
6150 p_api_version => p_api_version,
6151 p_init_msg_list => p_init_msg_list,
6152 x_return_status => l_return_status,
6153 x_msg_count => x_msg_count,
6154 x_msg_data => x_msg_data,
6155 p_lrt_id => p_qq_hdr_rec.rate_card_id,
6156 p_start_date => p_qq_hdr_rec.expected_start_date,
6157 p_term_in_months => p_qq_hdr_rec.term,
6158 p_eot_percentage => l_eot_percentage,
6159 x_lrs_details => l_lrs_details,
6160 x_lrs_factor => l_lrs_factor,
6161 x_lrs_levels => l_lrs_levels);
6162 IF l_return_status <> OKL_API.G_RET_STS_SUCCESS
6163 THEN
6164 OPEN get_cat_name(p_category_id => t_rec.item_category_id);
6165 FETCH get_cat_name INTO cat_rec;
6166 CLOSE get_cat_name;
6167 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6168 'Couldnot found the Lease Rate Factor levels for Item Category ' || cat_rec.name );
6169 -- Show the message and then return back throwing an error!
6170 OKL_API.set_message(
6171 p_app_name => G_APP_NAME,
6172 p_msg_name => 'OKL_LP_NO_LRS_LEVELS_FOUND',
6173 p_token1 => 'ITEMCAT',
6174 p_token1_value => cat_rec.name,
6175 p_token2 => 'ITEMTERM',
6176 p_token2_value => p_qq_hdr_rec.term,
6177 p_token3 => 'ITEMEOTPERCENT',
6178 p_token3_value => ROUND(l_eot_percentage,4) );
6179 RAISE OKL_API.G_EXCEPTION_ERROR;
6180 END IF;
6181 -- Apply the adjustment matrix if needed!
6182 IF l_lrs_details.adj_mat_version_id IS NOT NULL AND
6183 l_got_adj_factor = FALSE
6184 THEN
6185 l_ac_rec_type.src_id := l_lrs_details.adj_mat_version_id; -- Pricing adjustment matrix ID
6186 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
6187 l_ac_rec_type.target_id := p_qq_hdr_rec.ID ; -- Quote ID
6188 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
6189 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
6190 l_ac_rec_type.target_eff_from := p_qq_hdr_rec.expected_start_date; -- Quote effective From
6191 l_ac_rec_type.term := p_qq_hdr_rec.term; -- Remaining four will be from teh business object like QQ / LQ
6192 l_ac_rec_type.territory := p_qq_hdr_rec.sales_territory_id;
6193 l_ac_rec_type.deal_size := l_sum_fin_amt; -- Not sure how to pass this value
6194 l_ac_rec_type.customer_credit_class := NULL; -- Not sure how to pass this even ..
6195 -- Fetching the deal_size ..
6196 -- Calling the API to get the adjustment factor ..
6197 okl_ec_evaluate_pvt. get_adjustment_factor(
6198 p_api_version => p_api_version,
6199 p_init_msg_list => p_init_msg_list,
6200 x_return_status => x_return_status,
6201 x_msg_count => x_msg_count,
6202 x_msg_data => x_msg_data,
6203 p_okl_ac_rec => l_ac_rec_type,
6204 x_adjustment_factor => l_adj_factor );
6205 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6206 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6207 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6208 RAISE OKL_API.G_EXCEPTION_ERROR;
6209 END IF;
6210 END IF;
6211 IF l_got_adj_factor = FALSE
6212 THEN
6213 l_got_adj_factor := TRUE;
6214 l_adj_factor := nvl( l_adj_factor, 0 );
6215 END IF;
6216 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Adjustment Factor ' || l_adj_factor );
6217 -- Calculating the Asset Level Financed Amount. i.e C- nvl(S+D+T, 0)
6218 l_asset_fin_amt := l_item_cat_cf_tbl(i).financed_amount - nvl( l_item_cat_cf_tbl(i).subsidy +
6219 l_item_cat_cf_tbl(i).down_payment + l_item_cat_cf_tbl(i).trade_in, 0);
6220 -- Store the Item Category details in the PL/SQL table to return back ..
6221 l_item_cat_cf_tbl(i).cash_flow_rec.due_arrears_yn := l_lrs_details.arrears_yn;
6222 l_item_cat_cf_tbl(i).cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
6223 -- Get the Months factor!
6224 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
6225 p_frequency => l_lrs_details.frq_code,
6226 x_return_status => l_return_status);
6227 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6228 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6229 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6230 RAISE OKL_API.G_EXCEPTION_ERROR;
6231 END IF;
6232 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Months/Period ' || l_months_per_period );
6233 -- Populating the Cash Flow Levels
6234 l_months_after := 0;
6235 cf_index := 1;
6236 FOR t in l_lrs_levels.FIRST .. l_lrs_levels.LAST
6237 LOOP
6238 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).fqy_code := l_lrs_details.frq_code;
6239 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).number_of_periods := l_lrs_levels(t).periods;
6240 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).amount := ( l_lrs_levels(t).lease_rate_factor + nvl(l_adj_factor,0) ) * l_asset_fin_amt;
6241 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).is_stub := 'N';
6242 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).rate := l_lrs_levels(t).lease_rate_factor;
6243 -- Need to populate the start date per line .. !!
6244 okl_stream_generator_pvt.add_months_new(
6245 p_start_date => p_qq_hdr_rec.expected_start_date,
6246 p_months_after => l_months_after,
6247 x_date => l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).start_date,
6248 x_return_status => l_return_status);
6249 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6250 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6251 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6252 RAISE OKL_API.G_EXCEPTION_ERROR;
6253 END IF;
6254 -- Add to the l_months_after
6255 l_months_after := l_months_after + ( l_lrs_levels(t).periods * l_months_per_period );
6256 -- Increment the index
6257 cf_index := cf_index + 1;
6258 END LOOP;
6259 -- Increment the item category index
6260 i := i + 1;
6261 END LOOP;
6262 ELSE
6263 -- Note:
6264 -- When user hasn't picked the LRS for Rate Card pricing and wishes
6265 -- to enter the LRF .. ie. Structured Pricing, Suresh PB has confirmed
6266 -- that irrespective of the line level pricing has been checked or not
6267 -- sales team will populate the LRF in OKL_QUICK_QUOTE_LINES_B.
6268 -- Hence, pricing can just fetch the LRF in OKL_QUICK_QUOTE_LINES_B and
6269 -- then build the cash flows from that ..
6270 -- Get the Months factor!
6271 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
6272 p_frequency => p_qq_hdr_rec.target_frequency,
6273 x_return_status => l_return_status);
6274 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6275 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6276 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6277 RAISE OKL_API.G_EXCEPTION_ERROR;
6278 END IF;
6279 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Months/Period ' || l_months_per_period );
6280 l_periods := p_qq_hdr_rec.term / l_months_per_period;
6281 -- Need to validate that the term / ( frequency factor ) should be a whole number !
6282 IF l_periods <> TRUNC( l_periods )
6283 THEN
6284 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Periods has to be a whole number ');
6285 OKL_API.set_message( G_APP_NAME, OKL_API.G_INVALID_VALUE, OKL_API.G_COL_NAME_TOKEN, 'l_periods');
6286 RAISE OKL_API.G_EXCEPTION_ERROR;
6287 END IF;
6288 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6289 'Line ID | OEC | EOT Amount | Arrears YN | Freq | Periods | LRF | Amt | Start Date ' );
6290 i := 1;
6291 -- Loop through all item categories and build the corresponding cash flows ..
6292 FOR t_rec IN item_cat_csr( p_qq_id => p_qq_hdr_rec.id )
6293 LOOP
6294 -- Calculate the EOT Amount. FORMULA: EOT% = EOT % * Asset OEC / 100;
6295 IF l_eot_type_code = 'AMOUNT' OR l_eot_type_code = 'RESIDUAL_AMOUNT'
6296 THEN
6297 l_item_cat_cf_tbl(i).eot_amount := t_rec.end_of_term_amount;
6298 ELSE
6299 l_item_cat_cf_tbl(i).eot_amount := t_rec.value * t_rec.end_of_term_amount / 100;
6300 END IF;
6301 -- Calculate the Asset level Financed Amount: FORMULA: Asset Fin. Amt = C - NVL(S+D+T, 0)
6302 l_asset_fin_amt := l_item_cat_cf_tbl(i).financed_amount - nvl( l_item_cat_cf_tbl(i).subsidy +
6303 l_item_cat_cf_tbl(i).down_payment + l_item_cat_cf_tbl(i).trade_in, 0);
6304 -- Populating the Cash Flow Record
6305 l_item_cat_cf_tbl(i).cash_flow_rec.due_arrears_yn := p_qq_hdr_rec.target_arrears;
6306 l_item_cat_cf_tbl(i).cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
6307 -- Populating the Cash Flow Levels
6308 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).fqy_code := p_qq_hdr_rec.target_frequency;
6309 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).number_of_periods := l_periods;
6310 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).amount := t_rec.lease_rate_factor * l_asset_fin_amt;
6311 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).is_stub := 'N';
6312 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).start_date := p_qq_hdr_rec.expected_start_date;
6313 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).rate := t_rec.lease_rate_factor;
6314 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6315 t_rec.ID || ' | ' || round(l_item_cat_cf_tbl(i).financed_amount,2) || ' | ' || round(t_rec.end_of_term_amount, 2) || ' | ' ||
6316 p_qq_hdr_rec.target_arrears || ' | ' || p_qq_hdr_rec.target_frequency || ' | ' || l_periods || ' | ' ||
6317 t_rec.lease_rate_factor || ' | ' || round(l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).amount,2) || ' | ' ||
6318 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).start_date );
6319 -- Increment the item category index
6320 i := i + 1;
6321 END LOOP; -- Loop on item_cat_csr
6322 END IF;
6323 -- Fetch the day convention from the Stream Generation Template ...
6324 get_qq_sgt_day_convention(
6325 p_api_version => p_api_version,
6326 p_init_msg_list => p_init_msg_list,
6327 x_return_status => l_return_status,
6328 x_msg_count => x_msg_count,
6329 x_msg_data => x_msg_data,
6330 p_qq_id => p_qq_hdr_rec.id,
6331 x_days_in_month => x_days_in_month,
6332 x_days_in_year => x_days_in_year);
6333 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6334 'After get_qq_sgt_day_convention ' || l_return_status );
6335 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6336 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6337 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6338 RAISE OKL_API.G_EXCEPTION_ERROR;
6339 END IF;
6340 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6341 'SGT Day convention: ' || x_days_in_month || ' / ' || x_days_in_year);
6342 -- Return the values ...
6343 x_item_cat_cf_tbl := l_item_cat_cf_tbl;
6344 x_return_status := l_return_status;
6345 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
6346 x_msg_data => x_msg_data);
6347 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6348 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
6349 EXCEPTION
6350 WHEN OKL_API.G_EXCEPTION_ERROR THEN
6351 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6352 p_api_name => l_api_name,
6353 p_pkg_name => G_PKG_NAME,
6354 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
6355 x_msg_count => x_msg_count,
6356 x_msg_data => x_msg_data,
6357 p_api_type => g_api_type);
6358 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
6359 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6360 p_api_name => l_api_name,
6361 p_pkg_name => G_PKG_NAME,
6362 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
6363 x_msg_count => x_msg_count,
6364 x_msg_data => x_msg_data,
6365 p_api_type => g_api_type);
6366 WHEN OTHERS THEN
6367 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6368 p_api_name => l_api_name,
6369 p_pkg_name => G_PKG_NAME,
6370 p_exc_name => 'OTHERS',
6371 x_msg_count => x_msg_count,
6372 x_msg_data => x_msg_data,
6373 p_api_type => g_api_type);
6374 END get_qq_rc_cash_flows;
6375
6376
6377 -- This API is responsible to create cash flow and cash flow details records when
6378 -- the pricing type is Target Rate or
6379 -- User has picked the rate from SRT/LRS
6380 -- User has picked the structured pricing and mentiond the rate, periods, amount ..etc
6381 --
6382 -- Returns the populated cash flow record and cash flow levels table
6383 PROCEDURE get_qq_cash_flows(
6384 p_api_version IN NUMBER,
6385 p_init_msg_list IN VARCHAR2,
6386 x_return_status OUT NOCOPY VARCHAR2,
6387 x_msg_count OUT NOCOPY NUMBER,
6388 x_msg_data OUT NOCOPY VARCHAR2,
6389 p_qq_hdr_rec IN so_hdr_rec_type,
6390 p_eot_percentage IN NUMBER,
6391 p_oec IN NUMBER,
6392 x_days_in_month OUT NOCOPY VARCHAR2,
6393 x_days_in_year OUT NOCOPY VARCHAR2,
6394 x_cash_flow_rec OUT NOCOPY so_cash_flows_rec_type,
6395 x_cash_flow_det_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
6396 IS
6397 -- Local Variables
6398 l_api_version CONSTANT NUMBER DEFAULT 1.0;
6399 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_cash_flows (QQ)';
6400 l_return_status VARCHAR2(1);
6401
6402 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
6403 || G_PKG_NAME || '.' || UPPER(l_api_name);
6404 l_debug_enabled VARCHAR2(10);
6405 is_debug_procedure_on BOOLEAN;
6406 is_debug_statement_on BOOLEAN;
6407
6408 -- Cursor Declarations
6409 CURSOR get_deal_size_csr( p_qq_id NUMBER )
6410 IS
6411 SELECT sum(VALUE) deal_size
6412 FROM OKL_QUICK_QUOTE_LINES_B qql
6413 WHERE qql.quick_quote_id = p_qq_id
6414 AND qql.TYPE = G_ITEMCATEGORY_TYPE; -- Item Category Type
6415 -- Local Variables declaration
6416 l_cash_flow_rec so_cash_flows_rec_type;
6417 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
6418 i NUMBER; -- Index for looping over the Cash Flow Details
6419 l_months_per_period NUMBER;
6420 l_months_after NUMBER;
6421 -- Lease Rate Factor Variables
6422 l_lrs_details lrs_details_rec_type;
6423 l_lrs_factor lrs_factor_rec_type;
6424 l_lrs_levels lrs_levels_tbl_type;
6425 -- Standard Rate Template Variables
6426 l_srt_details srt_details_rec_type;
6427 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
6428 l_adj_factor NUMBER;
6429 l_deal_size NUMBER;
6430 l_months_factor NUMBER;
6431 BEGIN
6432 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6433 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
6434 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
6435 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6436 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
6437 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
6438 l_return_status := OKL_API.START_ACTIVITY(
6439 p_api_name => l_api_name,
6440 p_pkg_name => G_PKG_NAME,
6441 p_init_msg_list => p_init_msg_list,
6442 l_api_version => l_api_version,
6443 p_api_version => p_api_version,
6444 p_api_type => g_api_type,
6445 x_return_status => x_return_status);
6446 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6447 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6448 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6449 RAISE OKL_API.G_EXCEPTION_ERROR;
6450 END IF;
6451 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6452 'Pricing Method is ' || p_qq_hdr_rec.pricing_method );
6453 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6454 ': p_qq_hdr_rec.rate_template_id=' || p_qq_hdr_rec.rate_template_id );
6455 i := 1;
6456 l_months_after := 0;
6457 l_adj_factor := 0;
6458
6459 IF p_qq_hdr_rec.rate_template_id IS NOT NULL
6460 THEN
6461 -- Extract details from the Standard Rate Template
6462 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6463 'Fetching the Details from the Standard Rate Template ' );
6464 get_standard_rates(
6465 p_api_version => p_api_version,
6466 p_init_msg_list => p_init_msg_list,
6467 x_return_status => l_return_status,
6468 x_msg_count => x_msg_count,
6469 x_msg_data => x_msg_data,
6470 p_srt_id => p_qq_hdr_rec.rate_template_id,
6471 p_start_date => p_qq_hdr_rec.expected_start_date,
6472 x_srt_details => l_srt_details);
6473 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6474 ': l_return_status ' || l_return_status );
6475 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6476 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6477 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6478 RAISE OKL_API.G_EXCEPTION_ERROR;
6479 END IF;
6480 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6481 'Using SRT ' || l_srt_details.template_name || ' Version ' || l_srt_details.version_number
6482 || ' Status ' || l_srt_details.sts_code || ' Pricing Engine ' || l_srt_details.pricing_engine_code
6483 || ' Rate Type ' || l_srt_details.rate_type_code || ' Day Convention ' || l_srt_details.day_convention_code );
6484 IF l_srt_details.adj_mat_version_id IS NOT NULL
6485 THEN
6486 -- Fetch the Deal Size
6487 OPEN get_deal_size_csr( p_qq_id => p_qq_hdr_rec.ID );
6488 FETCH get_deal_size_csr INTO l_deal_size;
6489 CLOSE get_deal_size_csr;
6490 -- Populate the Adjustment mat. rec.
6491 l_ac_rec_type.src_id := l_srt_details.adj_mat_version_id; -- Pricing adjustment matrix ID
6492 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
6493 l_ac_rec_type.target_id := p_qq_hdr_rec.ID ; -- Quote ID
6494 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
6495 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
6496 l_ac_rec_type.target_eff_from := p_qq_hdr_rec.expected_start_date; -- Quote effective From
6497 l_ac_rec_type.term := p_qq_hdr_rec.term; -- Remaining four will be from teh business object like QQ / LQ
6498 l_ac_rec_type.territory := p_qq_hdr_rec.sales_territory_id;
6499 l_ac_rec_type.deal_size := l_deal_size;
6500 l_ac_rec_type.customer_credit_class := NULL; -- Not sure how to pass this even ..
6501 -- Calling the API to get the adjustment factor ..
6502 okl_ec_evaluate_pvt. get_adjustment_factor(
6503 p_api_version => p_api_version,
6504 p_init_msg_list => p_init_msg_list,
6505 x_return_status => x_return_status,
6506 x_msg_count => x_msg_count,
6507 x_msg_data => x_msg_data,
6508 p_okl_ac_rec => l_ac_rec_type,
6509 x_adjustment_factor => l_adj_factor );
6510 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6511 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6512 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6513 RAISE OKL_API.G_EXCEPTION_ERROR;
6514 END IF;
6515 END IF;
6516 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6517 'Adjustment Factor ' || l_adj_factor );
6518 -- Populating the Cash flows
6519 l_cash_flow_rec.due_arrears_yn := p_qq_hdr_rec.target_arrears;
6520 l_cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
6521 -- Populating the Cash flow levels
6522 l_cash_flow_det_tbl(1).fqy_code := l_srt_details.frequency_code;
6523 l_cash_flow_det_tbl(1).rate := l_srt_details.srt_rate + nvl(l_srt_details.spread,0) + nvl(l_adj_factor,0); -- Rate is being stored as Percentage
6524 IF nvl( l_srt_details.min_adj_rate,l_cash_flow_det_tbl(1).rate) > l_cash_flow_det_tbl(1).rate
6525 THEN
6526 l_cash_flow_det_tbl(1).rate := l_srt_details.min_adj_rate;
6527 ELSIF nvl( l_srt_details.max_adj_rate,l_cash_flow_det_tbl(1).rate) < l_cash_flow_det_tbl(1).rate
6528 THEN
6529 l_cash_flow_det_tbl(1).rate := l_srt_details.max_adj_rate;
6530 END IF;
6531 l_cash_flow_det_tbl(1).is_stub := 'N';
6532 l_cash_flow_det_tbl(1).start_date := p_qq_hdr_rec.expected_start_date;
6533 l_cash_flow_det_tbl(1).number_of_periods := p_qq_hdr_rec.target_periods;
6534 l_cash_flow_det_tbl(1).amount := p_qq_hdr_rec.target_amount;
6535 x_days_in_year := l_srt_details.day_convention_code;
6536 IF x_days_in_year = '360'
6537 THEN
6538 x_days_in_month := '30';
6539 ELSIF x_days_in_year = '365' OR x_days_in_year = 'ACTUAL'
6540 THEN
6541 x_days_in_month := 'ACTUAL';
6542 END IF;
6543 ELSIF p_qq_hdr_rec.pricing_method = 'TR'
6544 THEN
6545 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6546 'Building the Cash flows n Inflows ' || p_qq_hdr_rec.pricing_method );
6547 -- Populating the Cash flows
6548 l_cash_flow_rec.due_arrears_yn := p_qq_hdr_rec.target_arrears;
6549 l_cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
6550 -- Populating the Cash flow levels
6551 l_cash_flow_det_tbl(1).fqy_code := p_qq_hdr_rec.target_frequency;
6552 l_cash_flow_det_tbl(1).rate := p_qq_hdr_rec.target_rate; -- Rate is being stored as Percentage
6553 l_cash_flow_det_tbl(1).is_stub := 'N';
6554 l_cash_flow_det_tbl(1).start_date := p_qq_hdr_rec.expected_start_date;
6555 l_months_factor := okl_stream_generator_pvt.get_months_factor(
6556 p_frequency => p_qq_hdr_rec.target_frequency,
6557 x_return_status => x_return_status);
6558 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6559 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6560 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6561 RAISE OKL_API.G_EXCEPTION_ERROR;
6562 END IF;
6563 l_cash_flow_det_tbl(1).number_of_periods := p_qq_hdr_rec.term / l_months_factor;
6564 IF l_cash_flow_det_tbl(1).number_of_periods <> TRUNC( l_cash_flow_det_tbl(1).number_of_periods )
6565 THEN
6566 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Periods has to be a whole number ');
6567 OKL_API.set_message( G_APP_NAME, OKL_API.G_INVALID_VALUE, OKL_API.G_COL_NAME_TOKEN, 'Target Frequency');
6568 RAISE OKL_API.G_EXCEPTION_ERROR;
6569 END IF;
6570 -- Fetch the day convention from the Stream Generation Template ...
6571 get_qq_sgt_day_convention(
6572 p_api_version => p_api_version,
6573 p_init_msg_list => p_init_msg_list,
6574 x_return_status => l_return_status,
6575 x_msg_count => x_msg_count,
6576 x_msg_data => x_msg_data,
6577 p_qq_id => p_qq_hdr_rec.id,
6578 x_days_in_month => x_days_in_month,
6579 x_days_in_year => x_days_in_year);
6580 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6581 'After get_qq_sgt_day_convention ' || l_return_status );
6582 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6583 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6584 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6585 RAISE OKL_API.G_EXCEPTION_ERROR;
6586 END IF;
6587 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6588 'SGT Day convention: ' || x_days_in_month || ' / ' || x_days_in_year);
6589 ELSIF p_qq_hdr_rec.structured_pricing <> 'N'
6590 THEN
6591 -- Structured Pricing API
6592 -- Get the Pricing Details
6593 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6594 'Fetching from the Cash Flows ');
6595 get_qq_cash_flows(
6596 p_api_version => p_api_version,
6597 p_init_msg_list => p_init_msg_list,
6598 x_return_status => l_return_status,
6599 x_msg_count => x_msg_count,
6600 x_msg_data => x_msg_data,
6601 p_cf_source_type => G_CF_SOURCE_QQ,
6602 p_qq_id => p_qq_hdr_rec.id,
6603 x_days_in_month => x_days_in_month,
6604 x_days_in_year => x_days_in_year,
6605 x_cash_flow_rec => l_cash_flow_rec, -- Cash Flow Record
6606 x_cash_flow_det_tbl => l_cash_flow_det_tbl); -- Cash Flow Details Table
6607 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6608 'After get_qq_cash_flows ' || l_return_status );
6609 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6610 'l_cash_flow_det_tbl.COUNT ' || l_cash_flow_det_tbl.COUNT);
6611 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6612 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6613 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6614 RAISE OKL_API.G_EXCEPTION_ERROR;
6615 END IF;
6616 END IF; -- IF p_qq_hdr_rec.pricing_method
6617 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6618 ': Built the Cash flows and Levels ' );
6619 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6620 'Arrears = ' || l_cash_flow_rec.due_arrears_yn
6621 || 'Start Date=' || l_cash_flow_rec.start_date );
6622 IF l_cash_flow_det_tbl.COUNT > 0
6623 THEN
6624 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6625 ': Frequency | Rate | Stub Amount | Stub Days | Periods | Amount | Start Date ' );
6626 FOR t IN l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
6627 LOOP
6628 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6629 l_cash_flow_det_tbl(t).fqy_code || '|' || l_cash_flow_det_tbl(t).rate
6630 || '|' || l_cash_flow_det_tbl(t).stub_days || '|' || l_cash_flow_det_tbl(t).stub_amount
6631 || '|' || l_cash_flow_det_tbl(t).number_of_periods || '|' || l_cash_flow_det_tbl(t).amount
6632 || '|' || l_cash_flow_det_tbl(t).START_DATE || '|' || l_cash_flow_det_tbl(t).is_stub );
6633 END LOOP;
6634 END IF;
6635 -- Setting up the return variables
6636 x_cash_flow_rec := l_cash_flow_rec;
6637 x_cash_flow_det_tbl := l_cash_flow_det_tbl;
6638 x_return_status := l_return_status;
6639 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
6640 x_msg_data => x_msg_data);
6641 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6642 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
6643 EXCEPTION
6644 WHEN OKL_API.G_EXCEPTION_ERROR THEN
6645 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6646 p_api_name => l_api_name,
6647 p_pkg_name => G_PKG_NAME,
6648 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
6649 x_msg_count => x_msg_count,
6650 x_msg_data => x_msg_data,
6651 p_api_type => g_api_type);
6652 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
6653 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6654 p_api_name => l_api_name,
6655 p_pkg_name => G_PKG_NAME,
6656 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
6657 x_msg_count => x_msg_count,
6658 x_msg_data => x_msg_data,
6659 p_api_type => g_api_type);
6660 WHEN OTHERS THEN
6661 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6662 p_api_name => l_api_name,
6663 p_pkg_name => G_PKG_NAME,
6664 p_exc_name => 'OTHERS',
6665 x_msg_count => x_msg_count,
6666 x_msg_data => x_msg_data,
6667 p_api_type => g_api_type);
6668 END get_qq_cash_flows;
6669
6670 -- This API is responsible to create cash flow and cash flow details records when
6671 -- User has picked the rate from SRT for an Asset / Lease Quote
6672 -- User has picked the structured pricing and mentiond the rate, periods, amount ..etc
6673 -- either at the Lease Quote or Asset Level !
6674 -- Returns the populated cash flow record and cash flow levels table
6675 PROCEDURE get_lq_cash_flows(
6676 p_api_version IN NUMBER,
6677 p_init_msg_list IN VARCHAR2,
6678 x_return_status OUT NOCOPY VARCHAR2,
6679 x_msg_count OUT NOCOPY NUMBER,
6680 x_msg_data OUT NOCOPY VARCHAR2,
6681 p_id IN NUMBER,
6682 p_lq_srt_id IN NUMBER,
6683 p_cf_source IN VARCHAR2,
6684 p_adj_mat_cat_rec IN adj_mat_cat_rec,
6685 p_pricing_method IN VARCHAR2,
6686 x_days_in_month OUT NOCOPY VARCHAR2,
6687 x_days_in_year OUT NOCOPY VARCHAR2,
6688 x_cash_flow_rec OUT NOCOPY so_cash_flows_rec_type,
6689 x_cash_flow_det_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
6690 IS
6691 -- Local Variables
6692 l_api_version CONSTANT NUMBER DEFAULT 1.0;
6693 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lq_cash_flows';
6694 l_return_status VARCHAR2(1);
6695
6696 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
6697 || G_PKG_NAME || '.' || UPPER(l_api_name);
6698 l_debug_enabled VARCHAR2(10);
6699 is_debug_procedure_on BOOLEAN;
6700 is_debug_statement_on BOOLEAN;
6701
6702 -- Cursor Declarations ..
6703 CURSOR quote_csr(qteid NUMBER)
6704 IS
6705 SELECT qte.expected_start_date expected_start_date,
6706 qte.target_rate_type target_rate_type,
6707 qte.target_frequency target_frequency,
6708 qte.target_arrears_yn target_arrears,
6709 qte.target_rate target_rate,
6710 qte.target_periods target_periods,
6711 qte.target_amount target_amount,
6712 qte.term term,
6713 qte.structured_pricing structured_pricing,
6714 qte.pricing_method pricing_method
6715 FROM okl_lease_quotes_b qte
6716 WHERE qte.id = qteid;
6717 quote_rec quote_csr%ROWTYPE;
6718 -- Cursor to fetch the ID of the CFL defined at Quote Level !
6719 CURSOR get_cfl_id_csr( qteId NUMBER )
6720 IS
6721 SELECT cfl.ID cfl_id,
6722 cfh.id caf_id,
6723 cfo.id cfo_id,
6724 cfh.sty_id stream_type_id
6725 FROM OKL_CASH_FLOW_LEVELS cfl,
6726 OKL_CASH_FLOWS cfh,
6727 OKL_CASH_FLOW_OBJECTS cfo
6728 WHERE cfl.caf_id = cfh.id
6729 AND cfh.cfo_id = cfo.id
6730 AND cfo.source_table = 'OKL_LEASE_QUOTES_B'
6731 AND cfo.source_id = qteId
6732 ORDER BY cfl.start_date;
6733 -- Cursor to fetch the Details from the Asset
6734 CURSOR asset_details_csr( p_astId NUMBER )
6735 IS
6736 SELECT target_arrears,
6737 target_amount,
6738 parent_object_id
6739 FROM OKL_ASSETS_B
6740 WHERE id = p_astId;
6741 -- Cursor to fetch the Details from the Asset
6742 CURSOR fee_details_csr( p_feeId NUMBER )
6743 IS
6744 SELECT target_arrears,
6745 target_amount,
6746 parent_object_id,
6747 payment_type_id
6748 FROM OKL_FEES_B
6749 WHERE id = p_feeId;
6750 -- Cursor to fetch the Cash flow header information
6751 CURSOR lq_cash_flows_csr( p_id NUMBER, p_cf_source_type VARCHAR2 )
6752 IS
6753 SELECT cf.id caf_id
6754 ,dnz_khr_id khr_id
6755 ,dnz_qte_id qte_id
6756 ,cfo_id cfo_id
6757 ,sts_code sts_code
6758 ,sty_id sty_id
6759 ,cft_code cft_code
6760 ,due_arrears_yn due_arrears_yn
6761 ,start_date start_date
6762 ,number_of_advance_periods number_of_advance_periods
6763 ,oty_code oty_code
6764 FROM OKL_CASH_FLOWS cf,
6765 OKL_CASH_FLOW_OBJECTS cfo
6766 WHERE cf.cfo_id = cfo.id
6767 AND cfo.source_table = p_cf_source_type
6768 AND cfo.source_id = p_id;
6769 -- Cursor to fetch the Cash Flow Details
6770 CURSOR lq_cash_flow_levels_csr( p_caf_id NUMBER )
6771 IS
6772 SELECT id cfl_id
6773 ,caf_id
6774 ,fqy_code
6775 ,rate -- No rate is defined at Cash Flows Level.. Need to confirm
6776 ,stub_days
6777 ,stub_amount
6778 ,number_of_periods
6779 ,amount
6780 ,start_date
6781 FROM OKL_CASH_FLOW_LEVELS
6782 WHERE caf_id = p_caf_id
6783 ORDER BY start_date;
6784 -- Local Variables declaration
6785 l_cash_flow_rec so_cash_flows_rec_type;
6786 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
6787 i NUMBER; -- Index for looping over the Cash Flow Details
6788 l_months_per_period NUMBER;
6789 l_months_after NUMBER;
6790 -- Standard Rate Template Variables
6791 l_srt_details srt_details_rec_type;
6792 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
6793 l_adj_factor NUMBER;
6794 l_months_factor NUMBER;
6795 l_lq_id NUMBER;
6796 l_target_arrears NUMBER;
6797 cfl_index BINARY_INTEGER;
6798 BEGIN
6799 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6800 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
6801 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
6802 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6803 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
6804 -- check for logging on STATEMENT level
6805 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
6806 l_return_status := OKL_API.START_ACTIVITY(
6807 p_api_name => l_api_name,
6808 p_pkg_name => G_PKG_NAME,
6809 p_init_msg_list => p_init_msg_list,
6810 l_api_version => l_api_version,
6811 p_api_version => p_api_version,
6812 p_api_type => g_api_type,
6813 x_return_status => x_return_status);
6814 --Check if activity started successfully
6815 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6816 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6817 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6818 RAISE OKL_API.G_EXCEPTION_ERROR;
6819 END IF;
6820 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', ': p_id=' || p_id );
6821 i := 1;
6822 l_months_after := 0;
6823 l_adj_factor := 0;
6824 IF p_cf_source = G_CF_SOURCE_LQ
6825 THEN
6826 l_lq_id := p_id;
6827 ELSIF p_cf_source = G_CF_SOURCE_LQ_ASS
6828 THEN
6829 FOR t_rec IN asset_details_csr( p_id )
6830 LOOP
6831 l_lq_id := t_rec.parent_object_id;
6832 END LOOP;
6833 ELSIF p_cf_source = G_CF_SOURCE_LQ_FEE
6834 THEN
6835 FOR t_rec IN fee_details_csr( p_id )
6836 LOOP
6837 l_lq_id := t_rec.parent_object_id;
6838 END LOOP;
6839 END IF;
6840 -- Check whether the pricing method is of type Rate Card
6841 IF p_lq_srt_id IS NOT NULL
6842 THEN
6843 -- Fetch the target column values ..
6844 OPEN quote_csr(qteid => l_lq_id );
6845 FETCH quote_csr INTO quote_rec;
6846 CLOSE quote_csr;
6847 -- Extract details from the Standard Rate Template
6848 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6849 'Fetching the Details from the Standard Rate Template ' );
6850 get_standard_rates(
6851 p_api_version => p_api_version,
6852 p_init_msg_list => p_init_msg_list,
6853 x_return_status => l_return_status,
6854 x_msg_count => x_msg_count,
6855 x_msg_data => x_msg_data,
6856 p_srt_id => p_lq_srt_id,
6857 p_start_date => p_adj_mat_cat_rec.target_eff_from,
6858 x_srt_details => l_srt_details);
6859 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6860 ': l_return_status ' || l_return_status );
6861 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6862 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6863 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6864 RAISE OKL_API.G_EXCEPTION_ERROR;
6865 END IF;
6866 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6867 'Using SRT ' || l_srt_details.template_name || ' Version ' || l_srt_details.version_number
6868 || ' Status ' || l_srt_details.sts_code || ' Pricing Engine ' || l_srt_details.pricing_engine_code
6869 || ' Rate Type ' || l_srt_details.rate_type_code || ' Day Convention ' ||
6870 l_srt_details.day_convention_code );
6871 -- Need to apply the Adjustment factor to the rate !
6872 IF l_srt_details.adj_mat_version_id IS NOT NULL
6873 THEN
6874 l_ac_rec_type.src_id := l_srt_details.adj_mat_version_id; -- Pricing adjustment matrix ID
6875 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
6876 l_ac_rec_type.target_id := l_lq_id; -- Quote ID
6877 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
6878 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
6879 l_ac_rec_type.target_eff_from := p_adj_mat_cat_rec.target_eff_from; -- Quote effective From
6880 l_ac_rec_type.term := p_adj_mat_cat_rec.term; -- Remaining four will be from teh business object like QQ / LQ
6881 l_ac_rec_type.territory := p_adj_mat_cat_rec.territory;
6882 l_ac_rec_type.deal_size := p_adj_mat_cat_rec.deal_size; -- Not sure how to pass this value
6883 l_ac_rec_type.customer_credit_class := p_adj_mat_cat_rec.customer_credit_class; -- Not sure how to pass this even ..
6884 -- Calling the API to get the adjustment factor ..
6885 okl_ec_evaluate_pvt. get_adjustment_factor(
6886 p_api_version => p_api_version,
6887 p_init_msg_list => p_init_msg_list,
6888 x_return_status => x_return_status,
6889 x_msg_count => x_msg_count,
6890 x_msg_data => x_msg_data,
6891 p_okl_ac_rec => l_ac_rec_type,
6892 x_adjustment_factor => l_adj_factor );
6893 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6894 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6895 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6896 RAISE OKL_API.G_EXCEPTION_ERROR;
6897 END IF;
6898 END IF;
6899 -- Populating the Cash flow Header information
6900 IF p_cf_source = G_CF_SOURCE_LQ
6901 THEN
6902 l_cash_flow_rec.due_arrears_yn := quote_rec.target_arrears;
6903 l_cash_flow_det_tbl(1).amount := quote_rec.target_amount;
6904 ELSIF p_cf_source = G_CF_SOURCE_LQ_ASS
6905 THEN
6906 FOR t_rec IN asset_details_csr( p_id )
6907 LOOP
6908 l_cash_flow_rec.due_arrears_yn := t_rec.target_arrears;
6909 l_cash_flow_det_tbl(1).amount := t_rec.target_amount;
6910 END LOOP;
6911 ELSIF p_cf_source = G_CF_SOURCE_LQ_FEE
6912 THEN
6913 FOR t_rec IN fee_details_csr( p_id )
6914 LOOP
6915 l_cash_flow_rec.due_arrears_yn := t_rec.target_arrears;
6916 l_cash_flow_rec.sty_id := t_rec.payment_type_id;
6917 l_cash_flow_det_tbl(1).amount := t_rec.target_amount;
6918 END LOOP;
6919 END IF;
6920 l_cash_flow_rec.start_date := quote_rec.expected_start_date;
6921 IF quote_rec.pricing_method <> 'SM'
6922 THEN
6923 l_cash_flow_rec.sts_code := 'WORK';
6924 -- Populating the Cash flow levels
6925 l_cash_flow_det_tbl(1).fqy_code := l_srt_details.frequency_code;
6926 l_cash_flow_det_tbl(1).rate := l_srt_details.srt_rate + nvl(l_srt_details.spread,0) + nvl(l_adj_factor,0); -- Rate is being stored as Percentage
6927 IF nvl( l_srt_details.min_adj_rate,l_cash_flow_det_tbl(1).rate) > l_cash_flow_det_tbl(1).rate
6928 THEN
6929 l_cash_flow_det_tbl(1).rate := l_srt_details.min_adj_rate;
6930 ELSIF nvl( l_srt_details.max_adj_rate,l_cash_flow_det_tbl(1).rate) < l_cash_flow_det_tbl(1).rate
6931 THEN
6932 l_cash_flow_det_tbl(1).rate := l_srt_details.max_adj_rate;
6933 END IF;
6934 l_cash_flow_det_tbl(1).is_stub := 'N';
6935 l_cash_flow_det_tbl(1).start_date := quote_rec.expected_start_date;
6936 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6937 'GET_LQ p_frequency_passed' || l_srt_details.frequency_code);
6938 l_months_factor := okl_stream_generator_pvt.get_months_factor(
6939 p_frequency => l_srt_details.frequency_code,
6940 x_return_status => l_return_status);
6941 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6942 'p_months_factor'||l_months_factor);
6943 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6944 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6945 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6946 RAISE OKL_API.G_EXCEPTION_ERROR;
6947 END IF;
6948 l_cash_flow_det_tbl(1).number_of_periods := quote_rec.term / l_months_factor;
6949 --l_cash_flow_det_tbl(1).amount has been already fetched from the
6950 -- target_amount column either from OKL_LEASE_QUOTES_B/OKL_ASSETS_B/OKL_FEES_B
6951 ELSE
6952 -- When the LQ is being priced for SM pricng method, on selecting the SRT
6953 -- as the pricing option, the user will be shown to enter the Cash flow levels too.
6954 -- Hence, retrieve the cash flow levels even when the pricing option is SRT.
6955 -- From SRT, get the Rate,Frequency
6956 -- From CFL, get the Advance/Arrears, n, Fetching the Cash Flows Information
6957 l_return_status := OKL_API.G_RET_STS_ERROR;
6958 FOR t_rec in lq_cash_flows_csr( p_id =>p_id,
6959 p_cf_source_type => p_cf_source )
6960 LOOP
6961 l_cash_flow_rec.caf_id := t_rec.caf_id;
6962 l_cash_flow_rec.khr_id := t_rec.khr_id;
6963 l_cash_flow_rec.khr_id := t_rec.khr_id;
6964 l_cash_flow_rec.qte_id := t_rec.qte_id;
6965 l_cash_flow_rec.cfo_id := t_rec.cfo_id;
6966 l_cash_flow_rec.sts_code := t_rec.sts_code;
6967 l_cash_flow_rec.sty_id := t_rec.sty_id;
6968 l_cash_flow_rec.cft_code := t_rec.cft_code;
6969 l_cash_flow_rec.due_arrears_yn := t_rec.due_arrears_yn;
6970 l_cash_flow_rec.start_date := t_rec.start_date;
6971 l_cash_flow_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
6972 -- Use l_retun_status as a flag
6973 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6974 END LOOP;
6975 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
6976 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
6977 THEN
6978 cfl_index := 1;
6979 l_return_status := OKL_API.G_RET_STS_ERROR;
6980 -- Cash Flows exists. So, fetch the Cash Flow Levels
6981 FOR t_rec in lq_cash_flow_levels_csr( l_cash_flow_rec.caf_id )
6982 LOOP
6983 l_cash_flow_det_tbl(cfl_index).cfl_id := t_rec.cfl_id;
6984 l_cash_flow_det_tbl(cfl_index).caf_id := t_rec.caf_id;
6985 l_cash_flow_det_tbl(cfl_index).fqy_code := l_srt_details.frequency_code;
6986 -- Effective Rate from SRT = Rate + Spread + Adj Matrix
6987 l_cash_flow_det_tbl(cfl_index).rate :=
6988 l_srt_details.srt_rate + nvl(l_srt_details.spread,0) + nvl(l_adj_factor,0);
6989 IF nvl( l_srt_details.min_adj_rate,l_cash_flow_det_tbl(cfl_index).rate) >
6990 l_cash_flow_det_tbl(cfl_index).rate
6991 THEN
6992 l_cash_flow_det_tbl(cfl_index).rate := l_srt_details.min_adj_rate;
6993 ELSIF nvl( l_srt_details.max_adj_rate, l_cash_flow_det_tbl(1).rate) <
6994 l_cash_flow_det_tbl(cfl_index).rate
6995 THEN
6996 l_cash_flow_det_tbl(cfl_index).rate := l_srt_details.max_adj_rate;
6997 END IF;
6998 l_cash_flow_det_tbl(cfl_index).stub_days := t_rec.stub_days;
6999 l_cash_flow_det_tbl(cfl_index).stub_amount := t_rec.stub_amount;
7000 l_cash_flow_det_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
7001 l_cash_flow_det_tbl(cfl_index).amount := t_rec.amount;
7002 l_cash_flow_det_tbl(cfl_index).start_date := t_rec.start_date;
7003 -- Remember the flag whether its a stub payment or not
7004 IF t_rec.stub_days IS NOT NULL and t_rec.stub_amount IS NOT NULL
7005 THEN
7006 -- Stub Payment
7007 l_cash_flow_det_tbl(cfl_index).is_stub := 'Y';
7008 ELSE
7009 -- Regular Periodic Payment
7010 l_cash_flow_det_tbl(cfl_index).is_stub := 'N';
7011 END IF;
7012 -- Use l_retun_status as a flag
7013 l_return_status := OKL_API.G_RET_STS_SUCCESS;
7014 -- Increment i
7015 cfl_index := cfl_index + 1;
7016 END LOOP;
7017 ELSE
7018 l_return_status := OKL_API.G_RET_STS_SUCCESS;
7019 END IF;
7020 END IF;
7021 -- Get the Day convention from the SRT itself !
7022 x_days_in_year := l_srt_details.day_convention_code;
7023 IF x_days_in_year = '360'
7024 THEN
7025 x_days_in_month := '30';
7026 ELSIF x_days_in_year = '365' OR x_days_in_year = 'ACTUAL'
7027 THEN
7028 x_days_in_month := 'ACTUAL';
7029 END IF;
7030 ELSIF p_pricing_method = 'TR'
7031 THEN
7032 -- Fetch the target column values ..
7033 OPEN quote_csr(qteid => l_lq_id );
7034 FETCH quote_csr INTO quote_rec;
7035 CLOSE quote_csr;
7036 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7037 'After fetching the quote_csr details ');
7038 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7039 'Building the Cash flows n Inflows ' || p_pricing_method );
7040 -- Populating the Cash flows
7041 IF p_cf_source = G_CF_SOURCE_LQ_FEE
7042 THEN
7043 -- For Rollover/Financed fee, though the PM is TR, where LLO is not applicable
7044 -- there also, pricing will fetch Adv/Arrears, Rate, Frequency will be fetched
7045 -- from the quote, but the Payment Stream ID will be store in the okl_fees_b.payment_sty_id
7046 FOR t_rec IN fee_details_csr( p_id )
7047 LOOP
7048 l_cash_flow_rec.sty_id := t_rec.payment_type_id;
7049 END LOOP;
7050 END IF;
7051 l_cash_flow_rec.sts_code := 'CURRENT'; -- Added for bug 13769881
7052 l_cash_flow_rec.due_arrears_yn := quote_rec.target_arrears;
7053 l_cash_flow_rec.start_date := quote_rec.expected_start_date;
7054 -- Populating the Cash flow levels
7055 l_cash_flow_det_tbl(1).fqy_code := quote_rec.target_frequency;
7056 l_cash_flow_det_tbl(1).rate := quote_rec.target_rate; -- Rate is being stored as Percentage
7057 l_cash_flow_det_tbl(1).is_stub := 'N';
7058 l_cash_flow_det_tbl(1).start_date := quote_rec.expected_start_date;
7059 l_cash_flow_det_tbl(1).number_of_periods := quote_rec.target_periods;
7060 -- Need to fetch the CFL Id for the Updation
7061 FOR t_rec IN get_cfl_id_csr( qteId => p_id )
7062 LOOP
7063 l_cash_flow_rec.caf_id := t_rec.caf_id;
7064 l_cash_flow_rec.cfo_id := t_rec.cfo_id;
7065 l_cash_flow_rec.sty_id := t_rec.stream_type_id;
7066 l_cash_flow_det_tbl(1).cfl_id := t_rec.cfl_id;
7067 END LOOP;
7068 get_lq_sgt_day_convention(
7069 p_api_version => p_api_version,
7070 p_init_msg_list => p_init_msg_list,
7071 x_return_status => l_return_status,
7072 x_msg_count => x_msg_count,
7073 x_msg_data => x_msg_data,
7074 p_lq_id => p_id,
7075 x_days_in_month => x_days_in_month,
7076 x_days_in_year => x_days_in_year);
7077 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7078 ': After Fetching the Day convention from the SGT - TR ' );
7079 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7080 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7081 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7082 RAISE OKL_API.G_EXCEPTION_ERROR;
7083 END IF;
7084 ELSE
7085 -- Assuming that the Asset is having Structured Pricing overridden
7086 -- from that of the Payment Structure defined at the Lease Quote level
7087 get_qq_cash_flows(
7088 p_api_version => p_api_version,
7089 p_init_msg_list => p_init_msg_list,
7090 x_return_status => l_return_status,
7091 x_msg_count => x_msg_count,
7092 x_msg_data => x_msg_data,
7093 p_cf_source_type => p_cf_source, -- Pass the source type OKL_ASSETS_B/OKL_LEASE_QUOTES_B
7094 p_qq_id => p_id, -- Pass the id of the Assets/ Lease Quote !
7095 x_days_in_month => x_days_in_month,
7096 x_days_in_year => x_days_in_year,
7097 x_cash_flow_rec => l_cash_flow_rec, -- Cash Flow Record
7098 x_cash_flow_det_tbl => l_cash_flow_det_tbl); -- Cash Flow Details Table
7099 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7100 'After get_qq_cash_flows ' || l_return_status );
7101 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7102 'l_cash_flow_det_tbl.COUNT ' || l_cash_flow_det_tbl.COUNT);
7103 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7104 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7105 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7106 RAISE OKL_API.G_EXCEPTION_ERROR;
7107 END IF;
7108 END IF; -- IF p_qq_hdr_rec.pricing_method
7109 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7110 ': Built the Cash flows and Levels ' );
7111 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7112 'Arrears = ' || l_cash_flow_rec.due_arrears_yn
7113 || 'Start Date=' || l_cash_flow_rec.start_date );
7114 IF l_cash_flow_det_tbl.COUNT > 0
7115 THEN
7116 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7117 ': Frequency | Rate | Stub Amount | Stub Days | Periods | Amount | Start Date ' );
7118 FOR t IN l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
7119 LOOP
7120 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7121 l_cash_flow_det_tbl(t).fqy_code || '|' || l_cash_flow_det_tbl(t).rate
7122 || '|' || l_cash_flow_det_tbl(t).stub_days || '|' || l_cash_flow_det_tbl(t).stub_amount
7123 || '|' || l_cash_flow_det_tbl(t).number_of_periods
7124 || '|' || l_cash_flow_det_tbl(t).amount || '|' || l_cash_flow_det_tbl(t).start_date
7125 || '|' || l_cash_flow_det_tbl(t).is_stub );
7126 END LOOP;
7127 END IF;
7128 -- Setting up the return variables
7129 x_cash_flow_rec := l_cash_flow_rec;
7130 x_cash_flow_det_tbl := l_cash_flow_det_tbl;
7131 x_return_status := l_return_status;
7132
7133 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
7134 x_msg_data => x_msg_data);
7135 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
7136 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
7137 EXCEPTION
7138 WHEN OKL_API.G_EXCEPTION_ERROR THEN
7139 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
7140 p_api_name => l_api_name,
7141 p_pkg_name => G_PKG_NAME,
7142 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
7143 x_msg_count => x_msg_count,
7144 x_msg_data => x_msg_data,
7145 p_api_type => g_api_type);
7146 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
7147 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
7148 p_api_name => l_api_name,
7149 p_pkg_name => G_PKG_NAME,
7150 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
7151 x_msg_count => x_msg_count,
7152 x_msg_data => x_msg_data,
7153 p_api_type => g_api_type);
7154 WHEN OTHERS THEN
7155 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
7156 p_api_name => l_api_name,
7157 p_pkg_name => G_PKG_NAME,
7158 p_exc_name => 'OTHERS',
7159 x_msg_count => x_msg_count,
7160 x_msg_data => x_msg_data,
7161 p_api_type => g_api_type);
7162 END get_lq_cash_flows;
7163
7164 -- API to price a quick quote... Just need to pass me the ID ;-)
7165 PROCEDURE price_quick_quote(
7166 p_api_version IN NUMBER,
7167 p_init_msg_list IN VARCHAR2,
7168 x_return_status OUT NOCOPY VARCHAR2,
7169 x_msg_count OUT NOCOPY NUMBER,
7170 x_msg_data OUT NOCOPY VARCHAR2,
7171 p_qq_id IN NUMBER,
7172 x_yileds_rec OUT NOCOPY yields_rec,
7173 x_subsidized_yileds_rec OUT NOCOPY yields_rec,
7174 x_pricing_results_tbl OUT NOCOPY pricing_results_tbl_type )
7175 IS
7176 -- Cursor to fetch EOT Type
7177 CURSOR get_eot_type( p_qq_id NUMBER )
7178 IS
7179 SELECT qq.id
7180 ,qq.reference_number
7181 ,eot.end_of_term_name
7182 ,eot.eot_type_code eot_type_code
7183 ,eot.end_of_term_id end_of_term_id
7184 ,eotversion.end_of_term_ver_id
7185 FROM OKL_QUICK_QUOTES_B qq,
7186 okl_fe_eo_term_vers eotversion,
7187 okl_fe_eo_terms_all_b eot
7188 WHERE qq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
7189 AND eot.end_of_term_id = eotversion.end_of_term_id
7190 AND qq.id = p_qq_id;
7191
7192 --Bug 5884825 PAGARG start
7193 CURSOR get_product_name( p_qq_id NUMBER )
7194 IS
7195 SELECT PDT.NAME PRODUCTNAME
7196 FROM OKL_QUICK_QUOTES_B QQ
7197 , OKL_FE_EO_TERM_VERS EOTVERSION
7198 , OKL_FE_EO_TERMS_ALL_B EOT
7199 , OKL_PRODUCTS PDT
7200 WHERE QQ.END_OF_TERM_OPTION_ID = EOTVERSION.END_OF_TERM_VER_ID
7201 AND EOT.END_OF_TERM_ID = EOTVERSION.END_OF_TERM_ID
7202 AND PDT.ID = EOT.PRODUCT_ID
7203 AND QQ.ID = P_QQ_ID;
7204 --Bug 5884825 PAGARG End
7205
7206 -- Local Variables
7207 l_product_name okl_products.NAME%TYPE;--Bug 5884825 PAGARG
7208 l_api_version CONSTANT NUMBER DEFAULT 1.0;
7209 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'price_quick_quote';
7210 l_return_status VARCHAR2(1);
7211 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
7212 || G_PKG_NAME || '.' || UPPER(l_api_name);
7213 l_debug_enabled VARCHAR2(10);
7214 is_debug_procedure_on BOOLEAN;
7215 is_debug_statement_on BOOLEAN;
7216 -- Declarations
7217 l_valid_pm BOOLEAN; -- Flag holding true/false for valid Pricing Method
7218 l_tot_item_cat_amount NUMBER;
7219 l_tot_rent_payment NUMBER;
7220 l_tot_eot_amount NUMBER;
7221 l_eot_percentage NUMBER;
7222 l_oec NUMBER;
7223 l_hdr_rec so_hdr_rec_type;
7224 l_item_cat_tbl so_asset_details_tbl_type;
7225 l_residual_strms_tbl cash_inflows_tbl_type;
7226 l_pricing_parameters_rec pricing_parameter_rec_type;
7227 l_pricing_parameters_tbl pricing_parameter_tbl_type;
7228 l_pricing_parameters_tbl_cp pricing_parameter_tbl_type;
7229 l_tmp_prc_params_tbl pricing_parameter_tbl_type;
7230 pp_index NUMBER; -- Index for the l_pricing_parameters_tbl
7231 l_fin_adj_rec so_amt_details_rec_type;
7232 l_cash_flow_rec so_cash_flows_rec_type;
7233 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
7234 l_fee_srv_tbl so_fee_srv_tbl_type;
7235 l_strm_ele_tbl cash_inflows_tbl_type;
7236 l_dummy_strm_ele_tbl cash_inflows_tbl_type;
7237 l_eot_date DATE;
7238 l_iir NUMBER;
7239 l_irr NUMBER;
7240 l_bk_yield NUMBER;
7241 l_cf_dpp NUMBER;
7242 l_cf_ppy NUMBER;
7243 l_day_count_method VARCHAR2(30);
7244 l_days_in_month VARCHAR2(30);
7245 l_days_in_year VARCHAR2(30);
7246 l_miss_payment NUMBER;
7247 l_yields_rec yields_rec;
7248 l_subsidized_yields_rec yields_rec;
7249 l_qqlv_rec OKL_QQL_PVT.qqlv_rec_type;
7250 x_qqlv_rec OKL_QQL_PVT.qqlv_rec_type;
7251 x_termination_tbl cash_inflows_tbl_type;
7252 x_pre_tax_inc_tbl cash_inflows_tbl_type;
7253 i NUMBER;
7254 res_index NUMBER := 1;
7255 l_frequency VARCHAR2(30);
7256 l_item_cat_cf_tbl item_cat_cf_tbl_type;
7257 l_tmp_pp_index NUMBER;
7258 l_sgt_days_in_month VARCHAR2(30);
7259 l_sgt_days_in_year VARCHAR2(30);
7260 l_sgt_day_count_method VARCHAR2(30);
7261 l_eot_type_code VARCHAR2(30);
7262 l_net_percent NUMBER;
7263 l_net_financed_amount NUMBER;
7264 l_closing_balance NUMBER;
7265 l_residual_percent NUMBER;
7266 l_residual_int_factor NUMBER;
7267 l_net_adj_amt NUMBER;
7268 BEGIN
7269 l_return_status := OKL_API.G_RET_STS_SUCCESS;
7270 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
7271 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
7272 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
7273 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
7274 -- check for logging on STATEMENT level
7275 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
7276 -- Call START_ACTIVITY to create savepoint, check compatibility
7277 -- and initialize message list
7278 l_return_status := OKL_API.START_ACTIVITY(
7279 p_api_name => l_api_name,
7280 p_pkg_name => G_PKG_NAME,
7281 p_init_msg_list => p_init_msg_list,
7282 l_api_version => l_api_version,
7283 p_api_version => p_api_version,
7284 p_api_type => g_api_type,
7285 x_return_status => x_return_status);
7286 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7287 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7288 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7289 RAISE OKL_API.G_EXCEPTION_ERROR;
7290 END IF;
7291 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7292 ': p_qq_id ' || p_qq_id );
7293
7294 --Bug 5884825 PAGARG start
7295 OPEN get_product_name(p_qq_id);
7296 FETCH get_product_name INTO l_product_name;
7297 CLOSE get_product_name;
7298 --Bug 5884825 PAGARG end
7299
7300 -- Fetch the Header Details such as Start Date, Term, Pricing Method .. etc
7301 get_so_hdr(
7302 p_api_version => p_api_version,
7303 p_init_msg_list => p_init_msg_list,
7304 x_return_status => l_return_status,
7305 x_msg_count => x_msg_count,
7306 x_msg_data => x_msg_data,
7307 p_so_id => p_qq_id,
7308 p_so_type => 'QQ',
7309 x_so_hdr_rec => l_hdr_rec );
7310 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7311 'After get_so_hdr ' || l_return_status );
7312 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7313 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7314 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7315 RAISE OKL_API.G_EXCEPTION_ERROR;
7316 END IF;
7317 -- Validate the Pricing Method for Quick Quote
7318 -- RC, SF, SP, SS, SY, TR are the permitted pricing methods for the Quick Quote
7319 l_valid_pm := validate_pricing_method(
7320 p_pricing_method => l_hdr_rec.pricing_method,
7321 p_object_type => 'QQ',
7322 x_return_status => l_return_status);
7323 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7324 'After validate_pricing_method ' || l_return_status );
7325 IF l_valid_pm
7326 THEN
7327 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7328 'l_valid_pm = TRUE' );
7329 ELSE
7330 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7331 'l_valid_pm = FALSE' );
7332 END IF;
7333 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7334 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7335 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7336 RAISE OKL_API.G_EXCEPTION_ERROR;
7337 END IF;
7338 -- If Pricing Method is invalid .. raise exception ..
7339 IF l_valid_pm = FALSE
7340 THEN
7341 -- Display a message and raise an exception ..
7342 OKL_API.SET_MESSAGE(
7343 p_app_name => g_app_name,
7344 p_msg_name => g_invalid_value,
7345 p_token1 => g_col_name_token,
7346 p_token1_value => 'Pricing Method');
7347 RAISE OKL_API.G_EXCEPTION_ERROR;
7348 END IF;
7349 -- Know the type of the EOT and then proceed with the values directly or calculate the amount
7350 FOR t_rec IN get_eot_type( p_qq_id => p_qq_id )
7351 LOOP
7352 l_eot_type_code := t_rec.eot_type_code;
7353 END LOOP;
7354 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7355 'l_eot_type_code=' || l_eot_type_code );
7356 -- Get Item Costs, Residual Values
7357 get_qq_item_cat_details(
7358 p_api_version => p_api_version,
7359 p_init_msg_list => p_init_msg_list,
7360 x_return_status => l_return_status,
7361 x_msg_count => x_msg_count,
7362 x_msg_data => x_msg_data,
7363 p_qq_id => p_qq_id,
7364 p_pricing_method => l_hdr_rec.pricing_method,
7365 x_asset_amounts_tbl => l_item_cat_tbl);
7366 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7367 'After get_qq_item_cat_details ' || l_return_status );
7368 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7369 'l_item_cat_tbl.COUNT ' || l_item_cat_tbl.COUNT );
7370 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7371 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7372 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7373 RAISE OKL_API.G_EXCEPTION_ERROR;
7374 END IF;
7375 -- Loop through the Item Category Table and determine the Total Item Cat Cost
7376 l_tot_item_cat_amount := 0;
7377 l_tot_eot_amount := 0;
7378 IF l_hdr_rec.pricing_method <> 'SF' AND
7379 l_item_cat_tbl IS NOT NULL AND
7380 l_item_cat_tbl.COUNT > 0
7381 THEN
7382 FOR i in l_item_cat_tbl.FIRST .. l_item_cat_tbl.LAST
7383 LOOP
7384 l_tot_item_cat_amount := l_tot_item_cat_amount + nvl( l_item_cat_tbl(i).asset_cost,0);
7385 END LOOP;
7386 END IF;
7387 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7388 'l_tot_item_cat_amount =' || l_tot_item_cat_amount );
7389 -- Calculate the total End of term value amount
7390 l_tot_eot_amount := 0;
7391 IF l_item_cat_tbl IS NOT NULL AND
7392 l_item_cat_tbl.COUNT > 0
7393 THEN
7394 FOR itc_index in l_item_cat_tbl.FIRST .. l_item_cat_tbl.LAST
7395 LOOP
7396 l_tot_eot_amount := l_tot_eot_amount + l_item_cat_tbl(itc_index).end_of_term_amount;
7397 END LOOP;
7398 END IF;
7399 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7400 'l_tot_eot_amount =' || l_tot_eot_amount );
7401 -- Get Finance Adjustment Details
7402 -- like down payment, trade in, subsidy
7403 get_qq_fin_adj_details(
7404 p_api_version => p_api_version,
7405 p_init_msg_list => p_init_msg_list,
7406 x_return_status => l_return_status,
7407 x_msg_count => x_msg_count,
7408 x_msg_data => x_msg_data,
7409 p_qq_id => p_qq_id,
7410 p_pricing_method => l_hdr_rec.pricing_method,
7411 p_item_category_amount => l_tot_item_cat_amount,
7412 x_all_amounts_rec => l_fin_adj_rec);
7413 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7414 'After get_qq_fin_adj_details ' || l_return_status );
7415 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7416 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7417 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7418 RAISE OKL_API.G_EXCEPTION_ERROR;
7419 END IF;
7420 -- Possibly now, we can build the Pricing Parameter Record
7421 l_pricing_parameters_rec.financed_amount := l_tot_item_cat_amount;
7422 l_pricing_parameters_rec.trade_in := l_fin_adj_rec.tradein_amount;
7423 l_pricing_parameters_rec.down_payment := l_fin_adj_rec.down_payment_amount;
7424 l_pricing_parameters_rec.subsidy := l_fin_adj_rec.subsidy_amount;
7425
7426 -- Calculate the eot percentage using the formula
7427 -- ( l_tot_eot_amount / l_tot_item_cat_amount - subsidy - downpayment - trade in ) * 100
7428 l_eot_percentage := 0;
7429 IF l_hdr_rec.pricing_method <> 'SF'
7430 THEN
7431 -- Need to deduct the Trade_in, Subsidy, Down Payment values from the
7432 get_qq_asset_oec (
7433 p_api_version => p_api_version,
7434 p_init_msg_list => p_init_msg_list,
7435 x_return_status => l_return_status,
7436 x_msg_count => x_msg_count,
7437 x_msg_data => x_msg_data,
7438 p_asset_cost => l_tot_item_cat_amount,
7439 p_fin_adj_det_rec => l_fin_adj_rec,
7440 x_oec => l_oec);
7441 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7442 'After get_qq_asset_oec ' || l_return_status );
7443 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7444 'l_oec=' || nvl( l_oec, 0 ) );
7445 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7446 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7447 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7448 RAISE OKL_API.G_EXCEPTION_ERROR;
7449 END IF;
7450 l_eot_percentage := ( l_tot_eot_amount / l_oec ) * 100; -- EOT Percentage;
7451 END IF;
7452 IF l_hdr_rec.pricing_method = 'RC' -- Rate card pricing
7453 THEN
7454 -- Build the cash flows when the pricing method is Rate Card !
7455 get_qq_rc_cash_flows(
7456 p_api_version => p_api_version,
7457 p_init_msg_list => p_init_msg_list,
7458 x_return_status => l_return_status,
7459 x_msg_count => x_msg_count,
7460 x_msg_data => x_msg_data,
7461 p_qq_hdr_rec => l_hdr_rec,
7462 x_days_in_month => l_days_in_month,
7463 x_days_in_year => l_days_in_year,
7464 x_item_cat_cf_tbl => l_item_cat_cf_tbl);
7465 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7466 'After get_qq_rc_cash_flows ' || l_return_status );
7467 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7468 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7469 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7470 RAISE OKL_API.G_EXCEPTION_ERROR;
7471 END IF;
7472 -- The frequency needs to be fetched from the target_frequency
7473 l_frequency := l_item_cat_cf_tbl(1).cash_flow_level_tbl(1).fqy_code;
7474 ELSE
7475 -- Retrieve or build the Cash flows and Levels when user picked
7476 -- Structured pricing / SRT ..
7477 -- Modifying this API to fetch you the pricing day convention
7478 get_qq_cash_flows(
7479 p_api_version => p_api_version,
7480 p_init_msg_list => p_init_msg_list,
7481 x_return_status => l_return_status,
7482 x_msg_count => x_msg_count,
7483 x_msg_data => x_msg_data,
7484 p_qq_hdr_rec => l_hdr_rec,
7485 p_eot_percentage => l_eot_percentage,
7486 p_oec => l_oec,
7487 x_days_in_month => l_days_in_month,
7488 x_days_in_year => l_days_in_year,
7489 x_cash_flow_rec => l_cash_flow_rec, -- Cash Flow Record
7490 x_cash_flow_det_tbl => l_cash_flow_det_tbl); -- Cash Flow Details Table
7491 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7492 'After get_qq_cash_flows ' || l_return_status );
7493 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7494 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7495 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7496 RAISE OKL_API.G_EXCEPTION_ERROR;
7497 END IF;
7498 -- Generate the Streams
7499 IF l_cash_flow_det_tbl IS NOT NULL AND
7500 l_cash_flow_det_tbl.COUNT > 0
7501 THEN
7502 -- Initialize the Strm Count to Zero
7503 gen_so_cf_strms(
7504 p_api_version => p_api_version,
7505 p_init_msg_list => p_init_msg_list,
7506 x_return_status => l_return_status,
7507 x_msg_count => x_msg_count,
7508 x_msg_data => x_msg_data,
7509 p_cash_flow_rec => l_cash_flow_rec,
7510 p_cf_details_tbl => l_cash_flow_det_tbl,
7511 x_cash_inflow_strms_tbl => l_strm_ele_tbl);
7512 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7513 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7514 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7515 RAISE OKL_API.G_EXCEPTION_ERROR;
7516 END IF;
7517 l_frequency := l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code;
7518 ELSE
7519 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7520 'No Cash flow and Cash flow Levels obtained ! ' );
7521 OKL_API.SET_MESSAGE (
7522 p_app_name => G_APP_NAME,
7523 p_msg_name => 'OKL_LLA_PMT_SELECT');
7524 RAISE OKL_API.G_EXCEPTION_ERROR;
7525 END IF;
7526 END IF; -- IF on Rate Card Pricing Method ..
7527 -- Build the Residuals Table
7528 IF l_item_cat_tbl IS NOT NULL AND
7529 l_item_cat_tbl.COUNT > 0
7530 THEN
7531 okl_stream_generator_pvt.add_months_new(
7532 p_start_date => l_hdr_rec.expected_start_date,
7533 p_months_after => l_hdr_rec.term,
7534 x_date => l_eot_date,
7535 x_return_status => l_return_status);
7536 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7537 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7538 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7539 RAISE OKL_API.G_EXCEPTION_ERROR;
7540 END IF;
7541 l_eot_date := l_eot_date - 1;
7542 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7543 'QQ End date: ' || l_eot_date);
7544 -- Get the DPP and PPY inorder to populate for the Residuals Table
7545 get_dpp_ppy(
7546 p_frequency => l_frequency,
7547 x_dpp => l_cf_dpp,
7548 x_ppy => l_cf_ppy,
7549 x_return_status => l_return_status );
7550 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7551 'After get_dpp_ppy : ' || l_return_status);
7552 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7553 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7554 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7555 RAISE OKL_API.G_EXCEPTION_ERROR;
7556 END IF;
7557 IF l_hdr_rec.pricing_method <> 'RC'
7558 THEN
7559 FOR i in l_item_cat_tbl.FIRST .. l_item_cat_tbl.LAST
7560 LOOP
7561 l_residual_strms_tbl(i).line_number := i;
7562 l_residual_strms_tbl(i).cf_amount := l_item_cat_tbl(i).end_of_term_amount;
7563 l_residual_strms_tbl(i).cf_date := l_eot_date;
7564 l_residual_strms_tbl(i).cf_miss_pay := 'N';
7565 l_residual_strms_tbl(i).is_stub := 'N';
7566 l_residual_strms_tbl(i).is_arrears := 'Y';
7567 l_residual_strms_tbl(i).cf_dpp := l_cf_dpp;
7568 l_residual_strms_tbl(i).cf_ppy := l_cf_ppy;
7569 END LOOP;
7570 END IF; -- IF l_hdr_rec.pricing_method <> 'RC'
7571 END IF;
7572 pp_index := 1;
7573 IF l_hdr_rec.pricing_method = 'RC'
7574 THEN
7575 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7576 'Populate the Cash Flows and Levels for all item categories ');
7577 -- Generate the Streams
7578 FOR t IN l_item_cat_cf_tbl.FIRST .. l_item_cat_cf_tbl.LAST
7579 LOOP
7580 l_pricing_parameters_tbl(pp_index).line_type := 'FREE_FORM1';
7581 l_pricing_parameters_tbl(pp_index).line_start_date := l_hdr_rec.expected_start_date;
7582 l_pricing_parameters_tbl(pp_index).financed_amount := l_item_cat_cf_tbl(t).financed_amount;
7583 l_pricing_parameters_tbl(pp_index).down_payment := l_item_cat_cf_tbl(t).down_payment;
7584 l_pricing_parameters_tbl(pp_index).subsidy := l_item_cat_cf_tbl(t).subsidy;
7585 l_pricing_parameters_tbl(pp_index).trade_in := l_item_cat_cf_tbl(t).trade_in;
7586
7587 -- Storing the residual streams ..
7588 res_index := 1;
7589 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).line_number := res_index;
7590 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_amount := l_item_cat_cf_tbl(t).eot_amount;
7591 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_date := l_eot_date;
7592 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_miss_pay := 'N';
7593 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).is_stub := 'N';
7594 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).is_arrears := 'Y';
7595 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_dpp := l_cf_dpp;
7596 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_ppy := l_cf_ppy;
7597
7598 IF l_item_cat_cf_tbl(t).cash_flow_level_tbl IS NOT NULL AND
7599 l_item_cat_cf_tbl(t).cash_flow_level_tbl.COUNT > 0
7600 THEN
7601 -- Initialize the Strm Count to Zero
7602 gen_so_cf_strms(
7603 p_api_version => p_api_version,
7604 p_init_msg_list => p_init_msg_list,
7605 x_return_status => l_return_status,
7606 x_msg_count => x_msg_count,
7607 x_msg_data => x_msg_data,
7608 p_cash_flow_rec => l_item_cat_cf_tbl(t).cash_flow_rec,
7609 p_cf_details_tbl => l_item_cat_cf_tbl(t).cash_flow_level_tbl,
7610 x_cash_inflow_strms_tbl => l_strm_ele_tbl);
7611 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7612 'After gen_so_cf_strms ' || l_return_status );
7613 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7614 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7615 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7616 RAISE OKL_API.G_EXCEPTION_ERROR;
7617 END IF;
7618 ELSE
7619 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7620 'No Cash flow and Cash flow Levels obtained ! ' );
7621 OKL_API.SET_MESSAGE (
7622 p_app_name => G_APP_NAME,
7623 p_msg_name => 'OKL_LLA_PMT_SELECT');
7624 RAISE OKL_API.G_EXCEPTION_ERROR;
7625 END IF;
7626 l_pricing_parameters_tbl(pp_index).cash_inflows := l_strm_ele_tbl;
7627 l_strm_ele_tbl.DELETE;
7628 -- Increment the pricing param index ..
7629 pp_index := pp_index + 1;
7630 END LOOP;
7631 -- Remember the pp_index count ... for calling the IIR !!
7632 l_tmp_pp_index := pp_index - 1;
7633 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7634 'No. of Item Pricing Params built for RC (l_tmp_pp_index ) ' || l_tmp_pp_index );
7635 ELSE
7636 -- Build the pricing param rec with line type as FREE_FORM1
7637 l_pricing_parameters_rec.residual_inflows := l_residual_strms_tbl;
7638 l_pricing_parameters_rec.cash_inflows := l_strm_ele_tbl;
7639 -- Build the pricing parameters table !!
7640 l_pricing_parameters_tbl(pp_index) := l_pricing_parameters_rec;
7641 l_pricing_parameters_tbl(pp_index).line_type := 'FREE_FORM1';
7642 -- Increment the pp_index ...
7643 pp_index := pp_index + 1;
7644 END IF;
7645 -- Initialize things common for various Pricing Methods
7646 -- Assigning the day count methods !
7647 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7648 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
7649 get_day_count_method(
7650 p_days_in_month => l_days_in_month,
7651 p_days_in_year => l_days_in_year,
7652 x_day_count_method => l_day_count_method,
7653 x_return_status => l_return_status );
7654 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7655 'After get_day_count_method ' || l_return_status);
7656 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7657 'l_day_count_method = ' || l_day_count_method);
7658 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7659 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7660 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7661 --Bug 5884825 PAGARG start
7662 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
7663 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
7664 p_token1 => 'PRODUCT_NAME',
7665 p_token1_value => l_product_name);
7666 --Bug 5884825 PAGARG end
7667 RAISE OKL_API.G_EXCEPTION_ERROR;
7668 END IF;
7669 IF l_hdr_rec.rate_template_id IS NOT NULL
7670 THEN
7671 -- Fetch the day convention from the Stream Generation Template ...
7672 -- only if the user has picked the SRT otherwise while building the cash flows
7673 -- itself, we would have fetched the day convention from the SGT.
7674 get_qq_sgt_day_convention(
7675 p_api_version => p_api_version,
7676 p_init_msg_list => p_init_msg_list,
7677 x_return_status => l_return_status,
7678 x_msg_count => x_msg_count,
7679 x_msg_data => x_msg_data,
7680 p_qq_id => p_qq_id,
7681 x_days_in_month => l_sgt_days_in_month,
7682 x_days_in_year => l_sgt_days_in_year);
7683 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7684 'After get_qq_sgt_day_convention ' || l_return_status );
7685 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7686 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7687 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7688 RAISE OKL_API.G_EXCEPTION_ERROR;
7689 END IF;
7690 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7691 'SGT Day convention: ' || l_days_in_month || ' / ' || l_days_in_year);
7692 -- Get the day convention ..
7693 get_day_count_method(
7694 p_days_in_month => l_sgt_days_in_month,
7695 p_days_in_year => l_sgt_days_in_year,
7696 x_day_count_method => l_sgt_day_count_method,
7697 x_return_status => l_return_status );
7698 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7699 '2/ After get_day_count_method ' || l_return_status);
7700 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7701 'l_sgt_day_count_method = ' || l_sgt_day_count_method);
7702 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7703 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7704 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7705 --Bug 5884825 PAGARG start
7706 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
7707 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
7708 p_token1 => 'PRODUCT_NAME',
7709 p_token1_value => l_product_name);
7710 --Bug 5884825 PAGARG end
7711 RAISE OKL_API.G_EXCEPTION_ERROR;
7712 END IF;
7713 ELSE
7714 -- The day convention returned by the get_qq_rc_cash_flows / get_qq_cash_flows
7715 -- will be from the SGT already, so just store them in the SGT day convention variables.
7716 l_sgt_days_in_month := l_days_in_month;
7717 l_sgt_days_in_year := l_days_in_year;
7718 l_sgt_day_count_method := l_day_count_method;
7719 END IF;
7720 --------------------------------------------------------------------------------
7721 -- Solving for Missing Parameter
7722 --------------------------------------------------------------------------------
7723 -- We now have all the parameters in the tables to pass to the compute_iir api ..
7724 IF l_hdr_rec.pricing_method = 'SF' AND
7725 (l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
7726 THEN
7727 l_hdr_rec.pricing_method := 'SFP';
7728 END IF;
7729 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7730 'Before compute_iir l_hdr_rec.pricing_method=' || l_hdr_rec.pricing_method || ' | l_eot_type_code = ' || l_eot_type_code);
7731 IF l_hdr_rec.pricing_method = 'SP' OR
7732 l_hdr_rec.pricing_method = 'SF' OR
7733 l_hdr_rec.pricing_method = 'SS' OR
7734 ( l_hdr_rec.pricing_method = 'TR' AND
7735 l_hdr_rec.target_rate_type = 'IIR') -- Target Rate and Interest Type is IIR
7736 THEN
7737 -- Compute iir !!
7738 compute_iir(
7739 p_api_version => p_api_version,
7740 p_init_msg_list => p_init_msg_list,
7741 x_return_status => l_return_status,
7742 x_msg_count => x_msg_count,
7743 x_msg_data => x_msg_data,
7744 p_start_date => l_hdr_rec.expected_start_date,
7745 p_day_count_method => l_day_count_method,
7746 p_pricing_method => l_hdr_rec.pricing_method,
7747 p_initial_guess => 0.1,
7748 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
7749 px_iir => l_iir,
7750 x_payment => l_miss_payment);
7751 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7752 'After compute_iir ' || l_return_status );
7753 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7754 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7755 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7756 RAISE OKL_API.G_EXCEPTION_ERROR;
7757 END IF;
7758 IF l_hdr_rec.pricing_method = 'SP' OR
7759 (l_hdr_rec.pricing_method = 'TR' AND
7760 l_hdr_rec.target_rate_type = 'IIR' )
7761 THEN
7762 IF l_miss_payment < 0
7763 THEN
7764 OKL_API.SET_MESSAGE (
7765 p_app_name => G_APP_NAME,
7766 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
7767 p_token1 => 'TYPE',
7768 p_token1_value => 'Payment',
7769 p_token2 => 'AMOUNT',
7770 p_token2_value => round(l_miss_payment,2) );
7771 RAISE okl_api.g_exception_error;
7772 END IF;
7773 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7774 ' SOLVED PAYMENT AMOUNT : ' || l_miss_payment );
7775 -- Populate back the missing payment amount in all the stream elements
7776 FOR t_index IN l_pricing_parameters_tbl(1).cash_inflows.FIRST ..
7777 l_pricing_parameters_tbl(1).cash_inflows.LAST
7778 LOOP
7779 l_pricing_parameters_tbl(1).cash_inflows(t_index).cf_amount := l_miss_payment;
7780 END LOOP; -- Loop on l_pricing_parameters_tbl
7781 ELSIF l_hdr_rec.pricing_method = 'SF'
7782 THEN
7783 -- Solve for Financed Amount
7784 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7785 ' SOLVED FOR FINANCED AMOUNT ' || l_pricing_parameters_tbl(1).financed_amount );
7786 ELSIF l_hdr_rec.pricing_method = 'SS'
7787 THEN
7788 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7789 'SOLVED SUBSIDY AMOUNT ' || l_pricing_parameters_tbl(1).subsidy );
7790 IF l_pricing_parameters_tbl(1).subsidy < 0
7791 THEN
7792 OKL_API.SET_MESSAGE (
7793 p_app_name => G_APP_NAME,
7794 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
7795 p_token1 => 'TYPE',
7796 p_token1_value => 'Subsidy',
7797 p_token2 => 'AMOUNT',
7798 p_token2_value => round(l_pricing_parameters_tbl(1).subsidy,2) );
7799 RAISE okl_api.g_exception_error;
7800 END IF;
7801 END IF; -- IF on pricing method
7802 ELSIF l_hdr_rec.pricing_method = 'SFP'
7803 THEN
7804 -- Before calling the compute_iir_sfp, the pricing param rec, should
7805 -- not be passed with any asset cost, and adjustments with either
7806 -- FIXED or PERCENTAGE OF ASSET COST !
7807 compute_iir_sfp(
7808 p_api_version => p_api_version,
7809 p_init_msg_list => p_init_msg_list,
7810 x_return_status => l_return_status,
7811 x_msg_count => x_msg_count,
7812 x_msg_data => x_msg_data,
7813 p_start_date => l_hdr_rec.expected_start_date,
7814 p_day_count_method => l_day_count_method,
7815 p_pricing_method => l_hdr_rec.pricing_method,
7816 p_initial_guess => 0.1,
7817 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
7818 px_iir => l_iir,
7819 x_closing_balance => l_closing_balance,
7820 x_residual_percent => l_residual_percent,
7821 x_residual_int_factor => l_residual_int_factor);
7822 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7823 'After compute_iir_sfp ' || l_return_status );
7824 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7825 'Closing Balance | Residual Percent | l_residual_int_factor ' );
7826 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7827 round(l_closing_balance, 4) || ' | ' || round( l_residual_percent, 4) || ' | ' || round(l_residual_int_factor,4) );
7828 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7829 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7830 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7831 RAISE OKL_API.G_EXCEPTION_ERROR;
7832 END IF;
7833 END IF;
7834 IF l_hdr_rec.pricing_method = 'SF' OR
7835 l_hdr_rec.pricing_method = 'SFP'
7836 THEN
7837 --Need to manipulate the financial adjustments which are of type percentage ..
7838 -- Find the Financed Amount ( C-S-D-T, considering only D, T, S which are of type FIXED. )
7839 l_net_financed_amount := l_pricing_parameters_tbl(1).financed_amount;
7840 l_tot_item_cat_amount := l_pricing_parameters_tbl(1).financed_amount;
7841 -- Now sum the percentages of the D, T, S
7842 l_net_percent := 0;
7843 l_net_adj_amt := 0;
7844 IF l_fin_adj_rec.down_payment_basis <> 'FIXED'
7845 THEN
7846 l_net_percent := l_net_percent + nvl(l_fin_adj_rec.down_payment_value, 0);
7847 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7848 ' ** Down Payment %age ' || l_fin_adj_rec.down_payment_value );
7849 ELSE
7850 l_net_adj_amt := l_net_adj_amt + nvl(l_pricing_parameters_tbl(1).down_payment,0);
7851 END IF;
7852 IF l_fin_adj_rec.tradein_basis <> 'FIXED'
7853 THEN
7854 l_net_percent := l_net_percent + nvl(l_fin_adj_rec.tradein_value, 0);
7855 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7856 ' ** Tradein %age ' || l_fin_adj_rec.tradein_value );
7857 ELSE
7858 l_net_adj_amt := l_net_adj_amt + nvl(l_pricing_parameters_tbl(1).trade_in,0);
7859 END IF;
7860 IF l_fin_adj_rec.subsidy_basis_tbl.COUNT > 0
7861 THEN
7862 FOR t IN l_fin_adj_rec.subsidy_basis_tbl.FIRST ..
7863 l_fin_adj_rec.subsidy_basis_tbl.LAST
7864 LOOP
7865 IF l_fin_adj_rec.subsidy_basis_tbl(t) <> 'FIXED'
7866 THEN
7867 l_net_percent := l_net_percent + nvl(l_fin_adj_rec.subsidy_value_tbl(t), 0);
7868 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7869 ' ** Subsidy('||t|| ') %age ' || l_fin_adj_rec.tradein_value );
7870 END IF;
7871 END LOOP;
7872 END IF; -- Subsidies exists
7873 l_net_adj_amt := l_net_adj_amt + nvl(l_pricing_parameters_tbl(1).subsidy,0);
7874 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7875 ' Down Payment | Trade in | Subsidy ' );
7876 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7877 round(l_pricing_parameters_tbl(1).down_payment,4) || ' | ' ||
7878 round(l_pricing_parameters_tbl(1).trade_in,4) || ' | ' ||
7879 round(l_pricing_parameters_tbl(1).subsidy,4) );
7880 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7881 ' Financed Amount ' || round(l_net_financed_amount,4) || ' Total Percentage of Financial Adjustments ' || round(l_net_percent,4)
7882 || ' Total Adjustment Amount (FIXED)= ' || round( l_net_adj_amt, 4));
7883 IF l_hdr_rec.pricing_method = 'SFP'
7884 THEN
7885 l_pricing_parameters_tbl(1).financed_amount :=
7886 ( (l_closing_balance + l_net_adj_amt) /
7887 ( 1- (l_net_percent/100) - (l_residual_percent/l_residual_int_factor) ) );
7888 ELSIF l_hdr_rec.pricing_method = 'SF'
7889 THEN
7890 -- Find the Asset Cost C = F+[S++D+T]/(1-[S'+D'+T']/100)
7891 -- S,D,T are fixed financial adjustment amounts
7892 l_pricing_parameters_tbl(1).financed_amount := l_net_financed_amount / ( 1- l_net_percent / 100 );
7893 END IF;
7894 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7895 ' !!!! Asset Cost should be ' || l_pricing_parameters_tbl(1).financed_amount );
7896 IF l_net_percent > 0 AND
7897 l_net_percent <= 100
7898 THEN
7899 IF l_fin_adj_rec.down_payment_basis <> 'FIXED'
7900 THEN
7901 l_pricing_parameters_tbl(1).down_payment :=
7902 l_pricing_parameters_tbl(1).financed_amount * l_fin_adj_rec.down_payment_value/ 100;
7903 END IF;
7904 IF l_fin_adj_rec.tradein_basis <> 'FIXED'
7905 THEN
7906 l_pricing_parameters_tbl(1).trade_in := l_pricing_parameters_tbl(1).financed_amount
7907 * l_fin_adj_rec.tradein_value / 100;
7908 END IF;
7909 IF l_fin_adj_rec.subsidy_basis_tbl.COUNT > 0
7910 THEN
7911 FOR t IN l_fin_adj_rec.subsidy_basis_tbl.FIRST ..
7912 l_fin_adj_rec.subsidy_basis_tbl.LAST
7913 LOOP
7914 IF l_fin_adj_rec.subsidy_basis_tbl(t) <> 'FIXED'
7915 THEN
7916 l_pricing_parameters_tbl(1).subsidy := l_pricing_parameters_tbl(1).subsidy +
7917 ( l_pricing_parameters_tbl(1).financed_amount * l_fin_adj_rec.subsidy_value_tbl(t));
7918 END IF;
7919 END LOOP;
7920 END IF; -- If subsidies exists
7921 END IF;
7922 IF l_hdr_rec.pricing_method = 'SFP'
7923 THEN
7924 -- Still the calculation need to be done ..
7925 -- After pricing the EOT has to be calculated interms of amounts
7926 -- for pricing to calculate the yields further.
7927 FOR t_in IN l_pricing_parameters_tbl(1).residual_inflows.FIRST ..
7928 l_pricing_parameters_tbl(1).residual_inflows.LAST
7929 LOOP
7930 l_pricing_parameters_tbl(1).residual_inflows(t_in).cf_amount :=
7931 l_pricing_parameters_tbl(1).residual_inflows(t_in).cf_amount *
7932 l_pricing_parameters_tbl(1).financed_amount;
7933 END LOOP;
7934 END IF;
7935 END IF; -- IF pricing_method ='SF'/'SFP'
7936 -- If pricing method is RC, calculate the total Rent Payment amount, which
7937 -- needs to be passed in the get_fee_srvc_cash_flows
7938 -- Get the Total Rent Payment Amount
7939 -- For this loop through all the pricing params with line_type as FREE_FORM1
7940 -- and sumup the streams being passed there !
7941 l_tot_rent_payment := 0;
7942 FOR a IN l_pricing_parameters_tbl.FIRST .. l_pricing_parameters_tbl.LAST
7943 LOOP
7944 IF l_pricing_parameters_tbl(a).line_type = 'FREE_FORM1'
7945 THEN
7946 FOR b IN l_pricing_parameters_tbl(a).cash_inflows.FIRST ..
7947 l_pricing_parameters_tbl(a).cash_inflows.LAST
7948 LOOP
7949 l_tot_rent_payment := l_tot_rent_payment + nvl(l_pricing_parameters_tbl(a).cash_inflows(b).cf_amount, 0);
7950 END LOOP;
7951 END IF;
7952 END LOOP;
7953 ------------------------------------
7954 -- Get the Fee or Service Parameters
7955 ------------------------------------
7956 get_fee_srvc_cash_flows(
7957 p_api_version => p_api_version,
7958 p_init_msg_list => p_init_msg_list,
7959 x_return_status => l_return_status,
7960 x_msg_count => x_msg_count,
7961 x_msg_data => x_msg_data,
7962 p_hdr_rec => l_hdr_rec,
7963 p_tot_item_cat_cost => l_tot_item_cat_amount,
7964 p_tot_rent_payment => l_tot_rent_payment,
7965 x_fee_srv_tbl => l_fee_srv_tbl);
7966 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7967 'After get_fee_srvc_cash_flows ' || l_return_status );
7968 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7969 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7970 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7971 RAISE OKL_API.G_EXCEPTION_ERROR;
7972 END IF;
7973 -- Now need to loop through the l_fee_srv_tbl, generate streams if needed
7974 -- and accumulate the streams in the l_pricing_parameters_tbl !!
7975 IF l_fee_srv_tbl.COUNT > 0
7976 THEN
7977 FOR t_index IN l_fee_srv_tbl.FIRST .. l_fee_srv_tbl.LAST
7978 LOOP
7979 -- Populate the line_type, payment_type and streams in the
7980 -- l_pricing_parameters_tbl
7981 l_pricing_parameters_tbl(pp_index).line_type := l_fee_srv_tbl(t_index).type;
7982 -- Populate either INCOME / EXPENSE as a value for the payment_type !
7983 IF l_fee_srv_tbl(t_index).type = G_QQ_FEE_EXPENSE
7984 THEN
7985 l_pricing_parameters_tbl(pp_index).payment_type := 'EXPENSE';
7986 ELSIF l_fee_srv_tbl(t_index).TYPE = G_QQ_FEE_PAYMENT
7987 THEN
7988 l_pricing_parameters_tbl(pp_index).payment_type := 'INCOME';
7989 END IF;
7990 -- Start date for the line will be the quote expected start date
7991 l_pricing_parameters_tbl(pp_index).line_start_date :=l_hdr_rec.expected_start_date;
7992 l_pricing_parameters_tbl(pp_index).financed_amount := 0;
7993 -- Generate the streams .. using the corresponding cash flows and levels
7994 l_strm_ele_tbl.DELETE;
7995 IF l_fee_srv_tbl(t_index).cash_flow_level_tbl IS NOT NULL AND
7996 l_fee_srv_tbl(t_index).cash_flow_level_tbl.COUNT > 0
7997 THEN
7998 -- Initialize the Strm Count to Zero
7999 gen_so_cf_strms(
8000 p_api_version => p_api_version,
8001 p_init_msg_list => p_init_msg_list,
8002 x_return_status => l_return_status,
8003 x_msg_count => x_msg_count,
8004 x_msg_data => x_msg_data,
8005 p_cash_flow_rec => l_fee_srv_tbl(t_index).cash_flow_rec,
8006 p_cf_details_tbl => l_fee_srv_tbl(t_index).cash_flow_level_tbl,
8007 x_cash_inflow_strms_tbl => l_strm_ele_tbl);
8008 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8009 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8010 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8011 RAISE OKL_API.G_EXCEPTION_ERROR;
8012 END IF;
8013 END IF;
8014 -- Get the line_end_date from the last stream element generated !
8015 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8016 'After gen_so_cf_strms for fees ' || l_return_status );
8017 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8018 'Streams generated ' || l_strm_ele_tbl.COUNT );
8019 IF l_strm_ele_tbl IS NOT NULL AND
8020 l_strm_ele_tbl.COUNT > 0
8021 THEN
8022 IF l_strm_ele_tbl(l_strm_ele_tbl.LAST).is_arrears = 'N'
8023 THEN
8024 l_pricing_parameters_tbl(pp_index).line_end_date :=
8025 l_strm_ele_tbl(l_strm_ele_tbl.LAST).cf_period_start_end_date;
8026 ELSE
8027 l_pricing_parameters_tbl(pp_index).line_end_date :=
8028 l_strm_ele_tbl(l_strm_ele_tbl.LAST).cf_date;
8029 END IF;
8030 END IF;
8031 -- Assign the generated streams to the Pricing Parameters cash inflows table !
8032 l_pricing_parameters_tbl(pp_index).cash_inflows := l_strm_ele_tbl;
8033 -- Increment the pp_index
8034 pp_index := pp_index + 1;
8035 END LOOP; -- Loop on the l_fee_srv_tbl
8036 END IF; -- IF l_fee_srv_tbl.COUNT > 0
8037 -- Solve for the missing parameter using the IRR method if pricing method is
8038 -- Target Rate and Target Rate type is IRR
8039 IF ( l_hdr_rec.pricing_method = 'TR' AND
8040 l_hdr_rec.target_rate_type = 'PIRR' )
8041 THEN
8042 -- Check whether the interest picked is IIR or not??
8043 compute_irr(
8044 p_api_version => p_api_version,
8045 p_init_msg_list => p_init_msg_list,
8046 x_return_status => l_return_status,
8047 x_msg_count => x_msg_count,
8048 x_msg_data => x_msg_data,
8049 p_start_date => l_hdr_rec.expected_start_date,
8050 p_day_count_method => l_sgt_day_count_method,
8051 p_currency_code => l_hdr_rec.currency_code,
8052 p_pricing_method => l_hdr_rec.pricing_method,
8053 p_initial_guess => 0.1,
8054 px_pricing_parameter_tbl => l_pricing_parameters_tbl,
8055 px_irr => l_irr,
8056 x_payment => l_miss_payment);
8057 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8058 'After compute_irr ' || l_return_status );
8059 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8060 'SOLVED FOR TARGET-RATE (PIRR) ' || l_miss_payment );
8061 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8062 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8063 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8064 RAISE OKL_API.G_EXCEPTION_ERROR;
8065 END IF;
8066 IF l_miss_payment < 0
8067 THEN
8068 OKL_API.SET_MESSAGE (
8069 p_app_name => G_APP_NAME,
8070 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
8071 p_token1 => 'TYPE',
8072 p_token1_value => 'Payment',
8073 p_token2 => 'AMOUNT',
8074 p_token2_value => round(l_miss_payment,2) );
8075 RAISE okl_api.g_exception_error;
8076 END IF;
8077 END IF; -- Pricing method IF
8078 -- In case of the Pricing Method is SP...
8079 -- populate back the missing amount into the Cash Inflow Levels and the Streams too..
8080 -- for further solving for Yields
8081 IF l_hdr_rec.pricing_method = 'SP' OR
8082 l_hdr_rec.pricing_method = 'TR'
8083 THEN
8084 FOR i in l_strm_ele_tbl.FIRST .. l_strm_ele_tbl.LAST
8085 LOOP
8086 l_strm_ele_tbl(i).cf_amount := l_miss_payment;
8087 END LOOP;
8088 -- Need to populate back the Cash flow details, which will be
8089 -- returned back to the wrapper API !!
8090 FOR i in l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
8091 LOOP
8092 l_cash_flow_det_tbl(i).amount := l_miss_payment;
8093 END LOOP;
8094 -- Need to populate back the Cash inflows with the solved Amount for the FREE_FORM1 lines
8095 FOR i_index IN l_pricing_parameters_tbl.FIRST ..
8096 l_pricing_parameters_tbl.LAST
8097 LOOP
8098 FOR j_index IN l_pricing_parameters_tbl(i_index).cash_inflows.FIRST ..
8099 l_pricing_parameters_tbl(i_index).cash_inflows.LAST
8100 LOOP
8101 IF l_pricing_parameters_tbl(i_index).line_type = 'FREE_FORM1'
8102 THEN
8103 l_pricing_parameters_tbl(i_index).cash_inflows(j_index).cf_amount := l_miss_payment;
8104 END IF;
8105 END LOOP;
8106 END LOOP;
8107 -- Commenting the below code becasue, when QQ is being priced for TR[IRR],
8108 -- User will give the Fee Expense/Fee Payment amount, Pricing should not actually change that amounts
8109 /*
8110 -- Need to populate back the Cash flows into all the streams table back ..
8111 IF l_hdr_rec.target_rate_type = 'PIRR' AND
8112 l_fee_srv_tbl.COUNT > 0
8113 THEN
8114 FOR i_index IN l_fee_srv_tbl.FIRST .. l_fee_srv_tbl.LAST
8115 LOOP
8116 FOR j_index IN l_fee_srv_tbl(i_index).cash_flow_level_tbl.FIRST ..
8117 l_fee_srv_tbl(i_index).cash_flow_level_tbl.LAST
8118 LOOP
8119 l_fee_srv_tbl(i_index).cash_flow_level_tbl(j_index).amount := l_miss_payment;
8120 END LOOP;
8121 END LOOP;
8122 END IF;
8123 */
8124 END IF;
8125 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8126 '--------------------------------------------------------------------------');
8127 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8128 ' -- Subsidized Yields calculation');
8129 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8130 '--------------------------------------------------------------------------');
8131 -- Get the Total Item Categories cost
8132 IF l_hdr_rec.pricing_method = 'SF' OR
8133 l_hdr_rec.pricing_method = 'SFP'
8134 THEN
8135 -- The total financed amount would have been solved the compute_iir api
8136 -- and has been returned in l_pricing_parameters_tbl(1).financed_amount
8137 l_tot_item_cat_amount := l_pricing_parameters_tbl(1).financed_amount;
8138 END IF;
8139 -- When the pricing method is 'RC', we would have directly come to here
8140 -- as Rate Card method pricing is very similiar to the SY pricing method.
8141 -- 'Coz we have already calculated the payment amounts based on the
8142 -- Lease Rate Factor levels
8143 IF l_hdr_rec.pricing_method = 'TR' AND
8144 l_hdr_rec.target_rate_type = 'IIR'
8145 THEN
8146 l_iir := l_hdr_rec.target_rate /100;
8147 ELSE
8148 -- Calculate IIR
8149 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8150 'Subsidized IIR Calculation ------------------' );
8151 -- We will be calling the compute_irr with just the item cat. information
8152 -- and its residual streams .. ignoring fees and fee payments
8153 IF l_hdr_rec.pricing_method = 'RC'
8154 THEN
8155 -- We need to pass the pricing params corresponding to only the
8156 -- item categories leaving the Fee and else !
8157 FOR t IN 1 .. l_tmp_pp_index
8158 LOOP
8159 l_tmp_prc_params_tbl(t) := l_pricing_parameters_tbl(t);
8160 END LOOP;
8161 ELSE
8162 l_tmp_prc_params_tbl(1) := l_pricing_parameters_tbl(1);
8163 END IF;
8164 compute_irr(
8165 p_api_version => p_api_version,
8166 p_init_msg_list => p_init_msg_list,
8167 x_return_status => l_return_status,
8168 x_msg_count => x_msg_count,
8169 x_msg_data => x_msg_data,
8170 p_start_date => l_hdr_rec.expected_start_date,
8171 p_day_count_method => l_day_count_method,
8172 p_currency_code => l_hdr_rec.currency_code,
8173 p_pricing_method => 'SY',
8174 p_initial_guess => 0.1,
8175 px_pricing_parameter_tbl => l_tmp_prc_params_tbl,
8176 px_irr => l_iir,
8177 x_payment => l_miss_payment);
8178 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8179 '1/ After compute_iir ' || l_return_status );
8180 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8181 'SOLVED FOR IIR ' || l_iir );
8182 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8183 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8184 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8185 RAISE OKL_API.G_EXCEPTION_ERROR;
8186 END IF;
8187 -- Store back the pricing params record in l_pricing_parameters_tbl
8188 IF l_hdr_rec.pricing_method = 'RC'
8189 THEN
8190 FOR t IN 1 .. l_tmp_pp_index
8191 LOOP
8192 l_pricing_parameters_tbl(t) := l_tmp_prc_params_tbl(t);
8193 END LOOP;
8194 ELSE
8195 l_pricing_parameters_tbl(1) := l_tmp_prc_params_tbl(1);
8196 END IF;
8197 END IF; -- IF l_hdr_rec.pricing_mthod = 'TR' and l_hdr_rec.target_rate_type = 'IIR'
8198 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8199 'Subsidized IRR Calculation ------------------' );
8200 IF l_hdr_rec.pricing_method = 'TR' AND
8201 l_hdr_rec.target_rate_type = 'PIRR'
8202 THEN
8203 l_irr := l_hdr_rec.target_rate / 100;
8204 ELSE
8205 -- Calculate the IRR !
8206 compute_irr(
8207 p_api_version => p_api_version,
8208 p_init_msg_list => p_init_msg_list,
8209 x_return_status => l_return_status,
8210 x_msg_count => x_msg_count,
8211 x_msg_data => x_msg_data,
8212 p_start_date => l_hdr_rec.expected_start_date,
8213 p_day_count_method => l_sgt_day_count_method,
8214 p_currency_code => l_hdr_rec.currency_code,
8215 p_pricing_method => 'SY',
8216 p_initial_guess => l_iir,
8217 px_pricing_parameter_tbl => l_pricing_parameters_tbl,
8218 px_irr => l_irr,
8219 x_payment => l_miss_payment);
8220 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8221 'After compute_irr ' || l_return_status );
8222 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8223 'px_irr ' || l_irr );
8224 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8225 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8226 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8227 RAISE OKL_API.G_EXCEPTION_ERROR;
8228 END IF;
8229 END IF; -- IF l_hdr_rec.pricing_method = 'TR' AND l_hdr_rec.target_rate_type = 'PIRR'
8230 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8231 'Subsidized Booking Yield Calculation ' );
8232 IF l_hdr_rec.pricing_method = 'RC'
8233 THEN
8234 -- Store the IIR @ QQ level as the Booking Yield
8235 l_bk_yield := l_iir;
8236 ELSE
8237 -- Compute the Booking Yield
8238 l_bk_yield := l_iir;
8239 /*
8240 compute_bk_yield(
8241 p_api_version => p_api_version,
8242 p_init_msg_list => p_init_msg_list,
8243 x_return_status => l_return_status,
8244 x_msg_count => x_msg_count,
8245 x_msg_data => x_msg_data,
8246 p_start_date => l_hdr_rec.expected_start_date,
8247 p_day_count_method => l_day_count_method,
8248 p_pricing_method => 'SY',
8249 p_initial_guess => l_iir,
8250 p_term => l_hdr_rec.term,
8251 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
8252 x_bk_yield => l_bk_yield,
8253 x_termination_tbl => x_termination_tbl,
8254 x_pre_tax_inc_tbl => x_pre_tax_inc_tbl);
8255 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8256 'After compute_bk_yield ' || l_return_status );
8257 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8258 'x_bk_yield ' || l_bk_yield );
8259 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8260 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8261 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8262 RAISE OKL_API.G_EXCEPTION_ERROR;
8263 END IF;
8264 */
8265 END IF;
8266 -- Need to store the Subsidized Yields into l_subsized_yileds_rec
8267 -- ISG doesnot calculate yet the after_tax_irr
8268 l_subsidized_yields_rec.pre_tax_irr := l_irr;
8269 l_subsidized_yields_rec.iir := l_iir;
8270 l_subsidized_yields_rec.bk_yield := l_bk_yield;
8271 -- Storing the l_pricing_parameters_tbl into l_pricing_parameters_tbl_cp
8272 -- which will be useful during returning back of the pricing params ..
8273 l_pricing_parameters_tbl_cp := l_pricing_parameters_tbl;
8274 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8275 'Computed Subsidized Yields successfully ' );
8276 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8277 'Pre_Tax_IRR | IIR | Boooking Yield ' );
8278 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8279 round( l_subsidized_yields_rec.pre_tax_irr , 4 ) || ' | '
8280 || round( l_subsidized_yields_rec.iir , 4 ) || ' | '
8281 ||round( l_subsidized_yields_rec.bk_yield, 4 ) );
8282 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8283 '-------------------------------------------------------------');
8284 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8285 ' -- Calculation of the Yields ');
8286 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8287 '-------------------------------------------------------------');
8288 -- Dont consider any subsidy amount here !!
8289 FOR t_index IN l_pricing_parameters_tbl.FIRST .. l_pricing_parameters_tbl.LAST
8290 LOOP
8291 -- Remove the subsidy amount, normal yeilds calculation shouldnot consider
8292 -- subsidy amount as an inflow
8293 l_pricing_parameters_tbl(t_index).subsidy := 0;
8294 END LOOP;
8295 -- Calculate the IIR
8296 -- API being called is compute_irr but without passing any of the
8297 -- fees and fee payments info. from the QQ
8298 l_tmp_prc_params_tbl.DELETE;
8299 IF l_hdr_rec.pricing_method = 'RC'
8300 THEN
8301 -- We need to pass the pricing params corresponding to only the
8302 -- item categories leaving the Fee and else !
8303 FOR t IN 1 .. l_tmp_pp_index
8304 LOOP
8305 l_tmp_prc_params_tbl(t) := l_pricing_parameters_tbl(t);
8306 END LOOP;
8307 ELSE
8308 l_tmp_prc_params_tbl(1) := l_pricing_parameters_tbl(1);
8309 END IF;
8310 compute_irr(
8311 p_api_version => p_api_version,
8312 p_init_msg_list => p_init_msg_list,
8313 x_return_status => l_return_status,
8314 x_msg_count => x_msg_count,
8315 x_msg_data => x_msg_data,
8316 p_start_date => l_hdr_rec.expected_start_date,
8317 p_day_count_method => l_day_count_method,
8318 p_currency_code => l_hdr_rec.currency_code,
8319 p_pricing_method => 'SY',
8320 p_initial_guess => l_subsidized_yields_rec.iir,
8321 px_pricing_parameter_tbl => l_tmp_prc_params_tbl,
8322 px_irr => l_iir,
8323 x_payment => l_miss_payment);
8324 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8325 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8326 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8327 RAISE OKL_API.G_EXCEPTION_ERROR;
8328 END IF;
8329 -- Store back the pricing params ..
8330 IF l_hdr_rec.pricing_method = 'RC'
8331 THEN
8332 FOR t IN 1 .. l_tmp_pp_index
8333 LOOP
8334 l_pricing_parameters_tbl(t) := l_tmp_prc_params_tbl(t);
8335 END LOOP;
8336 ELSE
8337 l_pricing_parameters_tbl(1) := l_tmp_prc_params_tbl(1);
8338 END IF;
8339 -- Calculate the IRR !
8340 compute_irr(
8341 p_api_version => p_api_version,
8342 p_init_msg_list => p_init_msg_list,
8343 x_return_status => l_return_status,
8344 x_msg_count => x_msg_count,
8345 x_msg_data => x_msg_data,
8346 p_start_date => l_hdr_rec.expected_start_date,
8347 p_day_count_method => l_sgt_day_count_method,
8348 p_currency_code => l_hdr_rec.currency_code,
8349 p_pricing_method => 'SY',
8350 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr,
8351 px_pricing_parameter_tbl => l_pricing_parameters_tbl,
8352 px_irr => l_irr,
8353 x_payment => l_miss_payment);
8354 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8355 'After compute_irr ' || l_return_status );
8356 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8357 'px_irr ' || l_irr );
8358 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8359 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8360 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8361 RAISE OKL_API.G_EXCEPTION_ERROR;
8362 END IF;
8363 IF l_hdr_rec.pricing_method = 'RC'
8364 THEN
8365 -- Store the IIR as the Booking Yield @ the QQ level
8366 l_bk_yield := l_iir;
8367 ELSE
8368 -- Compute the Booking Yield
8369 l_bk_yield := l_iir;
8370 /*
8371 compute_bk_yield(
8372 p_api_version => p_api_version,
8373 p_init_msg_list => p_init_msg_list,
8374 x_return_status => l_return_status,
8375 x_msg_count => x_msg_count,
8376 x_msg_data => x_msg_data,
8377 p_start_date => l_hdr_rec.expected_start_date,
8378 p_day_count_method => l_day_count_method,
8379 p_pricing_method => 'SY',
8380 p_initial_guess => l_subsidized_yields_rec.bk_yield,
8381 p_term => l_hdr_rec.term,
8382 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
8383 x_bk_yield => l_bk_yield,
8384 x_termination_tbl => x_termination_tbl,
8385 x_pre_tax_inc_tbl => x_pre_tax_inc_tbl);
8386 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'After compute_bk_yield ' || l_return_status );
8387 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'x_bk_yield ' || l_bk_yield );
8388 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8389 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8390 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8391 RAISE OKL_API.G_EXCEPTION_ERROR;
8392 END IF;
8393 */
8394 END IF;
8395 -- ISG doesnot calculate the after_tax_irr yet
8396 l_yields_rec.pre_tax_irr := l_irr;
8397 l_yields_rec.iir := l_iir;
8398 l_yields_rec.bk_yield := l_bk_yield;
8399 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8400 '---------------------------------------------------' );
8401 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8402 'Yields ' );
8403 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8404 '---------------------------------------------------' );
8405 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8406 'Pre_Tax_IRR | IIR | Boooking Yield ' );
8407 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8408 round( l_yields_rec.pre_tax_irr , 4 ) || ' | ' || round( l_yields_rec.iir , 4 ) || ' | '
8409 ||round( l_yields_rec.bk_yield, 4 ) );
8410 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8411 '---------------------------------------------------' );
8412 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8413 'Subsidized Yields ' );
8414 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8415 '---------------------------------------------------' );
8416 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8417 'Pre_Tax_IRR | IIR | Boooking Yield ' );
8418 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8419 round( l_subsidized_yields_rec.pre_tax_irr , 4 ) || ' | '
8420 || round( l_subsidized_yields_rec.iir , 4 ) || ' | '
8421 ||round( l_subsidized_yields_rec.bk_yield, 4 ) );
8422 -- Need to calculate a quote API to update the Yields and Subsidized yields !
8423 -- Call the API which changes the status of the QQ !
8424 -- Actual logic Ends here
8425 x_yileds_rec := l_yields_rec;
8426 x_subsidized_yileds_rec := l_subsidized_yields_rec;
8427 -- Need to populate back the pricing results using the x_pricing_results_tbl ....
8428 i := 1;
8429 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8430 ' ************** PRICING ENGINE RETURN VALUES: ************** ' );
8431 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8432 'Line Type | Asset Cost | Down Payment | Trade In | Subsidy ' );
8433 IF l_hdr_rec.pricing_method = 'RC'
8434 THEN
8435 -- Loop through the l_item_cat_cf_tbl and then return the pricing results
8436 FOR t in l_item_cat_cf_tbl.FIRST .. l_item_cat_cf_tbl.LAST
8437 LOOP
8438 x_pricing_results_tbl(i).line_type := 'FREE_FORM1';
8439 x_pricing_results_tbl(i).line_id := l_item_cat_cf_tbl(t).line_id;
8440 x_pricing_results_tbl(i).item_category_id := l_item_cat_cf_tbl(t).item_category_id;
8441 x_pricing_results_tbl(i).financed_amount := l_item_cat_cf_tbl(t).financed_amount;
8442 x_pricing_results_tbl(i).trade_in := l_item_cat_cf_tbl(t).trade_in;
8443 x_pricing_results_tbl(i).down_payment := l_item_cat_cf_tbl(t).down_payment;
8444 x_pricing_results_tbl(i).subsidy := l_item_cat_cf_tbl(t).subsidy;
8445 x_pricing_results_tbl(i).cash_flow_rec := l_item_cat_cf_tbl(t).cash_flow_rec;
8446 x_pricing_results_tbl(i).cash_flow_level_tbl := l_item_cat_cf_tbl(t).cash_flow_level_tbl;
8447 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8448 x_pricing_results_tbl(1).line_type || ' | ' ||
8449 round(x_pricing_results_tbl(i).financed_amount, 4) || ' | ' ||
8450 round(x_pricing_results_tbl(i).down_payment, 4) || ' | ' ||
8451 round(x_pricing_results_tbl(i).trade_in, 4) || ' | ' ||
8452 round(x_pricing_results_tbl(i).subsidy, 4) ) ;
8453 IF x_pricing_results_tbl(i).cash_flow_level_tbl.COUNT > 0 AND
8454 x_pricing_results_tbl(i).cash_flow_level_tbl IS NOT NULL
8455 THEN
8456 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8457 ' Cash Flow Level details ' );
8458 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8459 ' Rate | Start Date | Frequency | Arrears Y/N | | Stub Days | Stub Amount | Periods | Periodic Amount ' );
8460 FOR t_in IN x_pricing_results_tbl(i).cash_flow_level_tbl.FIRST ..
8461 x_pricing_results_tbl(i).cash_flow_level_tbl.LAST
8462 LOOP
8463 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8464 ' ' || x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).rate || ' | ' ||
8465 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).START_DATE || ' | ' ||
8466 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).fqy_code || ' | ' ||
8467 x_pricing_results_tbl(i).cash_flow_rec.due_arrears_yn || ' | ' ||
8468 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_days || ' | ' ||
8469 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_amount || ' | ' ||
8470 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).number_of_periods || ' | ' ||
8471 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).amount );
8472 END LOOP;
8473 END IF;
8474 -- Increment i
8475 i := i + 1;
8476 END LOOP;
8477 ELSE
8478 -- The first pricing param will be the FREE_FORM1 line only ..
8479 -- in case of the pricing method is not RC.
8480 x_pricing_results_tbl(i).line_type := l_pricing_parameters_tbl_cp(1).line_type;
8481 x_pricing_results_tbl(i).financed_amount := l_pricing_parameters_tbl_cp(1).financed_amount;
8482 x_pricing_results_tbl(i).trade_in := l_pricing_parameters_tbl_cp(1).trade_in;
8483 x_pricing_results_tbl(i).down_payment := l_pricing_parameters_tbl_cp(1).down_payment;
8484 x_pricing_results_tbl(i).subsidy := l_pricing_parameters_tbl_cp(1).subsidy;
8485 x_pricing_results_tbl(i).cash_flow_rec := l_cash_flow_rec;
8486 x_pricing_results_tbl(i).cash_flow_level_tbl := l_cash_flow_det_tbl;
8487 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8488 x_pricing_results_tbl(1).line_type || ' | ' ||
8489 round(x_pricing_results_tbl(1).financed_amount, 4) || ' | ' ||
8490 round(x_pricing_results_tbl(1).down_payment, 4) || ' | ' ||
8491 round(x_pricing_results_tbl(1).trade_in, 4) || ' | ' ||
8492 round(x_pricing_results_tbl(1).subsidy, 4) ) ;
8493 IF x_pricing_results_tbl(i).cash_flow_level_tbl.COUNT > 0 AND
8494 x_pricing_results_tbl(i).cash_flow_level_tbl IS NOT NULL
8495 THEN
8496 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8497 ' Cash Flow Level details ' );
8498 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8499 ' Rate | Start Date | Frequency | Arrears Y/N | | Stub Days | Stub Amount | Periods | Periodic Amount ' );
8500 FOR t_in IN x_pricing_results_tbl(i).cash_flow_level_tbl.FIRST ..
8501 x_pricing_results_tbl(i).cash_flow_level_tbl.LAST
8502 LOOP
8503 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8504 ' ' || x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).rate || ' | ' ||
8505 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).START_DATE || ' | ' ||
8506 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).fqy_code || ' | ' ||
8507 x_pricing_results_tbl(i).cash_flow_rec.due_arrears_yn || ' | ' ||
8508 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_days || ' | ' ||
8509 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_amount || ' | ' ||
8510 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).number_of_periods || ' | ' ||
8511 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).amount );
8512 END LOOP;
8513 END IF;
8514 --Increment i ..
8515 i := i + 1;
8516 END IF;
8517 -- Need to return back the expense and fee payment cash flows !
8518 IF l_fee_srv_tbl.COUNT > 0
8519 THEN
8520 FOR t IN l_fee_srv_tbl.FIRST .. l_fee_srv_tbl.LAST
8521 LOOP
8522 x_pricing_results_tbl(i).line_type := l_fee_srv_tbl(t).type;
8523 x_pricing_results_tbl(i).financed_amount := NULL;
8524 x_pricing_results_tbl(i).trade_in := NULL;
8525 x_pricing_results_tbl(i).down_payment := NULL;
8526 x_pricing_results_tbl(i).subsidy := NULL;
8527 x_pricing_results_tbl(i).cash_flow_rec := l_fee_srv_tbl(t).cash_flow_rec;
8528 x_pricing_results_tbl(i).cash_flow_level_tbl := l_fee_srv_tbl(t).cash_flow_level_tbl;
8529 IF x_pricing_results_tbl(i).cash_flow_level_tbl.COUNT > 0 AND
8530 x_pricing_results_tbl(i).cash_flow_level_tbl IS NOT NULL
8531 THEN
8532 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8533 ' Cash Flow Level details for LINE_TYPE ' || x_pricing_results_tbl(i).line_type );
8534 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8535 ' Rate | Start Date | Frequency | Arrears Y/N | | Stub Days | Stub Amount | Periods | Periodic Amount ' );
8536 FOR t_in IN x_pricing_results_tbl(i).cash_flow_level_tbl.FIRST ..
8537 x_pricing_results_tbl(i).cash_flow_level_tbl.LAST
8538 LOOP
8539 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8540 ' ' || x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).rate || ' | ' ||
8541 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).START_DATE || ' | ' ||
8542 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).fqy_code || ' | ' ||
8543 x_pricing_results_tbl(i).cash_flow_rec.due_arrears_yn || ' | ' ||
8544 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_days || ' | ' ||
8545 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_amount || ' | ' ||
8546 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).number_of_periods || ' | ' ||
8547 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).amount );
8548 END LOOP;
8549 END IF;
8550 -- Increment i !
8551 i := i + 1;
8552 END LOOP;
8553 END IF;
8554 x_return_status := l_return_status;
8555 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
8556 x_msg_data => x_msg_data);
8557 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8558 'end debug OKLRPIUB.pls call ' || LOWER(l_api_name) );
8559 EXCEPTION
8560 WHEN OKL_API.G_EXCEPTION_ERROR THEN
8561 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8562 p_api_name => l_api_name,
8563 p_pkg_name => G_PKG_NAME,
8564 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
8565 x_msg_count => x_msg_count,
8566 x_msg_data => x_msg_data,
8567 p_api_type => g_api_type);
8568 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
8569 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8570 p_api_name => l_api_name,
8571 p_pkg_name => G_PKG_NAME,
8572 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
8573 x_msg_count => x_msg_count,
8574 x_msg_data => x_msg_data,
8575 p_api_type => g_api_type);
8576 WHEN OTHERS THEN
8577 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8578 p_api_name => l_api_name,
8579 p_pkg_name => G_PKG_NAME,
8580 p_exc_name => 'OTHERS',
8581 x_msg_count => x_msg_count,
8582 x_msg_data => x_msg_data,
8583 p_api_type => g_api_type);
8584 END price_quick_quote;
8585
8586 PROCEDURE distribute_fin_amount_lq(
8587 p_api_version IN NUMBER,
8588 p_init_msg_list IN VARCHAR2,
8589 x_return_status OUT NOCOPY VARCHAR2,
8590 x_msg_count OUT NOCOPY NUMBER,
8591 x_msg_data OUT NOCOPY VARCHAR2,
8592 p_lq_id IN NUMBER,
8593 p_tot_fin_amount IN NUMBER)
8594 IS
8595 -- Local Variables
8596 l_api_version CONSTANT NUMBER DEFAULT 1.0;
8597 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'distribute_fin_amount_lq';
8598 l_return_status VARCHAR2(1);
8599 l_module CONSTANT fnd_log_messages.module%TYPE :=
8600 'LEASE.ACCOUNTING.PRICING.OKL_PRICING_UTILS_PVT.distribute_fin_amount_lq';
8601 l_debug_enabled VARCHAR2(10);
8602 is_debug_procedure_on BOOLEAN;
8603 is_debug_statement_on BOOLEAN;
8604 -- Cursor to fetch the Lease Quote Header details
8605 CURSOR quote_csr(qteid NUMBER)
8606 IS
8607 SELECT qte.pricing_method pricing_method,
8608 qte.rate_template_id rate_template_id,
8609 qte.structured_pricing structured_pricing,
8610 qte.line_level_pricing line_level_pricing,
8611 qte.target_arrears_yn target_arrears
8612 FROM OKL_LEASE_QUOTES_B qte
8613 WHERE qte.id = qteid;
8614 quote_rec quote_csr%ROWTYPE;
8615 -- Cursor to fetch the Assets Details for a Lease Quote
8616 -- and SRT attached to the Asset ( if any .. )
8617 CURSOR assets_csr(qteid NUMBER)
8618 IS
8619 SELECT ast.id ast_id,
8620 ast.asset_number asset_number,
8621 ast.oec oec,
8622 ast.oec_percentage oec_percentage,
8623 ast.structured_pricing structured_pricing,
8624 ast.rate_template_id rate_template_id,
8625 ast.target_arrears target_arrears
8626 FROM okl_assets_b ast,
8627 okl_lease_quotes_b qte
8628 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
8629 ast.parent_object_id = qte.id AND
8630 qte.id = qteid;
8631 CURSOR c_asset_comp_csr( p_asset_id NUMBER) IS
8632 SELECT
8633 id
8634 ,primary_component
8635 ,unit_cost
8636 ,number_of_units
8637 FROM okl_asset_components_v
8638 WHERE asset_id = p_asset_id
8639 AND primary_component = 'YES';
8640
8641 -- Local Variables Declaration !
8642 l_overridden BOOLEAN;
8643 tot_oec_percentage NUMBER;
8644 i NUMBER;
8645 lq_level_fin_amt NUMBER;
8646 l_asset_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_tbl_type;
8647 l_component_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_component_tbl_type;
8648 l_cf_hdr_rec OKL_LEASE_QUOTE_ASSET_PVT.cashflow_hdr_rec_type;
8649 l_cf_level_tbl OKL_LEASE_QUOTE_ASSET_PVT.cashflow_level_tbl_type;
8650 BEGIN
8651 l_return_status := OKL_API.G_RET_STS_SUCCESS;
8652 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
8653 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
8654 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8655 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
8656 -- check for logging on STATEMENT level
8657 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
8658 l_return_status := OKL_API.START_ACTIVITY(
8659 p_api_name => l_api_name,
8660 p_pkg_name => G_PKG_NAME,
8661 p_init_msg_list => p_init_msg_list,
8662 l_api_version => l_api_version,
8663 p_api_version => p_api_version,
8664 p_api_type => g_api_type,
8665 x_return_status => x_return_status);
8666 --Check if activity started successfully
8667 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8668 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8669 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8670 RAISE OKL_API.G_EXCEPTION_ERROR;
8671 END IF;
8672 -- Loop thu all the assets
8673 -- store the non-overriding assets id into assets_tbl
8674 -- sum the oec_percentage
8675 --end loop
8676 OPEN quote_csr( qteId => p_lq_id );
8677 FETCH quote_csr INTO quote_rec;
8678 CLOSE quote_csr;
8679
8680 tot_oec_percentage := 0;
8681 i := 1;
8682 FOR asset_rec IN assets_csr(qteid => p_lq_id )
8683 LOOP
8684 l_overridden := is_asset_overriding(
8685 p_qte_id => p_lq_id,
8686 p_ast_id => asset_rec.ast_id,
8687 p_lq_line_level_pricing => quote_rec.line_level_pricing,
8688 p_lq_srt_id => quote_rec.rate_template_id,
8689 p_ast_srt_id => asset_rec.rate_template_id,
8690 p_lq_struct_pricing => quote_rec.structured_pricing,
8691 p_ast_struct_pricing => asset_rec.structured_pricing,
8692 p_lq_arrears_yn => quote_rec.target_arrears,
8693 p_ast_arrears_yn => asset_rec.target_arrears,
8694 x_return_status => l_return_status);
8695 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8696 'After is_asset_overriding assets_rec.id =' || asset_rec.ast_id);
8697 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8698 ' l_return_status =' || l_return_status );
8699 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8700 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8701 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8702 RAISE OKL_API.G_EXCEPTION_ERROR;
8703 END IF;
8704 IF l_overridden = FALSE
8705 THEN
8706 -- Asset is following the Payment Structure defined at Lease quote ..
8707 tot_oec_percentage := tot_oec_percentage + nvl(asset_rec.oec_percentage,0);
8708 l_asset_tbl(i).id := asset_rec.ast_id;
8709 l_asset_tbl(i).oec_percentage := asset_rec.oec_percentage;
8710 -- Increment the index
8711 i := i + 1;
8712 END IF;
8713 END LOOP;
8714 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8715 'Sum(OEC %age) for non-overiding assets = ' || ROUND( tot_oec_percentage, 4));
8716 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8717 'assets_tbl = ' || l_asset_tbl.COUNT );
8718 IF l_asset_tbl.COUNT > 0
8719 THEN
8720 lq_level_fin_amt := p_tot_fin_amount * 100 / ( tot_oec_percentage );
8721 -- Loop through the assets_tbl and update the OEC of each asset !
8722 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8723 'Districution of Assets OEC ' );
8724 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8725 'Asset ID | Financed Amount ');
8726 FOR t IN l_asset_tbl.FIRST .. l_asset_tbl.LAST
8727 LOOP
8728 l_asset_tbl(t).oec := lq_level_fin_amt * l_asset_tbl(t).oec_percentage / 100;
8729 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8730 l_asset_tbl(t).id || ' | ' || l_asset_tbl(t).oec );
8731 l_component_tbl.DELETE;
8732 FOR t_rec IN c_asset_comp_csr( p_asset_id => l_asset_tbl(t).id )
8733 LOOP
8734 l_component_tbl(1).id := t_rec.id;
8735 l_component_tbl(1).unit_cost := l_asset_tbl(t).oec / t_rec.number_of_units;
8736 l_component_tbl(1).record_mode := 'update';
8737 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8738 'Updated l_component_tbl(1).unit_cost = ' || l_component_tbl(1).unit_cost );
8739 END LOOP;
8740 -- Call the update api to store back the calculated OEC of the Asset!
8741 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8742 'Before OKL_LEASE_QUOTE_ASSET_PVT.update_asset ');
8743 -- Instead we need to use the OKL_LEASE_QUOTE_ASSET_PVT.update_asset
8744 OKL_LEASE_QUOTE_ASSET_PVT.update_asset (
8745 p_api_version => p_api_version,
8746 p_init_msg_list => p_init_msg_list,
8747 p_transaction_control => 'T',
8748 p_asset_rec => l_asset_tbl(t),
8749 p_component_tbl => l_component_tbl,
8750 p_cf_hdr_rec => l_cf_hdr_rec,
8751 p_cf_level_tbl => l_cf_level_tbl,
8752 x_return_status => l_return_status,
8753 x_msg_count => x_msg_count,
8754 x_msg_data => x_msg_data);
8755 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8756 'After OKL_LEASE_QUOTE_ASSET_PVT.update_asset ' || l_return_status );
8757 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8758 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8759 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8760 RAISE OKL_API.G_EXCEPTION_ERROR;
8761 END IF;
8762 END LOOP;
8763 END IF;
8764 -- Logic ends here !
8765 x_return_status := l_return_status;
8766 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
8767 x_msg_data => x_msg_data);
8768 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8769 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
8770 EXCEPTION
8771 WHEN OKL_API.G_EXCEPTION_ERROR THEN
8772 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8773 p_api_name => l_api_name,
8774 p_pkg_name => G_PKG_NAME,
8775 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
8776 x_msg_count => x_msg_count,
8777 x_msg_data => x_msg_data,
8778 p_api_type => g_api_type);
8779 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
8780 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8781 p_api_name => l_api_name,
8782 p_pkg_name => G_PKG_NAME,
8783 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
8784 x_msg_count => x_msg_count,
8785 x_msg_data => x_msg_data,
8786 p_api_type => g_api_type);
8787 WHEN OTHERS THEN
8788 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8789 p_api_name => l_api_name,
8790 p_pkg_name => G_PKG_NAME,
8791 p_exc_name => 'OTHERS',
8792 x_msg_count => x_msg_count,
8793 x_msg_data => x_msg_data,
8794 p_api_type => g_api_type);
8795 END distribute_fin_amount_lq;
8796
8797 --------------------------------------------------------------------------------
8798 -- Start of Commnets
8799 -- Procedure Name : price_standard_quote_asset
8800 -- Description : This API would have been called once for each asset
8801 -- which has overridden the Quote Level Pricing Structure !
8802 -- Business Rules :
8803 -- Parameters :
8804 -- Version : 1.0
8805 -- History : rgooty 22-May-2005 - created
8806 -- 1/ Added params p_price_at_lq_level
8807 -- When passed TRUE for p_price_at_lq_level, this api, will
8808 -- price the Asset, with the payment strucutre defined at the LQ level.
8809 -- Such senario, will be happening when the pricing_method is SP, and
8810 -- after we calculated the IIR at quote level, again, we will want to
8811 -- calculate the payments at each individual asset levels.
8812 -- p_target_rate will be passed as the IIR at the LQ Level.
8813 -- When p_price_at_lq_level is FALSE, then the Asset will be assumed
8814 -- to be overriding the payment structure defined at the LQ level.
8815 -- Hence, the Asset Level Cash flow Details will be fetched/defined ( incase of SRT )
8816 -- and the asset will be priced based on such information.
8817 -- 2/ Added, x_pricing_parameter_rec as an output parameter, because
8818 -- the price_standard_quote api can use the already built streams for this asset
8819 -- directly instead of it generating them again.
8820 -- 3/ Bug 7445154: Param p_line_type has been added.
8821 -- Pass FREE_FORM1 in case of Line Type = Asset
8822 -- If Line is a Fee, expected values are FINANCED/ROLLOVER
8823 -- End of Commnets
8824 --------------------------------------------------------------------------------
8825 PROCEDURE price_standard_quote_asset(
8826 x_return_status OUT NOCOPY VARCHAR2,
8827 x_msg_count OUT NOCOPY NUMBER,
8828 x_msg_data OUT NOCOPY VARCHAR2,
8829 p_api_version IN NUMBER,
8830 p_init_msg_list IN VARCHAR2,
8831 p_qte_id IN NUMBER,
8832 p_ast_id IN NUMBER, -- could be fee id.
8833 p_price_at_lq_level IN BOOLEAN,
8834 p_target_rate IN NUMBER,
8835 p_line_type IN VARCHAR2,
8836 x_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type)
8837 IS
8838 l_api_version CONSTANT NUMBER DEFAULT 1.0;
8839 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'price_standard_quote_asset';
8840 l_return_status VARCHAR2(1);
8841 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
8842 || G_PKG_NAME || '.' || UPPER(l_api_name);
8843
8844 l_debug_enabled VARCHAR2(10);
8845 is_debug_procedure_on BOOLEAN;
8846 is_debug_statement_on BOOLEAN;
8847
8848 CURSOR subsidy_adj_csr( subId NUMBER)
8849 IS
8850 SELECT amount
8851 FROM okl_subsidies_b
8852 WHERE id = subId;
8853
8854 subsidy_adj_rec subsidy_adj_csr%ROWTYPE;
8855
8856 -- Cursor to fetch the Lease Quote Header details
8857 CURSOR quote_csr(qteid NUMBER)
8858 IS
8859 SELECT qte.pricing_method pricing_method,
8860 qte.rate_template_id rate_template_id,
8861 qte.expected_start_date expected_start_date,
8862 qte.expected_delivery_date expected_delivery_date,
8863 qte.term term,
8864 qte.lease_rate_factor,
8865 qte.structured_pricing structured_pricing,
8866 qte.line_level_pricing line_level_pricing,
8867 qte.rate_card_id,
8868 qte.id,
8869 qte.parent_object_code,
8870 qte.target_frequency target_frequency,
8871 qte.target_arrears_yn target_arrears,
8872 qte.product_id,
8873 qte.sub_iir -- Yield used while calculating the payments @ Asset Level
8874 FROM OKL_LEASE_QUOTES_B qte
8875 WHERE qte.id = qteid;
8876 quote_rec quote_csr%ROWTYPE;
8877
8878 --Bug 5884825 PAGARG start
8879 --Cursor to fetch product name
8880 CURSOR product_name_csr(qteid NUMBER)
8881 IS
8882 SELECT PDT.NAME PRODUCTNAME
8883 FROM OKL_LEASE_QUOTES_B QTE
8884 , OKL_PRODUCTS PDT
8885 WHERE QTE.PRODUCT_ID = PDT.ID
8886 AND QTE.ID = QTEID;
8887 --Bug 5884825 PAGARG end
8888
8889 -- Local Variables Declaration
8890 l_product_name okl_products.NAME%TYPE;--Bug 5884825 PAGARG
8891 l_lrs_details lrs_details_rec_type;
8892 l_lrs_factor lrs_factor_rec_type;
8893 l_lrs_levels lrs_levels_tbl_type;
8894 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
8895 l_adj_factor NUMBER;
8896 l_months_per_period NUMBER;
8897 l_months_after NUMBER;
8898 cf_index NUMBER; -- Using as an index for Cash flow levels
8899 --Bug 5121548 dpsingh start
8900 --Cursor to fetch the Fees name for a Lease Quote
8901 CURSOR fees_csr(qteid NUMBER,
8902 fee_id NUMBER)
8903 IS
8904 SELECT stytl.name
8905 FROM okl_fees_b fee,
8906 okl_strm_type_tl stytl
8907 WHERE fee.parent_object_code = 'LEASEQUOTE'
8908 AND fee.parent_object_id = qteid
8909 AND fee.id = fee_id
8910 AND fee.STREAM_TYPE_ID = stytl.id
8911 AND stytl.LANGUAGE = USERENV('LANG');
8912 --Bug 5121548 dpsingh end
8913
8914 -- Cursor to fetch the Assets Details for a Lease Quote
8915 -- and SRT attached to the Asset ( if any .. )
8916 CURSOR assets_csr(qteid NUMBER,
8917 ast_fee_id NUMBER)
8918 IS
8919 SELECT ast.asset_number,
8920 ast.id ast_id,
8921 TO_NUMBER(NULL) fee_id,
8922 ast.rate_card_id,
8923 ast.rate_template_id rate_template_id,
8924 ast.structured_pricing,
8925 'FREE_FORM1' fee_type,
8926 TO_NUMBER(NULL) fee_amount,
8927 ast.lease_rate_factor lease_rate_factor,
8928 ast.asset_number name,
8929 ast.target_frequency target_frequency,
8930 ast.target_arrears target_arrears
8931 FROM okl_assets_b ast,
8932 okl_lease_quotes_b qte
8933 WHERE ast.parent_object_code = 'LEASEQUOTE'
8934 AND ast.parent_object_id = qte.id
8935 AND qte.id = qteid
8936 AND ast.id = ast_fee_id
8937 AND p_line_type = 'FREE_FORM1'
8938 UNION
8939 SELECT NULL asset_number,
8940 TO_NUMBER(NULL) ast_id,
8941 fee.id fee_id,
8942 fee.rate_card_id,
8943 fee.rate_template_id,
8944 fee.structured_pricing,
8945 fee.fee_type,
8946 fee.fee_amount,
8947 fee.lease_rate_factor lease_rate_factor,
8948 fee.fee_type || ' FEE' name,
8949 fee.target_frequency target_frequency,
8950 fee.target_arrears target_arrears
8951 FROM okl_fees_b fee,
8952 okl_lease_quotes_b qte
8953 WHERE fee.parent_object_code = 'LEASEQUOTE'
8954 AND fee.parent_object_id = qte.id
8955 AND qte.id = qteid
8956 AND fee.id = ast_fee_id
8957 AND p_line_type IN ( 'FINANCED', 'ROLLOVER' );
8958 assets_rec assets_csr%ROWTYPE;
8959 -- Cursor to fetch the Asset Level Details
8960 CURSOR asset_adj_csr(qteid NUMBER,
8961 astid NUMBER)
8962 IS
8963 SELECT ast.asset_number,
8964 ast.install_site_id,
8965 ast.rate_card_id,
8966 ast.rate_template_id,
8967 ast.oec,
8968 nvl(nvl(ast.end_of_term_value, ast.end_of_term_value_default),0) end_of_term_value,
8969 ast.oec_percentage,
8970 cmp.unit_cost,
8971 cmp.number_of_units,
8972 cmp.primary_component
8973 FROM okl_assets_b ast,
8974 okl_lease_quotes_b qte,
8975 okl_asset_components_b cmp
8976 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
8977 ast.parent_object_id = qte.id AND
8978 qte.id = qteid AND
8979 ast.id = astid AND
8980 cmp.primary_component = 'YES' AND
8981 cmp.asset_id = ast.id;
8982 -- Cursor to fetch the Asset Level Details
8983 CURSOR asset_cost_adj_csr(qteid NUMBER,
8984 astid NUMBER)
8985 IS
8986 SELECT adj.adjustment_source_type,
8987 adj.adjustment_source_id,
8988 adj.basis,
8989 -- Start : DJANASWA : Bug# 6347118
8990 nvl(adj.value,adj.default_subsidy_amount) value
8991 -- End : DJANASWA : Bug# 6347118
8992 FROM okl_assets_b ast,
8993 okl_lease_quotes_b qte,
8994 okl_cost_adjustments_b adj
8995 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
8996 ast.parent_object_id = qte.id AND
8997 qte.id = qteid AND
8998 ast.id = astid AND
8999 adj.parent_object_id = ast.id;
9000 -- Cursor to fetch the Customer Details
9001 CURSOR get_cust_details_csr( p_lq_id NUMBER )
9002 IS
9003 SELECT lopp.id parent_id
9004 ,lopp.prospect_id prospect_id
9005 ,lopp.cust_acct_id cust_acct_id
9006 ,lopp.sales_territory_id sales_territory_id
9007 ,lopp.currency_code currency_code
9008 FROM okl_lease_quotes_b lq,
9009 okl_lease_opportunities_b lopp
9010 WHERE parent_object_code = 'LEASEOPP'
9011 AND parent_object_id = lopp.id
9012 AND lq.id = p_lq_id;
9013 --Cursor to fetch the Parent Object Details
9014 CURSOR get_cust_details_csr_lapp( p_lq_id NUMBER )
9015 IS
9016 SELECT lapp.id parent_id
9017 ,lapp.prospect_id prospect_id
9018 ,lapp.cust_acct_id cust_acct_id
9019 ,lapp.sales_territory_id sales_territory_id
9020 ,lapp.currency_code currency_code
9021 FROM okl_lease_quotes_b lq,
9022 okl_lease_applications_b lapp
9023 WHERE parent_object_code = 'LEASEAPP'
9024 AND parent_object_id = lapp.id
9025 AND lq.id = p_lq_id;
9026 -- Cursor to fetch the Asset components details
9027 CURSOR c_asset_comp_csr( p_asset_id NUMBER) IS
9028 SELECT
9029 id
9030 ,primary_component
9031 ,unit_cost
9032 ,number_of_units
9033 FROM okl_asset_components_v
9034 WHERE asset_id = p_asset_id
9035 AND primary_component = 'YES';
9036
9037 CURSOR check_cfo_exists_csr(
9038 p_oty_code IN VARCHAR2,
9039 p_source_table IN VARCHAR2,
9040 p_source_id IN VARCHAR2 )
9041 IS
9042 SELECT 'YES' cfo_exists,
9043 cfo.id cfo_id,
9044 caf.id caf_id,
9045 caf.sty_id sty_id
9046 FROM OKL_CASH_FLOW_OBJECTS cfo,
9047 OKL_CASH_FLOWS caf
9048 WHERE OTY_CODE = p_oty_code
9049 AND SOURCE_TABLE = p_source_table
9050 AND SOURCE_ID = p_source_id
9051 AND caf.cfo_id = cfo.id;
9052 check_cfo_exists_rec check_cfo_exists_csr%ROWTYPE;
9053 -- Cursor to fetch the Stream Type
9054 CURSOR c_strm_type (
9055 pdtId NUMBER,
9056 expStartDate DATE,
9057 strm_purpose VARCHAR) IS
9058 SELECT STRM.STY_ID PAYMENT_TYPE_ID,
9059 STRM.STY_NAME PAYMENT_TYPE,
9060 STRM.START_DATE,
9061 STRM.END_DATE,
9062 STRM.STY_PURPOSE
9063 FROM OKL_STRM_TMPT_PRIMARY_UV STRM
9064 WHERE STY_PURPOSE = strm_purpose
9065 AND START_DATE <= expStartDate
9066 AND NVL(END_DATE, expStartDate) >= expStartDate
9067 AND STRM.PDT_ID = pdtId;
9068
9069 -- Cursor to fetch the Stream Type for FINANCED/ROLLOVER Fee Payment in case of TR pricing method
9070 CURSOR c_fee_pmnt_strm_type_csr (
9071 pdtId NUMBER,
9072 expStartDate DATE,
9073 strm_purpose VARCHAR)
9074 IS
9075 SELECT STRM.STY_ID PAYMENT_TYPE_ID,
9076 STRM.STY_NAME PAYMENT_TYPE,
9077 STRM.START_DATE,
9078 STRM.END_DATE,
9079 STRM.STY_PURPOSE
9080 FROM OKL_STRM_TMPT_PRIMARY_UV STRM
9081 WHERE STY_PURPOSE = strm_purpose
9082 AND START_DATE <= expStartDate
9083 AND NVL(END_DATE, expStartDate ) >= expStartDate
9084 AND NVL(STRM.CAPITALIZE_YN, 'N') = 'N'
9085 AND STRM.BILLABLE_YN = 'Y'
9086 AND STRM.PDT_ID = pdtId;
9087
9088 -- Cursor to fetch EOT Type
9089 CURSOR get_eot_type( p_lq_id NUMBER )
9090 IS
9091 SELECT lq.id
9092 ,lq.reference_number
9093 ,eot.end_of_term_name
9094 ,eot.eot_type_code eot_type_code
9095 ,eot.end_of_term_id end_of_term_id
9096 ,eotversion.end_of_term_ver_id
9097 FROM OKL_LEASE_QUOTES_B lq,
9098 okl_fe_eo_term_vers eotversion,
9099 okl_fe_eo_terms_all_b eot
9100 WHERE lq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
9101 AND eot.end_of_term_id = eotversion.end_of_term_id
9102 AND lq.id = p_lq_id;
9103 l_eot_type_code VARCHAR2(30);
9104 -- Cursor to handle the CAPITALIZED Fee amount for each Asset
9105 CURSOR get_asset_cap_fee_amt(p_source_type VARCHAR2,
9106 p_source_id OKL_LINE_RELATIONSHIPS_B.source_line_ID%TYPE,
9107 p_related_line_type OKL_LINE_RELATIONSHIPS_B.related_line_type%TYPE)
9108 IS
9109 SELECT SUM(amount) capitalized_amount
9110 FROM okl_line_relationships_v lre
9111 WHERE source_line_type = p_source_type
9112 AND related_line_type = 'CAPITALIZED'
9113 AND source_line_id = p_source_id;
9114
9115 -- Local Variables Declarations !
9116 l_day_count_method VARCHAR2(30);
9117 l_days_in_month VARCHAR2(30);
9118 l_days_in_year VARCHAR2(30);
9119 l_currency VARCHAR2(30);
9120 l_srt_details okl_pricing_utils_pvt.srt_details_rec_type;
9121 l_ast_srt_details okl_pricing_utils_pvt.srt_details_rec_type;
9122 lx_pricing_parameter_rec okl_pricing_utils_pvt.pricing_parameter_rec_type;
9123 x_iir NUMBER;
9124 l_initial_guess NUMBER := 0.1;
9125 x_payment NUMBER;
9126 -- Cash flow and Cash flow level variables
9127 l_cash_flow_rec so_cash_flows_rec_type;
9128 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
9129 l_cash_inflows okl_pricing_utils_pvt.cash_inflows_tbl_type;
9130 l_residual_inflows okl_pricing_utils_pvt.cash_inflows_tbl_type;
9131 cfl_index BINARY_INTEGER;
9132 res_index BINARY_INTEGER;
9133 l_eot_date DATE; -- Effective To of the quote
9134 l_cf_dpp NUMBER;
9135 l_cf_ppy NUMBER;
9136 l_pricing_method VARCHAR2(30);
9137 l_target_rate NUMBER := p_target_rate;
9138 l_adj_mat_cat_rec adj_mat_cat_rec;
9139 -- Variables used for storing back the pricing results !
9140 lx_asset_rec okl_ass_pvt.assv_rec_type;
9141 lx_fee_rec okl_fee_pvt.feev_rec_type;
9142 l_ass_adj_tbl okl_lease_quote_asset_pvt.asset_adjustment_tbl_type;
9143 l_cf_source VARCHAR2(30);
9144 l_fee_yn VARCHAR2(1) := 'N';
9145 l_cashflow_header_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
9146 l_cashflow_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
9147 l_asset_rec OKL_LEASE_QUOTE_ASSET_PVT.asset_rec_type;
9148 l_component_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_component_tbl_type;
9149 l_cf_hdr_rec OKL_LEASE_QUOTE_ASSET_PVT.cashflow_hdr_rec_type;
9150 l_cf_level_tbl OKL_LEASE_QUOTE_ASSET_PVT.cashflow_level_tbl_type;
9151 l_cfo_exists VARCHAR2(30);
9152 l_eot_percentage NUMBER;
9153 l_eot_amount NUMBER;
9154 l_rate_card_id NUMBER;
9155 l_lease_rate_factor NUMBER;
9156 l_asset_follows_lq_pricing VARCHAR2(30);
9157 l_rc_pricing VARCHAR2(30);
9158 l_target_frequency VARCHAR2(30);
9159 l_target_arrears_yn VARCHAR2(30);
9160 l_sty_id NUMBER;
9161 l_srt_id NUMBER;
9162 l_adj_type VARCHAR2(30);
9163 l_quote_type_code OKL_LEASE_QUOTES_B.PARENT_OBJECT_CODE%TYPE;
9164 l_missing_pmnts BOOLEAN;
9165 l_asset_number VARCHAR2(15);
9166 l_fee_name VARCHAR2(150);
9167 BEGIN
9168 l_return_status := OKL_API.G_RET_STS_SUCCESS;
9169 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
9170 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
9171 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
9172 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
9173 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
9174 l_return_status := OKL_API.START_ACTIVITY(
9175 p_api_name => l_api_name,
9176 p_pkg_name => G_PKG_NAME,
9177 p_init_msg_list => p_init_msg_list,
9178 l_api_version => l_api_version,
9179 p_api_version => p_api_version,
9180 p_api_type => g_api_type,
9181 x_return_status => l_return_status);
9182 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9183 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9184 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9185 RAISE OKL_API.G_EXCEPTION_ERROR;
9186 END IF;
9187
9188 --Bug 5884825 PAGARG start
9189 OPEN product_name_csr(p_qte_id);
9190 FETCH product_name_csr INTO l_product_name;
9191 CLOSE product_name_csr;
9192 --Bug 5884825 PAGARG end
9193
9194 -- Fetch the Lease Quote Header Details !
9195 OPEN quote_csr(p_qte_id);
9196 FETCH quote_csr INTO quote_rec;
9197 IF (quote_csr%NOTFOUND) THEN
9198 RAISE okl_api.g_exception_unexpected_error;
9199 END IF;
9200 CLOSE quote_csr;
9201 --Populate l_quote_type_code appropriately
9202 IF quote_rec.parent_object_code = 'LEASEAPP' THEN
9203 l_quote_type_code := 'LA';
9204 ELSE
9205 l_quote_type_code := 'LQ';
9206 END IF;
9207 l_pricing_method := quote_rec.pricing_method;
9208 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9209 'Fetched the Lease Quote Details ' || p_qte_id);
9210 -- Derieve the End of Term Date of the Lease Quote
9211 okl_stream_generator_pvt.add_months_new(
9212 p_start_date => quote_rec.expected_start_date,
9213 p_months_after => quote_rec.term,
9214 x_date => l_eot_date,
9215 x_return_status => l_return_status);
9216 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9217 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9218 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9219 RAISE OKL_API.G_EXCEPTION_ERROR;
9220 END IF;
9221 l_eot_date := l_eot_date - 1;
9222 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9223 'Effective To of the LQ ' || l_eot_date );
9224 -- Retrieve the Payment Structure or build the Cash flow or Cash flow Level objects
9225 lx_pricing_parameter_rec.financed_amount := 0;
9226 lx_pricing_parameter_rec.down_payment := 0;
9227 lx_pricing_parameter_rec.trade_in := 0;
9228 lx_pricing_parameter_rec.subsidy := 0;
9229 -- Retrieve the Asset level information !
9230 FOR assets_rec IN assets_csr(p_qte_id, p_ast_id) -- could be fee id (ROLLOVER or FINANCED)
9231 LOOP
9232 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9233 'Fetching the Asset Details ' );
9234 --Bug 5121548 dpsingh start
9235 l_asset_number := assets_rec.asset_number;
9236 --Bug 5121548 dpsingh end
9237 IF ( assets_rec.fee_type <> 'FREE_FORM1' OR assets_rec.ast_id IS NULL )
9238 THEN
9239 l_fee_yn := 'Y';
9240 ELSE
9241 l_fee_yn := 'N';
9242 END IF;
9243 -- Know the type of the EOT
9244 FOR t_rec IN get_eot_type( p_lq_id => p_qte_id )
9245 LOOP
9246 l_eot_type_code := t_rec.eot_type_code;
9247 END LOOP;
9248 -- Populate the Adjustment Matrix Criteria Record.
9249 l_adj_mat_cat_rec.target_eff_from := quote_rec.expected_start_date;
9250 l_adj_mat_cat_rec.term := quote_rec.term;
9251 IF quote_rec.parent_object_code = 'LEASEOPP'
9252 THEN
9253 -- Fetch from the Lease Opportunity
9254 FOR t_rec IN get_cust_details_csr( p_lq_id => p_qte_id )
9255 LOOP
9256 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
9257 l_adj_mat_cat_rec.customer_credit_class :=
9258 okl_lease_app_pvt.get_credit_classfication(
9259 p_party_id => t_rec.prospect_id,
9260 p_cust_acct_id => t_rec.cust_acct_id,
9261 p_site_use_id => -99);
9262 END LOOP;
9263 ELSE
9264 -- Fetch from the Lease Application
9265 FOR t_rec IN get_cust_details_csr_lapp( p_lq_id => p_qte_id )
9266 LOOP
9267 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
9268 l_adj_mat_cat_rec.customer_credit_class :=
9269 okl_lease_app_pvt.get_credit_classfication(
9270 p_party_id => t_rec.prospect_id,
9271 p_cust_acct_id => t_rec.cust_acct_id,
9272 p_site_use_id => -99);
9273 END LOOP;
9274 END IF;
9275 l_adj_mat_cat_rec.deal_size := NULL;
9276 IF assets_rec.ast_id IS NOT NULL
9277 THEN
9278 l_cf_source := G_CF_SOURCE_LQ_ASS;
9279 lx_pricing_parameter_rec.line_type := 'FREE_FORM1';
9280 ELSE
9281 l_cf_source := G_CF_SOURCE_LQ_FEE;
9282 lx_pricing_parameter_rec.payment_type := 'INCOME';
9283 lx_pricing_parameter_rec.line_type := assets_rec.fee_type;
9284 END IF;
9285 IF quote_rec.pricing_method <> 'RC'
9286 THEN
9287 IF p_price_at_lq_level = FALSE OR p_price_at_lq_level IS NULL
9288 THEN
9289 -- get_lq_cash_flows will fetch the Cash flows or Cash flow levels during Structured
9290 -- pricing (or) builds the CF and CF Levels in case of SRT and return.
9291 -- Very similiar API to the get_qq_cash_flows-2
9292 -- User p_cf_source as G_CF_SOURCE_LQ_ASS, as now we will be pricing the asset
9293 -- with the payment structure defined at the Asset Level itself !
9294 l_srt_id := assets_rec.rate_template_id;
9295 get_lq_cash_flows(
9296 p_api_version => p_api_version,
9297 p_init_msg_list => p_init_msg_list,
9298 x_return_status => l_return_status,
9299 x_msg_count => x_msg_count,
9300 x_msg_data => x_msg_data,
9301 p_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
9302 p_lq_srt_id => assets_rec.rate_template_id,
9303 p_cf_source => l_cf_source,
9304 p_adj_mat_cat_rec => l_adj_mat_cat_rec,
9305 p_pricing_method => quote_rec.pricing_method,
9306 x_days_in_month => l_days_in_month,
9307 x_days_in_year => l_days_in_year,
9308 x_cash_flow_rec => l_cash_flow_rec,
9309 x_cash_flow_det_tbl => l_cash_flow_det_tbl);
9310 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9311 'Fetched asset cash flows at Asset level l_return_status = ' || l_return_status);
9312 ELSE
9313 -- Fetching the Cash Flows Assosiated at the Lesae Quote Level
9314 l_cf_source := G_CF_SOURCE_LQ;
9315 -- Let the initial iir be p_target_rate
9316 l_initial_guess := p_target_rate;
9317 -- Fetch/Retrieve the Cash flows n levels
9318 get_lq_cash_flows(
9319 p_api_version => p_api_version,
9320 p_init_msg_list => p_init_msg_list,
9321 x_return_status => l_return_status,
9322 x_msg_count => x_msg_count,
9323 x_msg_data => x_msg_data,
9324 p_id => p_qte_id,
9325 p_lq_srt_id => quote_rec.rate_template_id,
9326 p_cf_source => l_cf_source,
9327 p_adj_mat_cat_rec => l_adj_mat_cat_rec,
9328 p_pricing_method => quote_rec.pricing_method,
9329 x_days_in_month => l_days_in_month,
9330 x_days_in_year => l_days_in_year,
9331 x_cash_flow_rec => l_cash_flow_rec,
9332 x_cash_flow_det_tbl => l_cash_flow_det_tbl);
9333 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9334 'Fetched asset cash flows @LQ level l_return_status = ' || l_return_status);
9335 END IF; -- If on get_lq_cash_flows
9336 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9337 quote_rec.pricing_method || 'After lq_cash_flows ' || l_return_status);
9338 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9339 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9340 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9341 RAISE OKL_API.G_EXCEPTION_ERROR;
9342 END IF;
9343 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9344 'No. of Cash Flow Levels ' || l_cash_flow_det_tbl.COUNT );
9345 IF l_cash_flow_det_tbl IS NULL OR
9346 l_cash_flow_det_tbl.COUNT <= 0
9347 THEN
9348 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9349 'No Cash flow and Cash flow Levels obtained ! ' );
9350 OKL_API.SET_MESSAGE (
9351 p_app_name => G_APP_NAME,
9352 p_msg_name => 'OKL_LLA_PMT_SELECT');
9353 RAISE OKL_API.G_EXCEPTION_ERROR;
9354 END IF;
9355 l_missing_pmnts := FALSE;
9356 -- When the pricing method is SM, an overridden asset may have a missing payment
9357 -- or not. If no missing payment is present, rates will be present for all CFL levels
9358 -- else, rate wont be present.
9359 IF quote_rec.pricing_method = 'SM'
9360 THEN
9361 FOR t_in IN l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
9362 LOOP
9363 IF ( l_cash_flow_det_tbl(t_in).stub_days > 0 AND
9364 l_cash_flow_det_tbl(t_in).stub_amount IS NULL ) OR
9365 ( l_cash_flow_det_tbl(t_in).number_of_periods > 0 AND
9366 l_cash_flow_det_tbl(t_in).amount IS NULL )
9367 THEN
9368 l_missing_pmnts := TRUE;
9369 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9370 '***** Need to solve for the Missing Payments *********' );
9371 END IF;
9372 END LOOP;
9373 END IF;
9374 -- Populate app. values for l_days_in_month and l_days_in_year !
9375 get_day_count_method(
9376 p_days_in_month => l_days_in_month,
9377 p_days_in_year => l_days_in_year,
9378 x_day_count_method => l_day_count_method,
9379 x_return_status => l_return_status );
9380 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9381 'After get_day_count_method ' || l_return_status);
9382 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9383 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9384 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9385 --Bug 5884825 PAGARG start
9386 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9387 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
9388 p_token1 => 'PRODUCT_NAME',
9389 p_token1_value => l_product_name);
9390 --Bug 5884825 PAGARG end
9391 RAISE OKL_API.G_EXCEPTION_ERROR;
9392 END IF;
9393 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9394 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
9395 -- Get the DPP and PPY inorder to populate for the Residuals Table
9396 get_dpp_ppy(
9397 p_frequency => l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code,
9398 x_dpp => l_cf_dpp,
9399 x_ppy => l_cf_ppy,
9400 x_return_status => l_return_status );
9401 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9402 'After get_dpp_ppy ' || l_return_status );
9403 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9404 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9405 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9406 RAISE OKL_API.G_EXCEPTION_ERROR;
9407 END IF;
9408 END IF; -- IF quote_rec.pricing_method <> 'RC'
9409 -- Retrieve the Cost adjustments defined for the Asset ! None for fees
9410 IF assets_rec.ast_id IS NOT NULL
9411 THEN
9412 FOR asset_cost_adj_rec IN asset_cost_adj_csr(p_qte_id, nvl(assets_rec.ast_id, -9999) )
9413 LOOP
9414 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE AND
9415 quote_rec.pricing_method <> 'SD'
9416 THEN
9417 lx_pricing_parameter_rec.down_payment := lx_pricing_parameter_rec.down_payment
9418 + asset_cost_adj_rec.value;
9419 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE AND
9420 quote_rec.pricing_method <> 'SS'
9421 THEN
9422 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
9423 THEN
9424 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
9425 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
9426 CLOSE subsidy_adj_csr;
9427 -- Bug 6622178 : Start
9428 -- Consider all subsidies for the asset
9429 lx_pricing_parameter_rec.subsidy := lx_pricing_parameter_rec.subsidy + NVL(subsidy_adj_rec.amount,0);
9430 ELSE
9431 lx_pricing_parameter_rec.subsidy := lx_pricing_parameter_rec.subsidy + NVL(asset_cost_adj_rec.value,0);
9432 -- Bug 6622178 : End
9433 END IF;
9434 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE AND
9435 quote_rec.pricing_method <> 'SI'
9436 THEN
9437 lx_pricing_parameter_rec.trade_in := lx_pricing_parameter_rec.trade_in
9438 + asset_cost_adj_rec.value;
9439 END IF;
9440 END LOOP;
9441 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9442 'After Retrieving the Asset Cost Adjustments ');
9443 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9444 'Down Payment| Trade In | Subsidy ' );
9445 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9446 lx_pricing_parameter_rec.down_payment || ' | ' ||
9447 lx_pricing_parameter_rec.trade_in || ' | ' ||
9448 lx_pricing_parameter_rec.subsidy );
9449 END IF; -- IF assets_rec.ast_id IS NOT NULL
9450 -- Generate the Streams for this Asset !
9451 -- Retrieve the Financed amount and the End of Term amount !
9452 res_index := 1;
9453 l_eot_amount := 0;
9454 IF ( assets_rec.ast_id IS NOT NULL)
9455 THEN
9456 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9457 'Asset/Fee ID = ' || assets_rec.ast_id );
9458 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
9459 LOOP
9460 IF l_pricing_method <> 'SF' OR ( quote_rec.pricing_method = 'SF' AND p_price_at_lq_level )
9461 THEN
9462 lx_pricing_parameter_rec.financed_amount := lx_pricing_parameter_rec.financed_amount
9463 + nvl(asset_adj_rec.oec,0);
9464 END IF;
9465 -- Calculate the Capitalized Fee for this Asset
9466 FOR t_rec IN get_asset_cap_fee_amt(
9467 p_source_type => 'ASSET',
9468 p_source_id => assets_rec.ast_id,
9469 p_related_line_type => 'CAPITALIZED')
9470 LOOP
9471 lx_pricing_parameter_rec.cap_fee_amount := nvl(t_rec.capitalized_amount, 0);
9472 END LOOP;
9473 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9474 'Unit Cost=' || asset_adj_rec.unit_cost || ' No. of Units ' || asset_adj_rec.number_of_units);
9475 l_residual_inflows(res_index).line_number := res_index;
9476 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' ) AND
9477 ( l_pricing_method <> 'SF' OR ( quote_rec.pricing_method = 'SF' AND p_price_at_lq_level ) )
9478 THEN
9479 -- Formula: EOT amount = OEC * residual_percentage
9480 -- The above formulat is applicable, a/ When EOT is PERCENT/RESIDUAL_PERCENT
9481 -- b/ When solving for an overridden asset, its financed amount.
9482 -- c/ When Qt. level pricing method is SF, but you are here actually for derieving
9483 -- the payment structures for non-overridden assets when pricing method is SF
9484 l_residual_inflows(res_index).cf_amount :=
9485 (asset_adj_rec.end_of_term_value/100) * nvl(asset_adj_rec.unit_cost * asset_adj_rec.number_of_units,0);
9486 l_eot_percentage := asset_adj_rec.end_of_term_value;
9487 ELSIF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' ) AND
9488 ( l_pricing_method = 'SF' )
9489 THEN
9490 -- EOT is given in terms of percentage .. store the percentage
9491 -- NOTE: For overriden assets, OEC percentage doesnot matter. As they are being priced seperately
9492 l_residual_inflows(res_index).cf_amount := (asset_adj_rec.end_of_term_value/100);
9493 ELSE
9494 -- EOT is an amount so directly store it ..
9495 l_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
9496 END IF;
9497 -- Store the End of Term Value
9498 l_eot_amount := l_eot_amount + l_residual_inflows(res_index).cf_amount;
9499 l_residual_inflows(res_index).cf_date := l_eot_date;
9500 l_residual_inflows(res_index).cf_miss_pay := 'N';
9501 l_residual_inflows(res_index).is_stub := 'N';
9502 l_residual_inflows(res_index).is_arrears := 'Y';
9503 l_residual_inflows(res_index).cf_dpp := l_cf_dpp;
9504 l_residual_inflows(res_index).cf_ppy := l_cf_ppy;
9505 -- Increment the res_index
9506 res_index := res_index + 1;
9507 END LOOP;
9508 ELSE -- ELSE IT IS A FEE
9509 lx_pricing_parameter_rec.financed_amount := assets_rec.fee_amount;
9510 END IF;
9511 IF l_pricing_method = 'RC' AND l_fee_yn = 'N'
9512 THEN
9513 -- Calculate the EOT Percentage Amount
9514 IF ( l_eot_type_code <> 'PERCENT' AND l_eot_type_code <> 'RESIDUAL_PERCENT' )
9515 THEN
9516 l_eot_percentage := nvl(l_eot_amount,0) / lx_pricing_parameter_rec.financed_amount * 100;
9517 END IF;
9518 l_asset_follows_lq_pricing := 'Y';
9519 l_rc_pricing := 'Y';
9520 -- Prioritize Configuration line ones first
9521 IF nvl(quote_rec.line_level_pricing, 'N') = 'Y'
9522 THEN
9523 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9524 '******* Line Level Pricing is enabled at Quote *******' );
9525 -- Line level pricing has been enabled
9526 -- Store the Lease Rate Factor and Rate Template of the of the Configuration lines
9527 IF nvl(assets_rec.structured_pricing, 'N') = 'Y'
9528 THEN
9529 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9530 '******* Structured Pricing picked @ Asset ******* ' || assets_rec.structured_pricing );
9531 l_lease_rate_factor := assets_rec.lease_rate_factor;
9532 l_asset_follows_lq_pricing := 'N';
9533 l_rc_pricing := 'N';
9534 -- May need to store the Frequency/Arrears flag even here
9535 l_target_frequency := assets_rec.target_frequency;
9536 l_target_arrears_yn := assets_rec.target_arrears;
9537 ELSIF assets_rec.rate_card_id IS NOT NULL
9538 THEN
9539 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9540 '******* Rate Card picked @ Asset ******* ' || assets_rec.rate_card_id );
9541 l_rate_card_id := assets_rec.rate_card_id;
9542 l_asset_follows_lq_pricing := 'N';
9543 l_rc_pricing := 'Y';
9544 END IF;
9545 END IF;
9546 IF NVL(quote_rec.line_level_pricing, 'N') = 'N' OR
9547 l_asset_follows_lq_pricing = 'Y'
9548 THEN
9549 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9550 '******* Either Line Level Pricing is NULL/N or Asset follws rate @ Quote *******' ||
9551 quote_rec.line_level_pricing || ' | ' || l_asset_follows_lq_pricing );
9552 -- If Line level pricing is not picked or
9553 -- the configuration line is not overriding the pricing params
9554 -- picked at the lease quote level, use the data at the lease quote level itself.
9555 IF nvl(quote_rec.structured_pricing, 'N') = 'Y'
9556 THEN
9557 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9558 '******* Structured Pricing Enabled @ Quote *******' || quote_rec.structured_pricing );
9559 l_lease_rate_factor := quote_rec.lease_rate_factor;
9560 l_rc_pricing := 'N';
9561 -- May need to store the Frequency/Arrears flag even here
9562 l_target_frequency := quote_rec.target_frequency;
9563 l_target_arrears_yn := quote_rec.target_arrears;
9564 ELSIF quote_rec.rate_card_id IS NOT NULL
9565 THEN
9566 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9567 '******* Rate Card Picked @ Quote *******' || quote_rec.rate_card_id );
9568 l_rate_card_id := quote_rec.rate_card_id;
9569 l_rc_pricing := 'Y';
9570 END IF;
9571 END IF;
9572 ELSIF l_pricing_method = 'RC' AND l_fee_yn = 'Y'
9573 THEN
9574 -- Handling seperately for config fee FINANCED/ROLLOVER
9575 l_eot_percentage := 0;
9576 l_asset_follows_lq_pricing := 'N';
9577 IF nvl(assets_rec.structured_pricing, 'N') = 'Y'
9578 THEN
9579 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9580 '******* Structured Pricing picked @ Config FEE level = ' || assets_rec.structured_pricing );
9581 l_lease_rate_factor := assets_rec.lease_rate_factor;
9582 l_asset_follows_lq_pricing := 'N';
9583 l_rc_pricing := 'N';
9584 -- May need to store the Frequency/Arrears flag even here
9585 l_target_frequency := assets_rec.target_frequency;
9586 l_target_arrears_yn := assets_rec.target_arrears;
9587 ELSIF assets_rec.rate_card_id IS NOT NULL
9588 THEN
9589 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9590 '******* Rate Card picked @ config Fee Level = ' || assets_rec.rate_card_id );
9591 l_rate_card_id := assets_rec.rate_card_id;
9592 l_rc_pricing := 'Y';
9593 END IF;
9594 END IF;
9595 IF l_pricing_method = 'RC' AND
9596 l_rc_pricing = 'Y'
9597 THEN
9598 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9599 'Pricing using a Rate Card with ID ' || l_rate_card_id );
9600 get_lease_rate_factors(
9601 p_api_version => p_api_version,
9602 p_init_msg_list => p_init_msg_list,
9603 x_return_status => l_return_status,
9604 x_msg_count => x_msg_count,
9605 x_msg_data => x_msg_data,
9606 p_lrt_id => l_rate_card_id,
9607 p_start_date => quote_rec.expected_start_date,
9608 p_term_in_months => quote_rec.term,
9609 p_eot_percentage => l_eot_percentage,
9610 x_lrs_details => l_lrs_details,
9611 x_lrs_factor => l_lrs_factor,
9612 x_lrs_levels => l_lrs_levels);
9613 -- If unable to find the Lease Rate Factor levels throw the error ..
9614 IF l_return_status <> OKL_API.G_RET_STS_SUCCESS
9615 THEN
9616 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9617 'Couldnot found the Lease Rate Factor levels for configuration line ' || assets_rec.name );
9618 -- Show the message and then return back throwing an error!
9619 OKL_API.set_message(
9620 p_app_name => G_APP_NAME,
9621 p_msg_name => 'OKL_LP_NO_LRS_LEVELS_FOUND',
9622 p_token1 => 'ITEMCAT',
9623 p_token1_value => assets_rec.name,
9624 p_token2 => 'ITEMTERM',
9625 p_token2_value => quote_rec.term,
9626 p_token3 => 'ITEMEOTPERCENT',
9627 p_token3_value => ROUND(l_eot_percentage,4) );
9628 RAISE OKL_API.G_EXCEPTION_ERROR;
9629 END IF;
9630 -- Apply the adjustment matrix if needed!
9631 l_adj_factor := 0;
9632 IF l_lrs_details.adj_mat_version_id IS NOT NULL
9633 THEN
9634 l_ac_rec_type.src_id := l_lrs_details.adj_mat_version_id; -- Pricing adjustment matrix ID
9635 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
9636 l_ac_rec_type.target_id := quote_rec.ID ; -- Quote ID
9637 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
9638 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
9639 l_ac_rec_type.target_eff_from := quote_rec.expected_start_date; -- Quote effective From
9640 l_ac_rec_type.term := quote_rec.term; -- Remaining four will be from teh business object like QQ / LQ
9641 l_ac_rec_type.territory := l_adj_mat_cat_rec.territory;
9642 l_ac_rec_type.deal_size := lx_pricing_parameter_rec.financed_amount; -- Not sure how to pass this value
9643 l_ac_rec_type.customer_credit_class := l_adj_mat_cat_rec.customer_credit_class; -- Not sure how to pass this even ..
9644 -- Fetching the deal_size ..
9645 -- Calling the API to get the adjustment factor ..
9646 okl_ec_evaluate_pvt.get_adjustment_factor(
9647 p_api_version => p_api_version,
9648 p_init_msg_list => p_init_msg_list,
9649 x_return_status => x_return_status,
9650 x_msg_count => x_msg_count,
9651 x_msg_data => x_msg_data,
9652 p_okl_ac_rec => l_ac_rec_type,
9653 x_adjustment_factor => l_adj_factor );
9654 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9655 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9656 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9657 RAISE OKL_API.G_EXCEPTION_ERROR;
9658 END IF;
9659 END IF;
9660 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9661 'Adjustment Factor ' || l_adj_factor );
9662 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
9663 p_frequency => l_lrs_details.frq_code,
9664 x_return_status => l_return_status);
9665 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9666 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9667 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9668 RAISE OKL_API.G_EXCEPTION_ERROR;
9669 END IF;
9670 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9671 'Months/Period ' || l_months_per_period );
9672 l_cash_flow_rec.due_arrears_yn := l_lrs_details.arrears_yn;
9673 --Populating the Cash Flow Levels
9674 l_months_after := 0;
9675 cf_index := 1;
9676 FOR i in l_lrs_levels.FIRST .. l_lrs_levels.LAST
9677 LOOP
9678 l_cash_flow_det_tbl(cf_index).fqy_code := l_lrs_details.frq_code;
9679 l_cash_flow_det_tbl(cf_index).number_of_periods := l_lrs_levels(i).periods;
9680 -- FORMULA: Periodic Amt = (Rate Factor + Adj. Factor ) * ( C - NVL( S+D+T, 0) )
9681 l_cash_flow_det_tbl(cf_index).amount :=
9682 ( l_lrs_levels(cf_index).lease_rate_factor + NVL(l_adj_factor,0) ) *
9683 ( lx_pricing_parameter_rec.financed_amount - NVL(lx_pricing_parameter_rec.subsidy +
9684 lx_pricing_parameter_rec.down_payment + lx_pricing_parameter_rec.trade_in,0 ) );
9685 l_cash_flow_det_tbl(cf_index).is_stub := 'N';
9686 -- Need to populate the start date per line .. !!
9687 okl_stream_generator_pvt.add_months_new(
9688 p_start_date => quote_rec.expected_start_date,
9689 p_months_after => l_months_after,
9690 x_date => l_cash_flow_det_tbl(cf_index).start_date,
9691 x_return_status => l_return_status);
9692 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9693 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9694 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9695 RAISE OKL_API.G_EXCEPTION_ERROR;
9696 END IF;
9697 -- Add to the l_months_after
9698 l_months_after := l_months_after + ( l_lrs_levels(i).periods * l_months_per_period );
9699 -- Increment the index
9700 cf_index := cf_index + 1;
9701 END LOOP;
9702 ELSIF l_pricing_method = 'RC' AND
9703 l_rc_pricing = 'N'
9704 THEN
9705 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9706 '!!!!! STRUCTURED PRICING IN RATE CARD PRICING !!!!!! ' );
9707 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9708 'lease rate factor | Frequency | Arrears ' );
9709 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9710 l_lease_rate_factor || ' | ' || l_target_frequency || ' | ' || l_target_arrears_yn );
9711 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
9712 p_frequency => l_target_frequency,
9713 x_return_status => l_return_status);
9714 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9715 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9716 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9717 RAISE OKL_API.G_EXCEPTION_ERROR;
9718 END IF;
9719 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9720 'Months/Period ' || l_months_per_period );
9721 l_cash_flow_rec.due_arrears_yn := l_target_arrears_yn;
9722 --Populating the Cash Flow Levels
9723 l_months_after := 0;
9724 l_cash_flow_det_tbl(1).fqy_code := l_target_frequency;
9725 l_cash_flow_det_tbl(1).number_of_periods := quote_rec.term/l_months_per_period;
9726 -- Need to check whether the periods is a whole number or not
9727 IF trunc(l_cash_flow_det_tbl(1).number_of_periods) <>
9728 l_cash_flow_det_tbl(1).number_of_periods
9729 THEN
9730 -- Throw the message saying that Periods have to be whole number
9731 OKL_API.SET_MESSAGE (
9732 p_app_name => G_APP_NAME,
9733 p_msg_name => 'OKL_LEVEL_PERIOD_FRACTION');
9734 RAISE OKL_API.G_EXCEPTION_ERROR;
9735 END IF;
9736 -- FORMULA: Periodic Amt = User Entered Rate Factor * ( C - NVL( S+D+T, 0) )
9737 l_cash_flow_det_tbl(1).amount := l_lease_rate_factor *
9738 ( lx_pricing_parameter_rec.financed_amount - NVL(lx_pricing_parameter_rec.subsidy +
9739 lx_pricing_parameter_rec.down_payment + lx_pricing_parameter_rec.trade_in,0 ) );
9740 l_cash_flow_det_tbl(1).is_stub := 'N';
9741 l_cash_flow_det_tbl(1).start_date := quote_rec.expected_start_date;
9742 END IF;
9743 -- Generate the Streams based on the Cash flows obtained above
9744 IF l_cash_flow_det_tbl IS NOT NULL AND
9745 l_cash_flow_det_tbl.COUNT > 0
9746 THEN
9747 -- Initialize the Strm Count to Zero
9748 gen_so_cf_strms(
9749 p_api_version => p_api_version,
9750 p_init_msg_list => p_init_msg_list,
9751 x_return_status => l_return_status,
9752 x_msg_count => x_msg_count,
9753 x_msg_data => x_msg_data,
9754 p_cash_flow_rec => l_cash_flow_rec,
9755 p_cf_details_tbl => l_cash_flow_det_tbl,
9756 x_cash_inflow_strms_tbl => l_cash_inflows);
9757 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9758 'After gen_so_cf_strms ' || l_return_status);
9759 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9760 'Number of Stream Elements generated ' || l_cash_inflows.COUNT);
9761 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9762 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9763 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9764 RAISE OKL_API.G_EXCEPTION_ERROR;
9765 END IF;
9766 ELSE
9767 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9768 'No Cash flow and Cash flow Levels obtained ! ' );
9769 OKL_API.SET_MESSAGE (
9770 p_app_name => G_APP_NAME,
9771 p_msg_name => 'OKL_LLA_PMT_SELECT');
9772 RAISE OKL_API.G_EXCEPTION_ERROR;
9773 END IF; -- IF l_cash_flow_det_tbl.COUNT > 0
9774 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9775 'After building the Residual Table Count ' || l_residual_inflows.COUNT );
9776 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9777 'Financed Amount = ' || lx_pricing_parameter_rec.financed_amount);
9778 lx_pricing_parameter_rec.cash_inflows := l_cash_inflows;
9779 lx_pricing_parameter_rec.residual_inflows := l_residual_inflows;
9780 -- Bug 7440199: Quote Streams ER: RGOOTY
9781 lx_pricing_parameter_rec.cfo_id := l_cash_flow_rec.cfo_id;
9782 -- Bug 7440199: Quote Streams ER: RGOOTY
9783 IF quote_rec.pricing_method = 'RC'
9784 THEN
9785 -- Get the DPP and PPY inorder to populate for the Residuals Table
9786 get_dpp_ppy(
9787 p_frequency => l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code,
9788 x_dpp => l_cf_dpp,
9789 x_ppy => l_cf_ppy,
9790 x_return_status => l_return_status );
9791 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9792 'After get_dpp_ppy ' || l_return_status );
9793 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9794 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9795 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9796 RAISE OKL_API.G_EXCEPTION_ERROR;
9797 END IF;
9798 IF lx_pricing_parameter_rec.residual_inflows.COUNT > 0
9799 THEN
9800 FOR r_in IN lx_pricing_parameter_rec.residual_inflows.FIRST ..
9801 lx_pricing_parameter_rec.residual_inflows.LAST
9802 LOOP
9803 lx_pricing_parameter_rec.residual_inflows(r_in).cf_dpp := l_cf_dpp;
9804 lx_pricing_parameter_rec.residual_inflows(r_in).cf_ppy := l_cf_ppy;
9805 END LOOP;
9806 END IF;
9807 END IF;
9808 IF quote_rec.pricing_method = 'TR' AND l_fee_yn = 'Y'
9809 THEN
9810 FOR t_in IN lx_pricing_parameter_rec.cash_inflows.FIRST ..
9811 lx_pricing_parameter_rec.cash_inflows.LAST
9812 LOOP
9813 -- For each cash flow level use the SUB_IIR rate solved
9814 lx_pricing_parameter_rec.cash_inflows(t_in).cf_rate := p_target_rate ;
9815 END LOOP;
9816 END IF;
9817 -- End: Fix for SY pricing method @ Asset Level
9818 IF quote_rec.pricing_method = 'SM' AND l_missing_pmnts = FALSE
9819 THEN
9820 -- Nothing to be solved for
9821 NULL;
9822 ELSE
9823 IF ( ( l_fee_yn = 'Y' ) AND ( l_pricing_method IN ( 'SP', 'SM', 'TR' ) ) ) OR
9824 ( ( l_fee_yn = 'N' ) AND ( l_pricing_method NOT IN ( 'SY', 'RC' ) ) )
9825 THEN
9826 -- call compute_iir for payment
9827 -- For fees, when the pricing method is SP/SM/TR, then only we solve for the payment amount
9828 -- For Assets, when pricing method is SY/RC, therez nothing to solve
9829 IF l_pricing_method = 'SF' AND
9830 ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
9831 THEN
9832 l_pricing_method := 'SFP';
9833 END IF;
9834 compute_iir(
9835 p_api_version => p_api_version,
9836 p_init_msg_list => p_init_msg_list,
9837 x_return_status => l_return_status,
9838 x_msg_count => x_msg_count,
9839 x_msg_data => x_msg_data,
9840 p_start_date => quote_rec.expected_start_date,
9841 p_day_count_method => l_day_count_method,
9842 p_pricing_method => l_pricing_method,
9843 p_initial_guess => l_initial_guess,
9844 px_pricing_parameter_rec => lx_pricing_parameter_rec,
9845 px_iir => x_iir,
9846 x_payment => x_payment);
9847 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9848 'After compute_iir l_return_status = ' || l_return_status || 'Solved Payment Amount ' || x_payment);
9849 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9850 'Financed Amount | Down Payment | Subsidy | Trade in ');
9851 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9852 ROUND(lx_pricing_parameter_rec.financed_amount, 4) || ' | ' || ROUND(lx_pricing_parameter_rec.down_payment, 4) || ' | ' ||
9853 ROUND(lx_pricing_parameter_rec.subsidy, 4) || ' | ' || ROUND(lx_pricing_parameter_rec.trade_in, 4) );
9854 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
9855 RAISE okl_api.g_exception_unexpected_error;
9856 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
9857 RAISE okl_api.g_exception_error;
9858 END IF;
9859 IF l_pricing_method IN ( 'SP', 'SM', 'TR' ) AND
9860 x_payment < 0
9861 THEN
9862 --Bug 5121548 dpsingh start
9863 IF l_fee_yn = 'Y'
9864 THEN
9865 OPEN fees_csr(p_qte_id,p_ast_id);
9866 FETCH fees_csr into l_fee_name;
9867 CLOSE fees_csr;
9868 OKL_API.SET_MESSAGE (
9869 p_app_name => G_APP_NAME,
9870 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT_FEE',
9871 p_token1 => 'TYPE',
9872 p_token1_value => 'Payment',
9873 p_token2 => 'AMOUNT',
9874 p_token2_value => round(x_payment,2),
9875 p_token3 => 'NAME',
9876 p_token3_value => l_fee_name);
9877 ELSE
9878 OKL_API.SET_MESSAGE (
9879 p_app_name => G_APP_NAME,
9880 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT_ASSET',
9881 p_token1 => 'TYPE',
9882 p_token1_value => 'Payment',
9883 p_token2 => 'AMOUNT',
9884 p_token2_value => round(x_payment,2),
9885 p_token3 => 'NAME',
9886 p_token3_value => l_asset_number);
9887 END IF;
9888 --Bug 5121548 dpsingh end
9889 RAISE okl_api.g_exception_error;
9890 END IF;
9891 IF l_pricing_method = 'SFP'
9892 THEN
9893 l_pricing_method := 'SF'; -- Revert back the pricing method to 'SF'
9894 -- Change the residual amount
9895 IF lx_pricing_parameter_rec.residual_inflows IS NOT NULL AND
9896 lx_pricing_parameter_rec.residual_inflows.COUNT > 0
9897 THEN
9898 FOR t_in IN lx_pricing_parameter_rec.residual_inflows.FIRST ..
9899 lx_pricing_parameter_rec.residual_inflows.LAST
9900 LOOP
9901 lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount :=
9902 lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount *
9903 lx_pricing_parameter_rec.financed_amount;
9904 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9905 'lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount = ' ||
9906 round(lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount, 4) );
9907 END LOOP;
9908 END IF; -- Count on Residual Table
9909 END IF; -- IF l_pricing_method = 'SFP'
9910 END IF;
9911 END IF;
9912 END LOOP; -- For loop on assets_csr
9913 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9914 ' quote_rec.pricing_method = ' || quote_rec.pricing_method ||
9915 'assets_rec.rate_template_id = ' || assets_rec.rate_template_id );
9916 IF quote_rec.pricing_method = 'SP' OR
9917 quote_rec.pricing_method = 'RC' OR
9918 ( quote_rec.pricing_method = 'SM' AND l_missing_pmnts )OR
9919 (p_price_at_lq_level AND quote_rec.pricing_method IN ( 'SY', 'TR', 'SF') ) OR
9920 l_srt_id IS NOT NULL -- When the lines uses the SRT
9921 THEN
9922 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9923 'Creating/Updating the Cash Flow Object !!' );
9924 -- Check whether CFO already exists or not, if so, update
9925 -- else create new
9926 l_cfo_exists := 'NO';
9927 IF l_fee_yn = 'Y'
9928 THEN
9929 l_cashflow_header_rec.parent_object_code := 'QUOTED_FEE';
9930 FOR t_rec IN check_cfo_exists_csr(
9931 p_oty_code => 'QUOTED_FEE',
9932 p_source_table => 'OKL_FEES_B',
9933 p_source_id => p_ast_id)
9934 LOOP
9935 l_cfo_exists := t_rec.cfo_exists;
9936 l_sty_id := t_rec.sty_id;
9937 END LOOP;
9938 ELSE
9939 l_cashflow_header_rec.parent_object_code := 'QUOTED_ASSET';
9940 FOR t_rec IN check_cfo_exists_csr(
9941 p_oty_code => 'QUOTED_ASSET',
9942 p_source_table => 'OKL_ASSETS_B',
9943 p_source_id => p_ast_id)
9944 LOOP
9945 l_cfo_exists := t_rec.cfo_exists;
9946 l_sty_id := t_rec.sty_id;
9947 END LOOP;
9948 END IF;
9949 -- IF cash flows exists delete the existing ones and create afresh ..
9950 IF l_cfo_exists = 'YES'
9951 THEN
9952 -- Delete the Cash Flow Levels which may be already created by Pricing ..
9953 okl_lease_quote_cashflow_pvt.delete_cashflows (
9954 p_api_version => p_api_version,
9955 p_init_msg_list => p_init_msg_list,
9956 p_transaction_control => NULL,
9957 p_source_object_code => l_cashflow_header_rec.parent_object_code,
9958 p_source_object_id => p_ast_id,
9959 x_return_status => l_return_status,
9960 x_msg_count => x_msg_count,
9961 x_msg_data => x_msg_data);
9962 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9963 ' ----- After deleting the Cash flows for the asset ' || l_return_status );
9964 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
9965 RAISE okl_api.g_exception_unexpected_error;
9966 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
9967 RAISE okl_api.g_exception_error;
9968 END IF;
9969 ELSE
9970 FOR t_rec IN c_strm_type (
9971 pdtId => quote_rec.product_id,
9972 expStartDate => quote_rec.expected_start_date,
9973 strm_purpose => 'RENT')
9974 LOOP
9975 l_sty_id := t_rec.payment_type_id;
9976 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9977 'Fetched stream type id from the cursor' || l_sty_id );
9978 END LOOP;
9979 END IF;
9980 -- Create cash flows in case of user using the SRT
9981 l_cashflow_header_rec.parent_object_id := p_ast_id;
9982 l_cashflow_header_rec.type_code := 'INFLOW';
9983 l_cashflow_header_rec.status_code := l_cash_flow_rec.sts_code;
9984 IF p_price_at_lq_level = TRUE
9985 THEN
9986 -- You will reach this code only when you are actually Solving for Payment
9987 -- or Missing Payment for the Assets, which follow the payment strucutre
9988 -- at the lease quote, and you want to find out the payment at each and every
9989 -- Non-overriding Fee/Asset.
9990 -- Pricing solves the payment amount for all the non-overriding assets and
9991 -- store the WORK statused cash flow levels.
9992 l_cashflow_header_rec.status_code := 'WORK';
9993 END IF;
9994 l_cashflow_header_rec.arrears_flag := l_cash_flow_rec.due_arrears_yn;
9995 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9996 'Stream type id using for creation of cash flows ' || l_sty_id );
9997 IF l_sty_id IS NULL AND
9998 l_fee_yn = 'N'
9999 THEN
10000 -- When pricing option is SRT, you may come here ..
10001 FOR t_rec IN c_strm_type (
10002 pdtId => quote_rec.product_id,
10003 expStartDate => quote_rec.expected_start_date,
10004 strm_purpose => 'RENT')
10005 LOOP
10006 l_sty_id := t_rec.payment_type_id;
10007 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10008 'Fetched stream type id from the cursor' || l_sty_id );
10009 END LOOP;
10010 END IF;
10011 IF l_cash_flow_rec.sty_id IS NOT NULL
10012 THEN
10013 l_cashflow_header_rec.stream_type_id := l_cash_flow_rec.sty_id;
10014 ELSE
10015 l_cashflow_header_rec.stream_type_id := l_sty_id;
10016 END IF;
10017 -- Exception for Stream Type id is: TR pricing method, Fees=Yes,
10018 IF l_fee_yn = 'Y' and quote_rec.pricing_method = 'TR'
10019 THEN
10020 FOR t_rec IN c_fee_pmnt_strm_type_csr ( pdtId => quote_rec.product_id,
10021 expStartDate => quote_rec.expected_start_date, strm_purpose => 'FEE_PAYMENT')
10022 LOOP
10023 l_cashflow_header_rec.stream_type_id := t_rec.payment_type_id;
10024 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10025 'Fetched fee pmnt cursor id from the cursor' || l_sty_id );
10026 EXIT;
10027 END LOOP;
10028 END IF;
10029 l_cashflow_header_rec.frequency_code := l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code;
10030 l_cashflow_header_rec.quote_type_code := l_quote_type_code;
10031 l_cashflow_header_rec.quote_id := p_qte_id;
10032 FOR i in l_cash_flow_det_tbl.FIRST..l_cash_flow_det_tbl.LAST
10033 LOOP
10034 l_cashflow_level_tbl(i).start_date := l_cash_flow_det_tbl(i).start_date;
10035 IF p_price_at_lq_level AND quote_rec.pricing_method IN ('SY', 'TR', 'SF')
10036 THEN
10037 l_cashflow_level_tbl(i).rate := quote_rec.sub_iir;
10038 ELSE
10039 l_cashflow_level_tbl(i).rate := l_cash_flow_det_tbl(i).rate;
10040 END IF;
10041 l_cashflow_level_tbl(i).stub_amount := l_cash_flow_det_tbl(i).stub_amount;
10042 l_cashflow_level_tbl(i).stub_days := l_cash_flow_det_tbl(i).stub_days;
10043 l_cashflow_level_tbl(i).periods := l_cash_flow_det_tbl(i).number_of_periods;
10044 l_cashflow_level_tbl(i).periodic_amount := l_cash_flow_det_tbl(i).amount;
10045 IF quote_rec.pricing_method = 'RC'
10046 THEN
10047 l_cashflow_level_tbl(i).periodic_amount := l_cash_flow_det_tbl(i).amount;
10048 ELSIF quote_rec.pricing_method = 'SP' OR
10049 ( p_price_at_lq_level AND quote_rec.pricing_method IN ('SY', 'TR', 'SF'))
10050 THEN
10051 -- Pricing would have solved the periodic/stub amount for all cash flow levels
10052 IF l_cash_flow_det_tbl(i).stub_days > 0
10053 THEN
10054 l_cashflow_level_tbl(i).stub_amount := x_payment;
10055 ELSIF l_cash_flow_det_tbl(i).number_of_periods > 0
10056 THEN
10057 l_cashflow_level_tbl(i).periodic_amount := x_payment;
10058 END IF;
10059 ELSIF quote_rec.pricing_method = 'SM'
10060 THEN
10061 -- Pricing would have solved the periodic/stub amount for only the cash flow
10062 -- level which misses it ..
10063 IF l_cash_flow_det_tbl(i).stub_days > 0 AND l_cash_flow_det_tbl(i).stub_amount IS NULL
10064 THEN
10065 l_cashflow_level_tbl(i).stub_amount := x_payment;
10066 l_cashflow_level_tbl(i).missing_pmt_flag := 'Y';
10067 ELSIF l_cash_flow_det_tbl(i).number_of_periods > 0 AND l_cash_flow_det_tbl(i).amount IS NULL
10068 THEN
10069 l_cashflow_level_tbl(i).periodic_amount := x_payment;
10070 l_cashflow_level_tbl(i).missing_pmt_flag := 'Y';
10071 END IF;
10072 END IF;
10073 l_cashflow_level_tbl(i).record_mode := 'CREATE';
10074 END LOOP;
10075 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10076 'Before calling create_cash_flow ' );
10077 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
10078 p_api_version => p_api_version,
10079 p_init_msg_list => p_init_msg_list,
10080 p_transaction_control => NULL,
10081 p_cashflow_header_rec => l_cashflow_header_rec,
10082 p_cashflow_level_tbl => l_cashflow_level_tbl,
10083 x_return_status => l_return_status,
10084 x_msg_count => x_msg_count,
10085 x_msg_data => x_msg_data);
10086 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10087 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10088 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10089 RAISE OKL_API.G_EXCEPTION_ERROR;
10090 END IF;
10091 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
10092 lx_pricing_parameter_rec.cfo_id := l_cashflow_header_rec.cashflow_object_id;
10093 -- Bug 7440199: Quote Streams ER: RGOOTY: End
10094 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10095 'After calling create_cash_flow ' || l_return_status);
10096 END IF;
10097 -- When the pricing method is SP/SM update the pricing rec with the
10098 -- solved payment amount back
10099 IF quote_rec.pricing_method IN ( 'SP', 'TR' ) OR
10100 ( quote_rec.pricing_method = 'SM' AND l_missing_pmnts )
10101 THEN
10102 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10103 'Updating the Cash inflows back with the solved payment amount ' || x_payment);
10104 FOR t_in IN lx_pricing_parameter_rec.cash_inflows.FIRST ..
10105 lx_pricing_parameter_rec.cash_inflows.LAST
10106 LOOP
10107 IF lx_pricing_parameter_rec.cash_inflows(t_in).cf_miss_pay = 'Y' OR
10108 quote_rec.pricing_method IN ( 'SP', 'TR' )
10109 THEN
10110 lx_pricing_parameter_rec.cash_inflows(t_in).cf_amount := x_payment;
10111 END IF;
10112 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10113 lx_pricing_parameter_rec.cash_inflows(t_in).cf_date || ' | ' ||
10114 lx_pricing_parameter_rec.cash_inflows(t_in).cf_miss_pay || ' | ' ||
10115 lx_pricing_parameter_rec.cash_inflows(t_in).cf_amount );
10116 END LOOP;
10117 END IF;
10118 IF quote_rec.pricing_method = 'SF' AND
10119 p_price_at_lq_level = FALSE
10120 THEN
10121 lx_asset_rec.id := p_ast_id;
10122 IF (l_fee_yn = 'N')
10123 THEN
10124 -- Need to change here to call the okl_lease_quote_asset_pvt.update_asset
10125 l_asset_rec.id := p_ast_id;
10126 l_asset_rec.oec := lx_pricing_parameter_rec.financed_amount;
10127 FOR t_rec IN c_asset_comp_csr( p_asset_id => p_ast_id )
10128 LOOP
10129 l_component_tbl(1).id := t_rec.id;
10130 l_component_tbl(1).unit_cost := l_asset_rec.oec / t_rec.number_of_units;
10131 l_component_tbl(1).record_mode := 'update';
10132 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10133 'Updated l_component_tbl(1).unit_cost = ' || l_component_tbl(1).unit_cost );
10134 END LOOP;
10135 -- Call the update api to store back the calculated OEC of the Asset!
10136 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10137 'Before OKL_LEASE_QUOTE_ASSET_PVT.update_asset ');
10138 -- Instead we need to use the OKL_LEASE_QUOTE_ASSET_PVT.update_asset
10139 OKL_LEASE_QUOTE_ASSET_PVT.update_asset (
10140 p_api_version => p_api_version,
10141 p_init_msg_list => p_init_msg_list,
10142 p_transaction_control => 'T',
10143 p_asset_rec => l_asset_rec,
10144 p_component_tbl => l_component_tbl,
10145 p_cf_hdr_rec => l_cf_hdr_rec,
10146 p_cf_level_tbl => l_cf_level_tbl,
10147 x_return_status => l_return_status,
10148 x_msg_count => x_msg_count,
10149 x_msg_data => x_msg_data);
10150 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10151 'After OKL_LEASE_QUOTE_ASSET_PVT.update_asset ' || l_return_status );
10152 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10153 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10154 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10155 RAISE OKL_API.G_EXCEPTION_ERROR;
10156 END IF;
10157 ELSE
10158 -- Do Nothing
10159 NULL;
10160 END IF;
10161 ELSIF (quote_rec.pricing_method = 'SD' OR
10162 quote_rec.pricing_method = 'SI' OR
10163 quote_rec.pricing_method = 'SS') AND (l_fee_yn = 'N')
10164 THEN
10165 ----------------------------------------------------------------------------------
10166 -- Create an Asset Cost Adjustment for the Solved Down Payment/Trade-in/Subsidy !!
10167 ----------------------------------------------------------------------------------
10168 -- Need to populate the following !!
10169 l_ass_adj_tbl.DELETE;
10170 l_ass_adj_tbl(1).parent_object_code := 'ASSET';
10171 l_ass_adj_tbl(1).parent_object_id := p_ast_id;
10172 l_ass_adj_tbl(1).basis := 'FIXED';
10173 IF quote_rec.pricing_method = 'SI'
10174 THEN
10175 l_ass_adj_tbl(1).adjustment_source_type := 'TRADEIN';
10176 l_ass_adj_tbl(1).VALUE := lx_pricing_parameter_rec.trade_in;
10177 l_adj_type := 'Trade-in';
10178 ELSIF quote_rec.pricing_method = 'SD'
10179 THEN
10180 l_ass_adj_tbl(1).adjustment_source_type := 'DOWN_PAYMENT';
10181 l_ass_adj_tbl(1).VALUE := lx_pricing_parameter_rec.down_payment;
10182 l_adj_type := 'Down Payment';
10183 ELSIF quote_rec.pricing_method = 'SS'
10184 THEN
10185 l_ass_adj_tbl(1).adjustment_source_type := 'SUBSIDY';
10186 l_ass_adj_tbl(1).VALUE := lx_pricing_parameter_rec.subsidy;
10187 l_adj_type := 'Subsidy';
10188 END IF;
10189 IF l_ass_adj_tbl(1).VALUE < 0 THEN
10190 --Bug 5121548 dpsingh start
10191 OKL_API.SET_MESSAGE (
10192 p_app_name => G_APP_NAME,
10193 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT_ASSET',
10194 p_token1 => 'TYPE',
10195 p_token1_value => l_adj_type,
10196 p_token2 => 'AMOUNT',
10197 p_token2_value => round(l_ass_adj_tbl(1).VALUE, 2),
10198 p_token3 => 'NAME',
10199 p_token3_value => l_asset_number);
10200 --Bug 5121548 dpsingh end
10201 RAISE okl_api.g_exception_error;
10202 END IF;
10203 okl_lease_quote_asset_pvt.create_adjustment(
10204 p_api_version => p_api_version,
10205 p_init_msg_list => p_init_msg_list,
10206 p_transaction_control => FND_API.G_TRUE,
10207 p_asset_adj_tbl => l_ass_adj_tbl,
10208 x_return_status => l_return_status,
10209 x_msg_count => x_msg_count,
10210 x_msg_data => x_msg_data );
10211 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10212 'After okl_lease_quote.asset.create_adjustment ' || l_return_status);
10213 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
10214 RAISE okl_api.g_exception_unexpected_error;
10215 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
10216 RAISE okl_api.g_exception_error;
10217 END IF;
10218 END IF; -- IF quote_rec.pricing_method .....
10219 -- Actual logic Ends here
10220 x_pricing_parameter_rec := lx_pricing_parameter_rec;
10221 x_return_status := l_return_status;
10222 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
10223 x_msg_data => x_msg_data);
10224 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10225 'end debug OKLRPIUB.pls call ' || LOWER(l_api_name) );
10226 EXCEPTION
10227 WHEN OKL_API.G_EXCEPTION_ERROR THEN
10228 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10229 p_api_name => l_api_name,
10230 p_pkg_name => G_PKG_NAME,
10231 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
10232 x_msg_count => x_msg_count,
10233 x_msg_data => x_msg_data,
10234 p_api_type => g_api_type);
10235 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
10236 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10237 p_api_name => l_api_name,
10238 p_pkg_name => G_PKG_NAME,
10239 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
10240 x_msg_count => x_msg_count,
10241 x_msg_data => x_msg_data,
10242 p_api_type => g_api_type);
10243 WHEN OTHERS THEN
10244 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10245 p_api_name => l_api_name,
10246 p_pkg_name => G_PKG_NAME,
10247 p_exc_name => 'OTHERS',
10248 x_msg_count => x_msg_count,
10249 x_msg_data => x_msg_data,
10250 p_api_type => g_api_type);
10251 END price_standard_quote_asset;
10252 --------------------------------------------------------------------------------
10253 -- Start of Commnets
10254 -- Procedure Name : is_asset_overriding
10255 -- Description :
10256 -- Business Rules :
10257 -- Parameters :
10258 -- Version : 1.0
10259 -- History : rgooty 5-Aug-2005 - created
10260 -- This is the API, which will return TRUE, if an Asset in a Lease Quote has overridden
10261 -- the Payment option defined at the quote level, otherwise if it has to follow the payment
10262 -- option at the quote level, return false !
10263 -- End of Commnets
10264 --------------------------------------------------------------------------------
10265 FUNCTION is_asset_overriding( p_qte_id IN NUMBER,
10266 p_ast_id IN NUMBER,
10267 p_lq_line_level_pricing IN VARCHAR2,
10268 p_lq_srt_id IN NUMBER,
10269 p_ast_srt_id IN NUMBER,
10270 p_lq_struct_pricing IN VARCHAR2,
10271 p_ast_struct_pricing IN VARCHAR2,
10272 p_lq_arrears_yn IN VARCHAR2,
10273 p_ast_arrears_yn IN VARCHAR2,
10274 x_return_status OUT NOCOPY VARCHAR2)
10275 RETURN BOOLEAN
10276 AS
10277 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'is_asset_overriding';
10278 l_return_status VARCHAR2(1);
10279 l_ret_value BOOLEAN;
10280 BEGIN
10281
10282 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10283 l_ret_value := FALSE;
10284 IF p_lq_line_level_pricing = 'Y' AND
10285 p_lq_struct_pricing IS NULL AND
10286 p_lq_srt_id IS NULL
10287 THEN
10288 -- User opted for Line level override, havent picked Structured Pricing at Quote level
10289 -- and havent picked SRT too at quote level. This means all assets are overriding
10290 l_ret_value := TRUE;
10291 ELSIF p_lq_line_level_pricing IS NULL OR
10292 p_lq_line_level_pricing = 'N'
10293 THEN
10294 l_ret_value := FALSE;
10295 ELSIF p_lq_struct_pricing = 'Y' AND
10296 p_ast_struct_pricing = 'Y'
10297 THEN
10298 -- Case 1: Two scenarios possible here !
10299 -- Lq has a structured payment structure and Asset follows another structured payment structure
10300 IF p_lq_line_level_pricing = 'Y'
10301 THEN
10302 l_ret_value := TRUE;
10303 ELSE
10304 l_ret_value := FALSE;
10305 END IF;
10306 ELSIF p_lq_struct_pricing = 'Y' AND
10307 ( p_ast_struct_pricing = 'N' OR p_ast_srt_id IS NOT NULL )
10308 THEN
10309 -- Case 2: LQ with Structured Pricing and Asset linked to SRT
10310 l_ret_value := TRUE;
10311 ELSIF p_ast_struct_pricing = 'Y' AND
10312 ( p_lq_struct_pricing = 'N' OR p_lq_srt_id IS NOT NULL )
10313 THEN
10314 -- Case 3: LQ linked to SRT and Asset following Strucured Pricing
10315 l_ret_value := TRUE;
10316 ELSIF p_lq_srt_id IS NOT NULL AND
10317 p_ast_srt_id IS NOT NULL AND
10318 p_lq_srt_id <> p_ast_srt_id
10319 THEN
10320 -- Case 4: User picked the SRT at the quote level and at the Asset level
10321 -- also, user picked another SRT !
10322 l_ret_value := TRUE;
10323 ELSIF p_lq_srt_id IS NOT NULL AND
10324 p_ast_srt_id IS NOT NULL AND
10325 p_lq_srt_id = p_ast_srt_id AND
10326 nvl(p_lq_arrears_yn, 'N') <> nvl(p_ast_arrears_yn, 'N')
10327 THEN
10328 -- Case 5: User picked the same SRT at Quote and Asset level,
10329 -- but varied Advance/Arrears
10330 l_ret_value := TRUE;
10331 ELSIF p_lq_srt_id IS NOT NULL AND
10332 p_ast_srt_id IS NOT NULL AND
10333 p_lq_line_level_pricing = 'Y'
10334 THEN
10335 -- Case 6: User picked the same SRT at Quote and Asset level.
10336 -- Returning TRUE in this case also, as User picked the same SRT explicitly
10337 -- but enabling the Line Level Override.
10338 l_ret_value := TRUE;
10339 END IF;
10340 x_return_status := l_return_status;
10341 return l_ret_value;
10342 EXCEPTION
10343 WHEN OKL_API.G_EXCEPTION_ERROR
10344 THEN
10345 x_return_status := G_RET_STS_ERROR;
10346 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR
10347 THEN
10348 x_return_status := G_RET_STS_UNEXP_ERROR;
10349 WHEN OTHERS
10350 THEN
10351 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
10352 p_msg_name => G_DB_ERROR,
10353 p_token1 => G_PROG_NAME_TOKEN,
10354 p_token1_value => l_api_name,
10355 p_token2 => G_SQLCODE_TOKEN,
10356 p_token2_value => sqlcode,
10357 p_token3 => G_SQLERRM_TOKEN,
10358 p_token3_value => sqlerrm);
10359 x_return_status := G_RET_STS_UNEXP_ERROR;
10360 END is_asset_overriding;
10361
10362 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
10363 --------------------------------------------------------------------------------
10364 -- Start of Commnets
10365 -- Procedure Name : get_lq_srvc_cash_flows
10366 -- Description :
10367 -- Business Rules :
10368 -- Parameters :
10369 -- Version : 1.0
10370 -- History : RGOOTY 27-May-2008 - created
10371 -- End of Commnets
10372 --------------------------------------------------------------------------------
10373 PROCEDURE get_lq_srvc_cash_flows(
10374 p_api_version IN NUMBER,
10375 p_init_msg_list IN VARCHAR2,
10376 x_return_status OUT NOCOPY VARCHAR2,
10377 x_msg_count OUT NOCOPY NUMBER,
10378 x_msg_data OUT NOCOPY VARCHAR2,
10379 p_srvc_type IN VARCHAR2,
10380 p_lq_id IN NUMBER,
10381 p_srvc_id IN NUMBER,
10382 x_inflow_caf_rec OUT NOCOPY so_cash_flows_rec_type,
10383 x_inflow_cfl_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
10384 IS
10385 -- Cursor to fetch the Lease Quotes Cash Flow Details
10386 CURSOR lq_cash_flows_csr(
10387 p_id NUMBER,
10388 p_cf_source VARCHAR2,
10389 p_cft_code VARCHAR2)
10390 IS
10391 SELECT cf.id caf_id
10392 ,dnz_khr_id khr_id
10393 ,dnz_qte_id qte_id
10394 ,cfo_id cfo_id
10395 ,sts_code sts_code
10396 ,sty_id sty_id
10397 ,cft_code cft_code
10398 ,due_arrears_yn due_arrears_yn
10399 ,start_date start_date
10400 ,number_of_advance_periods number_of_advance_periods
10401 ,cfo.oty_code oty_code
10402 FROM OKL_CASH_FLOWS cf,
10403 OKL_CASH_FLOW_OBJECTS cfo
10404 WHERE cf.cfo_id = cfo.id
10405 AND cfo.source_table = p_cf_source
10406 AND cfo.source_id = p_id
10407 AND cf .cft_code = p_cft_code ;
10408
10409 -- Cursor to fetch the Cash Flow Details
10410 CURSOR cash_flow_levels_csr( p_caf_id NUMBER )
10411 IS
10412 SELECT id cfl_id
10413 ,caf_id
10414 ,fqy_code
10415 ,rate -- No rate is defined at Cash Flows Level.. Need to confirm
10416 ,stub_days
10417 ,stub_amount
10418 ,number_of_periods
10419 ,amount
10420 ,start_date
10421 FROM OKL_CASH_FLOW_LEVELS
10422 WHERE caf_id = p_caf_id
10423 ORDER BY start_date;
10424
10425 l_api_version CONSTANT NUMBER DEFAULT 1.0;
10426 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lq_srvc_cash_flows';
10427 l_return_status VARCHAR2(1);
10428 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
10429 || G_PKG_NAME || '.' || UPPER(l_api_name);
10430
10431 l_debug_enabled VARCHAR2(10);
10432 is_debug_procedure_on BOOLEAN;
10433 is_debug_statement_on BOOLEAN;
10434 cfl_index NUMBER;
10435 BEGIN
10436 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10437 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
10438 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
10439 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10440 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
10441 -- check for logging on STATEMENT level
10442 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
10443 l_return_status := OKL_API.START_ACTIVITY(
10444 p_api_name => l_api_name,
10445 p_pkg_name => G_PKG_NAME,
10446 p_init_msg_list => p_init_msg_list,
10447 l_api_version => l_api_version,
10448 p_api_version => p_api_version,
10449 p_api_type => g_api_type,
10450 x_return_status => x_return_status);
10451 --Check if activity started successfully
10452 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10453 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10454 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10455 RAISE OKL_API.G_EXCEPTION_ERROR;
10456 END IF;
10457
10458 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10459
10460 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10461 '!!!!! Fetching the Inflow Cash flows for service ' || p_srvc_type );
10462
10463 FOR t_rec IN lq_cash_flows_csr(
10464 p_id => p_srvc_id,
10465 p_cf_source => 'OKL_SERVICES_B',
10466 p_cft_code => 'PAYMENT_SCHEDULE')
10467 LOOP
10468 x_inflow_caf_rec.caf_id := t_rec.caf_id;
10469 x_inflow_caf_rec.khr_id := t_rec.khr_id;
10470 x_inflow_caf_rec.khr_id := t_rec.khr_id;
10471 x_inflow_caf_rec.qte_id := t_rec.qte_id;
10472 x_inflow_caf_rec.cfo_id := t_rec.cfo_id;
10473 x_inflow_caf_rec.sts_code := t_rec.sts_code;
10474 x_inflow_caf_rec.sty_id := t_rec.sty_id;
10475 x_inflow_caf_rec.cft_code := t_rec.cft_code;
10476 x_inflow_caf_rec.due_arrears_yn := t_rec.due_arrears_yn;
10477 x_inflow_caf_rec.start_date := t_rec.start_date;
10478 x_inflow_caf_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
10479 -- Use l_retun_status as a flag
10480 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10481 END LOOP;
10482 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
10483 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
10484 THEN
10485 cfl_index := 1;
10486 -- Cash Flows exists. So, fetch the Cash Flow Levels
10487 FOR t_rec in cash_flow_levels_csr( x_inflow_caf_rec.caf_id )
10488 LOOP
10489 x_inflow_cfl_tbl(cfl_index).cfl_id := t_rec.cfl_id;
10490 x_inflow_cfl_tbl(cfl_index).caf_id := t_rec.caf_id;
10491 x_inflow_cfl_tbl(cfl_index).fqy_code := t_rec.fqy_code;
10492 x_inflow_cfl_tbl(cfl_index).rate := t_rec.rate;
10493 x_inflow_cfl_tbl(cfl_index).stub_days := t_rec.stub_days;
10494 x_inflow_cfl_tbl(cfl_index).stub_amount := t_rec.stub_amount;
10495 x_inflow_cfl_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
10496 x_inflow_cfl_tbl(cfl_index).amount := t_rec.amount;
10497 x_inflow_cfl_tbl(cfl_index).start_date := t_rec.start_date;
10498 x_inflow_cfl_tbl(cfl_index).locked_amt := 'Y';
10499 -- Remember the flag whether its a stub payment or not
10500 IF t_rec.stub_days IS NOT NULL and t_rec.stub_amount IS NOT NULL
10501 THEN
10502 -- Stub Payment
10503 x_inflow_cfl_tbl(cfl_index).is_stub := 'Y';
10504 ELSE
10505 -- Regular Periodic Payment
10506 x_inflow_cfl_tbl(cfl_index).is_stub := 'N';
10507 END IF;
10508 -- Use l_retun_status as a flag
10509 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10510 -- Increment i
10511 cfl_index := cfl_index + 1;
10512 END LOOP;
10513 ELSE
10514 -- Show an error saying that no cash flow levels found
10515 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10516 '!!!!! No Inflow Cash flow levels obtained for the service ' || p_srvc_type );
10517 OKL_API.SET_MESSAGE (
10518 p_app_name => G_APP_NAME,
10519 p_msg_name => 'OKL_LLA_PMT_SELECT');
10520 RAISE OKL_API.G_EXCEPTION_ERROR;
10521 END IF;
10522
10523 -- Setting up the return variables
10524 x_return_status := l_return_status;
10525 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
10526 x_msg_data => x_msg_data);
10527 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10528 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
10529 EXCEPTION
10530 WHEN OKL_API.G_EXCEPTION_ERROR THEN
10531 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10532 p_api_name => l_api_name,
10533 p_pkg_name => G_PKG_NAME,
10534 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
10535 x_msg_count => x_msg_count,
10536 x_msg_data => x_msg_data,
10537 p_api_type => g_api_type);
10538 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
10539 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10540 p_api_name => l_api_name,
10541 p_pkg_name => G_PKG_NAME,
10542 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
10543 x_msg_count => x_msg_count,
10544 x_msg_data => x_msg_data,
10545 p_api_type => g_api_type);
10546 WHEN OTHERS THEN
10547 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10548 p_api_name => l_api_name,
10549 p_pkg_name => G_PKG_NAME,
10550 p_exc_name => 'OTHERS',
10551 x_msg_count => x_msg_count,
10552 x_msg_data => x_msg_data,
10553 p_api_type => g_api_type);
10554 END get_lq_srvc_cash_flows;
10555 --end bkatraga
10556 --------------------------------------------------------------------------------
10557 -- Start of Commnets
10558 -- Procedure Name : Price_Standard_Quote
10559 -- Description :
10560 -- Business Rules :
10561 -- Parameters :
10562 -- Version : 1.0
10563 -- History : ssiruvol 22-May-2005 - created
10564 -- End of Commnets
10565 --------------------------------------------------------------------------------
10566 PROCEDURE get_lq_fee_cash_flows(
10567 p_api_version IN NUMBER,
10568 p_init_msg_list IN VARCHAR2,
10569 x_return_status OUT NOCOPY VARCHAR2,
10570 x_msg_count OUT NOCOPY NUMBER,
10571 x_msg_data OUT NOCOPY VARCHAR2,
10572 p_fee_type IN VARCHAR2,
10573 p_lq_id IN NUMBER,
10574 p_fee_id IN NUMBER,
10575 x_outflow_caf_rec OUT NOCOPY so_cash_flows_rec_type,
10576 x_outflow_cfl_tbl OUT NOCOPY so_cash_flow_details_tbl_type,
10577 x_inflow_caf_rec OUT NOCOPY so_cash_flows_rec_type,
10578 x_inflow_cfl_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
10579 IS
10580 -- Cursor to fetch the Lease Quotes Cash Flow Details
10581 CURSOR lq_cash_flows_csr(
10582 p_id NUMBER,
10583 p_cf_source VARCHAR2,
10584 p_cft_code VARCHAR2)
10585 IS
10586 SELECT cf.id caf_id
10587 ,dnz_khr_id khr_id
10588 ,dnz_qte_id qte_id
10589 ,cfo_id cfo_id
10590 ,sts_code sts_code
10591 ,sty_id sty_id
10592 ,cft_code cft_code
10593 ,due_arrears_yn due_arrears_yn
10594 ,start_date start_date
10595 ,number_of_advance_periods number_of_advance_periods
10596 ,cfo.oty_code oty_code
10597 FROM OKL_CASH_FLOWS cf,
10598 OKL_CASH_FLOW_OBJECTS cfo
10599 WHERE cf.cfo_id = cfo.id
10600 AND cfo.source_table = p_cf_source
10601 AND cfo.source_id = p_id
10602 AND cf .cft_code = p_cft_code ;
10603 -- Cursor to fetch the Cash Flow Details
10604 CURSOR cash_flow_levels_csr( p_caf_id NUMBER )
10605 IS
10606 SELECT id cfl_id
10607 ,caf_id
10608 ,fqy_code
10609 ,rate -- No rate is defined at Cash Flows Level.. Need to confirm
10610 ,stub_days
10611 ,stub_amount
10612 ,number_of_periods
10613 ,amount
10614 ,start_date
10615 FROM OKL_CASH_FLOW_LEVELS
10616 WHERE caf_id = p_caf_id
10617 ORDER BY start_date;
10618
10619 l_api_version CONSTANT NUMBER DEFAULT 1.0;
10620 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lq_fee_cash_flows';
10621 l_return_status VARCHAR2(1);
10622 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
10623 || G_PKG_NAME || '.' || UPPER(l_api_name);
10624
10625 l_debug_enabled VARCHAR2(10);
10626 is_debug_procedure_on BOOLEAN;
10627 is_debug_statement_on BOOLEAN;
10628 cfl_index NUMBER;
10629 BEGIN
10630 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10631 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
10632 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
10633 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10634 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
10635 -- check for logging on STATEMENT level
10636 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
10637 l_return_status := OKL_API.START_ACTIVITY(
10638 p_api_name => l_api_name,
10639 p_pkg_name => G_PKG_NAME,
10640 p_init_msg_list => p_init_msg_list,
10641 l_api_version => l_api_version,
10642 p_api_version => p_api_version,
10643 p_api_type => g_api_type,
10644 x_return_status => x_return_status);
10645 --Check if activity started successfully
10646 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10647 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10648 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10649 RAISE OKL_API.G_EXCEPTION_ERROR;
10650 END IF;
10651 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10652 -- Expense Fees/Miscellaneous Fees will have OUTFLOW_SCHEDULE oty_code cash flows
10653 IF p_fee_type IN ( 'EXPENSE', 'MISCELLANEOUS' )
10654 THEN
10655 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10656 '!!!!! Fetching the Expense Cash flows for fee type ' || p_fee_type );
10657 FOR t_rec IN lq_cash_flows_csr(
10658 p_id => p_fee_id,
10659 p_cf_source => 'OKL_FEES_B',
10660 p_cft_code => 'OUTFLOW_SCHEDULE')
10661 LOOP
10662 x_outflow_caf_rec.caf_id := t_rec.caf_id;
10663 x_outflow_caf_rec.khr_id := t_rec.khr_id;
10664 x_outflow_caf_rec.khr_id := t_rec.khr_id;
10665 x_outflow_caf_rec.qte_id := t_rec.qte_id;
10666 x_outflow_caf_rec.cfo_id := t_rec.cfo_id;
10667 x_outflow_caf_rec.sts_code := t_rec.sts_code;
10668 x_outflow_caf_rec.sty_id := t_rec.sty_id;
10669 x_outflow_caf_rec.cft_code := t_rec.cft_code;
10670 x_outflow_caf_rec.due_arrears_yn := t_rec.due_arrears_yn;
10671 x_outflow_caf_rec.start_date := t_rec.start_date;
10672 x_outflow_caf_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
10673 -- Use l_retun_status as a flag
10674 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10675 END LOOP;
10676 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
10677 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
10678 THEN
10679 cfl_index := 1;
10680 -- Cash Flows exists. So, fetch the Cash Flow Levels
10681 FOR t_rec in cash_flow_levels_csr( x_outflow_caf_rec.caf_id )
10682 LOOP
10683 x_outflow_cfl_tbl(cfl_index).cfl_id := t_rec.cfl_id;
10684 x_outflow_cfl_tbl(cfl_index).caf_id := t_rec.caf_id;
10685 x_outflow_cfl_tbl(cfl_index).fqy_code := t_rec.fqy_code;
10686 x_outflow_cfl_tbl(cfl_index).rate := t_rec.rate;
10687 x_outflow_cfl_tbl(cfl_index).stub_days := t_rec.stub_days;
10688 x_outflow_cfl_tbl(cfl_index).stub_amount := t_rec.stub_amount;
10689 x_outflow_cfl_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
10690 x_outflow_cfl_tbl(cfl_index).amount := t_rec.amount;
10691 x_outflow_cfl_tbl(cfl_index).start_date := t_rec.start_date;
10692 x_outflow_cfl_tbl(cfl_index).locked_amt := 'Y';
10693 -- Remember the flag whether its a stub payment or not
10694 IF t_rec.stub_days IS NOT NULL and t_rec.stub_amount IS NOT NULL
10695 THEN
10696 -- Stub Payment
10697 x_outflow_cfl_tbl(cfl_index).is_stub := 'Y';
10698 ELSE
10699 -- Regular Periodic Payment
10700 x_outflow_cfl_tbl(cfl_index).is_stub := 'N';
10701 END IF;
10702 -- Use l_retun_status as a flag
10703 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10704 -- Increment i
10705 cfl_index := cfl_index + 1;
10706 END LOOP;
10707 ELSE
10708 -- Show an error saying that no cash flow levels found
10709 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10710 '!!!!! No Cash flow levels obtained for the fee type ' || p_fee_type );
10711 OKL_API.SET_MESSAGE (
10712 p_app_name => G_APP_NAME,
10713 p_msg_name => 'OKL_AM_NO_PYMT_INFO');
10714 RAISE OKL_API.G_EXCEPTION_ERROR;
10715 END IF;
10716 END IF; -- If p_fee_type = 'EXPENSE'/'MISCELLANEOUS'
10717 -- Income Fees/Security Deposit will have PAYMENT_SCHEDULE cash flows
10718 -- Miscellaneous Fees may have an inflow PAYMENT_SCHEDULE ( Not Mandatory for Payment )
10719 IF p_fee_type IN ( 'INCOME', 'SECDEPOSIT', 'MISCELLANEOUS' )
10720 THEN
10721 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10722 '!!!!! Fetching the Income Cash flows for fee type ' || p_fee_type );
10723 l_return_status := OKL_API.G_RET_STS_ERROR;
10724 FOR t_rec IN lq_cash_flows_csr(
10725 p_id => p_fee_id,
10726 p_cf_source => 'OKL_FEES_B',
10727 p_cft_code => 'PAYMENT_SCHEDULE')
10728 LOOP
10729 x_inflow_caf_rec.caf_id := t_rec.caf_id;
10730 x_inflow_caf_rec.khr_id := t_rec.khr_id;
10731 x_inflow_caf_rec.khr_id := t_rec.khr_id;
10732 x_inflow_caf_rec.qte_id := t_rec.qte_id;
10733 x_inflow_caf_rec.cfo_id := t_rec.cfo_id;
10734 x_inflow_caf_rec.sts_code := t_rec.sts_code;
10735 x_inflow_caf_rec.sty_id := t_rec.sty_id;
10736 x_inflow_caf_rec.cft_code := t_rec.cft_code;
10737 x_inflow_caf_rec.due_arrears_yn := t_rec.due_arrears_yn;
10738 x_inflow_caf_rec.start_date := t_rec.start_date;
10739 x_inflow_caf_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
10740 -- Use l_retun_status as a flag
10741 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10742 END LOOP;
10743 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
10744 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
10745 THEN
10746 cfl_index := 1;
10747 -- Cash Flows exists. So, fetch the Cash Flow Levels
10748 FOR t_rec in cash_flow_levels_csr( x_inflow_caf_rec.caf_id )
10749 LOOP
10750 x_inflow_cfl_tbl(cfl_index).cfl_id := t_rec.cfl_id;
10751 x_inflow_cfl_tbl(cfl_index).caf_id := t_rec.caf_id;
10752 x_inflow_cfl_tbl(cfl_index).fqy_code := t_rec.fqy_code;
10753 x_inflow_cfl_tbl(cfl_index).rate := t_rec.rate;
10754 x_inflow_cfl_tbl(cfl_index).stub_days := t_rec.stub_days;
10755 x_inflow_cfl_tbl(cfl_index).stub_amount := t_rec.stub_amount;
10756 x_inflow_cfl_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
10757 x_inflow_cfl_tbl(cfl_index).amount := t_rec.amount;
10758 x_inflow_cfl_tbl(cfl_index).start_date := t_rec.start_date;
10759 x_inflow_cfl_tbl(cfl_index).locked_amt := 'Y';
10760 -- Remember the flag whether its a stub payment or not
10761 IF t_rec.stub_days IS NOT NULL and t_rec.stub_amount IS NOT NULL
10762 THEN
10763 -- Stub Payment
10764 x_inflow_cfl_tbl(cfl_index).is_stub := 'Y';
10765 ELSE
10766 -- Regular Periodic Payment
10767 x_inflow_cfl_tbl(cfl_index).is_stub := 'N';
10768 END IF;
10769 -- Use l_retun_status as a flag
10770 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10771 -- Increment i
10772 cfl_index := cfl_index + 1;
10773 END LOOP;
10774 ELSE
10775 -- Show an error saying that no cash flow levels found
10776 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10777 '!!!!! No Cash flow levels obtained for the fee type ' || p_fee_type );
10778 IF p_fee_type <> 'MISCELLANEOUS'
10779 THEN
10780 OKL_API.SET_MESSAGE (
10781 p_app_name => G_APP_NAME,
10782 p_msg_name => 'OKL_LLA_PMT_SELECT');
10783 RAISE OKL_API.G_EXCEPTION_ERROR;
10784 END IF;
10785 END IF;
10786 END IF; -- If p_fee_type = 'INCOME'/'SECDEPOSIT'/'MISCELLANEOUS'
10787 -- Setting up the return variables
10788 x_return_status := l_return_status;
10789 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
10790 x_msg_data => x_msg_data);
10791 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10792 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
10793 EXCEPTION
10794 WHEN OKL_API.G_EXCEPTION_ERROR THEN
10795 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10796 p_api_name => l_api_name,
10797 p_pkg_name => G_PKG_NAME,
10798 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
10799 x_msg_count => x_msg_count,
10800 x_msg_data => x_msg_data,
10801 p_api_type => g_api_type);
10802 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
10803 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10804 p_api_name => l_api_name,
10805 p_pkg_name => G_PKG_NAME,
10806 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
10807 x_msg_count => x_msg_count,
10808 x_msg_data => x_msg_data,
10809 p_api_type => g_api_type);
10810 WHEN OTHERS THEN
10811 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10812 p_api_name => l_api_name,
10813 p_pkg_name => G_PKG_NAME,
10814 p_exc_name => 'OTHERS',
10815 x_msg_count => x_msg_count,
10816 x_msg_data => x_msg_data,
10817 p_api_type => g_api_type);
10818 END get_lq_fee_cash_flows;
10819 --------------------------------------------------------------------------------
10820 -- Start of Commnets
10821 -- Procedure Name : solve_pmnts_at_lq
10822 -- Description :
10823 -- Business Rules :
10824 -- Parameters :
10825 -- Version : 1.0
10826 -- History : rgooty 6-Mar-20006 Created.
10827 -- End of Commnets
10828 --------------------------------------------------------------------------------
10829 PROCEDURE solve_pmnts_at_lq(
10830 p_api_version IN NUMBER,
10831 p_init_msg_list IN VARCHAR2,
10832 x_return_status OUT NOCOPY VARCHAR2,
10833 x_msg_count OUT NOCOPY NUMBER,
10834 x_msg_data OUT NOCOPY VARCHAR2,
10835 p_id IN NUMBER,
10836 x_caf_rec OUT NOCOPY OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type,
10837 x_cfl_tbl OUT NOCOPY OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type,
10838 x_solved OUT NOCOPY VARCHAR2)
10839 IS
10840 -- Cursor to fetch all the Assets in a Lease Quote
10841 CURSOR all_assets_csr( p_qte_id IN okl_lease_quotes_b.id%TYPE)
10842 IS
10843 SELECT ast.id ast_id,
10844 ast.asset_number ast_number
10845 FROM okl_assets_b ast,
10846 okl_lease_quotes_b qte
10847 WHERE ast.parent_object_code = 'LEASEQUOTE'
10848 AND ast.parent_object_id = qte.id
10849 AND qte.id = p_qte_id;
10850 all_assets_rec all_assets_csr%ROWTYPE;
10851 -- Cursor to fetch the payment structure defined/derieved of an asset
10852 CURSOR ast_payments_csr( p_ast_id OKL_ASSETS_B.ID%TYPE,
10853 p_qte_id OKL_LEASE_QUOTES_B.ID%TYPE)
10854 IS
10855 SELECT cfl.fqy_code frequency,
10856 caf.due_arrears_yn adv_arrears,
10857 caf.sty_id sty_id,
10858 cfl.start_date,
10859 cfl.rate,
10860 cfl.stub_days,
10861 cfl.stub_amount,
10862 cfl.number_of_periods periods,
10863 cfl.amount periodic_amount
10864 FROM okl_assets_b ast,
10865 okl_cash_flow_objects cfo,
10866 okl_cash_flows caf,
10867 okl_cash_flow_levels cfl,
10868 okl_strm_type_b sty
10869 WHERE ast.id = p_ast_id
10870 AND ast.parent_object_id = p_qte_id
10871 AND cfo.source_id = ast.id
10872 AND caf.cfo_id = cfo.id
10873 AND cfl.caf_id = caf.id
10874 AND cfo.source_table = 'OKL_ASSETS_B'
10875 AND cfo.oty_code = 'QUOTED_ASSET'
10876 AND caf.sts_code IN ( 'CURRENT', 'WORK')
10877 AND caf.sty_id = sty.id
10878 AND sty.stream_type_purpose = 'RENT'
10879 ORDER BY cfl.start_date;
10880 ast_payments_rec ast_payments_csr%ROWTYPE;
10881 -- Local Variables Declaration
10882 l_api_version CONSTANT NUMBER DEFAULT 1.0;
10883 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'solve_pmnts_at_lq';
10884 l_return_status VARCHAR2(1);
10885 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
10886 || G_PKG_NAME || '.' || UPPER(l_api_name);
10887
10888 l_debug_enabled VARCHAR2(10);
10889 is_debug_procedure_on BOOLEAN;
10890 is_debug_statement_on BOOLEAN;
10891 i NUMBER;
10892 l_first BOOLEAN;
10893 l_caf_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
10894 l_cfl_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
10895 l_solved VARCHAR2(30);
10896 BEGIN
10897 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10898 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
10899 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
10900 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10901 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
10902 -- check for logging on STATEMENT level
10903 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
10904 l_return_status := OKL_API.START_ACTIVITY(
10905 p_api_name => l_api_name,
10906 p_pkg_name => G_PKG_NAME,
10907 p_init_msg_list => p_init_msg_list,
10908 l_api_version => l_api_version,
10909 p_api_version => p_api_version,
10910 p_api_type => g_api_type,
10911 x_return_status => x_return_status);
10912 --Check if activity started successfully
10913 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10914 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10915 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10916 RAISE OKL_API.G_EXCEPTION_ERROR;
10917 END IF;
10918 -- Actual logic starts here
10919 l_first := TRUE;
10920 l_solved := 'YES';
10921 FOR ast_rec IN all_assets_csr( p_qte_id => p_id)
10922 LOOP
10923 i := 1;
10924 IF l_first
10925 THEN
10926 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10927 ' FIRST ONE : Frequency | Adv/Arrears | Rate | Days | Amount | Periods | Periodic Amount ' );
10928 FOR cfl_rec IN ast_payments_csr( p_ast_id => ast_rec.ast_id,
10929 p_qte_id => p_id)
10930 LOOP
10931 -- Store them in the Cash flows and Cash Flow Levels
10932 l_caf_rec.frequency_code := cfl_rec.frequency;
10933 l_caf_rec.arrears_flag := cfl_rec.adv_arrears;
10934 l_caf_rec.stream_type_id := cfl_rec.sty_id;
10935 l_cfl_tbl(i).record_mode := 'CREATE';
10936 l_cfl_tbl(i).start_date := cfl_rec.start_date;
10937 l_cfl_tbl(i).rate := cfl_rec.rate;
10938 l_cfl_tbl(i).stub_days := cfl_rec.stub_days;
10939 l_cfl_tbl(i).stub_amount := cfl_rec.stub_amount;
10940 l_cfl_tbl(i).periods := cfl_rec.periods;
10941 l_cfl_tbl(i).periodic_amount := cfl_rec.periodic_amount;
10942 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10943 cfl_rec.frequency || ' | ' || cfl_rec.adv_arrears || ' | ' || cfl_rec.rate || ' | ' ||
10944 cfl_rec.stub_days || ' | ' || cfl_rec.stub_amount || ' | ' ||
10945 cfl_rec.periods || ' | ' || cfl_rec.periodic_amount );
10946 i := i + 1;
10947 l_first := FALSE;
10948 END LOOP;
10949 ELSE
10950 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10951 ' Frequency | Adv/Arrears | Rate | Days | Amount | Periods | Periodic Amount ' );
10952 FOR cfl_rec IN ast_payments_csr( p_ast_id => ast_rec.ast_id,
10953 p_qte_id => p_id)
10954 LOOP
10955 -- Compare with the previous cash flow levels
10956 IF l_cfl_tbl.EXISTS(i) AND (
10957 l_caf_rec.frequency_code = cfl_rec.frequency AND
10958 nvl(l_caf_rec.arrears_flag,'N') = nvl(cfl_rec.adv_arrears, 'N') AND
10959 l_cfl_tbl(i).start_date = cfl_rec.start_date AND
10960 nvl(l_cfl_tbl(i).stub_days,-1) = nvl(cfl_rec.stub_days, -1) AND
10961 nvl(l_cfl_tbl(i).periods, -1) = nvl(cfl_rec.periods, -1) )
10962 THEN
10963 l_cfl_tbl(i).stub_amount := l_cfl_tbl(i).stub_amount + cfl_rec.stub_amount;
10964 l_cfl_tbl(i).periodic_amount := l_cfl_tbl(i).periodic_amount + cfl_rec.periodic_amount;
10965 ELSE
10966 l_solved := 'NO';
10967 EXIT;
10968 END IF;
10969 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10970 cfl_rec.frequency || ' | ' || cfl_rec.adv_arrears || ' | ' || cfl_rec.rate || ' | ' ||
10971 l_cfl_tbl(i).stub_days || ' | ' || cfl_rec.stub_amount || ' | ' ||
10972 cfl_rec.periods || ' | ' || cfl_rec.periodic_amount );
10973 i := i + 1;
10974 END LOOP; -- Loop on the ast_payments_csr
10975 END IF; -- IF l_first
10976 EXIT WHEN l_solved = 'NO';
10977 END LOOP; -- Loop on the Assets
10978 x_caf_rec := l_caf_rec;
10979 x_cfl_tbl := l_cfl_tbl;
10980 x_solved := l_solved;
10981 x_return_status := l_return_status;
10982 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
10983 x_msg_data => x_msg_data);
10984 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10985 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
10986 EXCEPTION
10987 WHEN OKL_API.G_EXCEPTION_ERROR THEN
10988 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10989 p_api_name => l_api_name,
10990 p_pkg_name => G_PKG_NAME,
10991 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
10992 x_msg_count => x_msg_count,
10993 x_msg_data => x_msg_data,
10994 p_api_type => g_api_type);
10995 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
10996 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10997 p_api_name => l_api_name,
10998 p_pkg_name => G_PKG_NAME,
10999 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
11000 x_msg_count => x_msg_count,
11001 x_msg_data => x_msg_data,
11002 p_api_type => g_api_type);
11003 WHEN OTHERS THEN
11004 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
11005 p_api_name => l_api_name,
11006 p_pkg_name => G_PKG_NAME,
11007 p_exc_name => 'OTHERS',
11008 x_msg_count => x_msg_count,
11009 x_msg_data => x_msg_data,
11010 p_api_type => g_api_type);
11011 END solve_pmnts_at_lq;
11012
11013 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
11014 --------------------------------------------------------------------------------
11015 -- Start of Commnets
11016 -- Procedure Name : delete_quote_streams
11017 -- Description :
11018 -- Business Rules :
11019 -- Parameters :
11020 -- Version : 1.0
11021 -- History : RGOOTY 27-May-2009 - created
11022 -- End of Commnets
11023 --------------------------------------------------------------------------------
11024 PROCEDURE delete_quote_streams(
11025 p_api_version IN NUMBER,
11026 p_init_msg_list IN VARCHAR2,
11027 x_return_status OUT NOCOPY VARCHAR2,
11028 x_msg_count OUT NOCOPY NUMBER,
11029 x_msg_data OUT NOCOPY VARCHAR2,
11030 p_quote_id IN NUMBER
11031 ) IS
11032
11033 l_return_status VARCHAR2(1):= G_RET_STS_SUCCESS;
11034 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'delete_quote_streams';
11035 l_api_version CONSTANT NUMBER DEFAULT 1.0;
11036 l_strm_elements_tbl OKL_QSL_PVT.qsl_tbl_type;
11037 l_streams_tbl OKL_QSH_PVT.qsh_tbl_type;
11038 p_index NUMBER;
11039
11040 CURSOR get_strm_elements_csr IS
11041 SELECT QTE_SEL.QUOTE_STRM_ELEMENT_ID
11042 FROM OKL_QUOTE_STREAMS QTE_STM,
11043 OKL_QUOTE_STRM_ELEMENTS QTE_SEL
11044 WHERE QTE_STM.QUOTE_STREAM_ID = QTE_SEL.QUOTE_STREAM_ID
11045 AND QTE_STM.QUOTE_ID = p_quote_id;
11046
11047 CURSOR get_streams_csr IS
11048 SELECT QTE_STM.QUOTE_STREAM_ID
11049 FROM OKL_QUOTE_STREAMS QTE_STM
11050 WHERE QTE_STM.QUOTE_ID = p_quote_id;
11051
11052 BEGIN
11053
11054 l_return_status := OKL_API.START_ACTIVITY(
11055 p_api_name => l_api_name,
11056 p_pkg_name => G_PKG_NAME,
11057 p_init_msg_list => p_init_msg_list,
11058 l_api_version => l_api_version,
11059 p_api_version => p_api_version,
11060 p_api_type => g_api_type,
11061 x_return_status => l_return_status);
11062 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11063 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11064 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11065 RAISE OKL_API.G_EXCEPTION_ERROR;
11066 END IF;
11067
11068 p_index := 1;
11069 FOR strm_element_rec IN get_strm_elements_csr
11070 LOOP
11071 l_strm_elements_tbl(p_index).quote_strm_element_id := strm_element_rec.QUOTE_STRM_ELEMENT_ID;
11072 p_index := p_index + 1;
11073 END LOOP;
11074 IF(l_strm_elements_tbl.COUNT > 0) THEN
11075 OKL_QSL_PVT.delete_row(p_api_version => p_api_version,
11076 p_init_msg_list => p_init_msg_list,
11077 x_return_status => l_return_status,
11078 x_msg_count => x_msg_count,
11079 x_msg_data => x_msg_data,
11080 p_qsl_tbl => l_strm_elements_tbl
11081 );
11082 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11083 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11084 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11085 RAISE OKL_API.G_EXCEPTION_ERROR;
11086 END IF;
11087 END IF;
11088
11089 p_index := 1;
11090 FOR strm_rec IN get_streams_csr
11091 LOOP
11092 l_streams_tbl(p_index).quote_stream_id := strm_rec.QUOTE_STREAM_ID;
11093 p_index := p_index + 1;
11094 END LOOP;
11095 IF(l_streams_tbl.COUNT > 0) THEN
11096 OKL_QSH_PVT.delete_row(p_api_version => p_api_version,
11097 p_init_msg_list => p_init_msg_list,
11098 x_return_status => l_return_status,
11099 x_msg_count => x_msg_count,
11100 x_msg_data => x_msg_data,
11101 p_qsh_tbl => l_streams_tbl
11102 );
11103 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11104 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11105 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11106 RAISE OKL_API.G_EXCEPTION_ERROR;
11107 END IF;
11108 END IF;
11109
11110 x_return_status := l_return_status;
11111 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
11112 x_msg_data => x_msg_data);
11113 EXCEPTION
11114 WHEN OKL_API.G_EXCEPTION_ERROR THEN
11115 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
11116 p_api_name => l_api_name,
11117 p_pkg_name => G_PKG_NAME,
11118 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
11119 x_msg_count => x_msg_count,
11120 x_msg_data => x_msg_data,
11121 p_api_type => g_api_type);
11122 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
11123 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
11124 p_api_name => l_api_name,
11125 p_pkg_name => G_PKG_NAME,
11126 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
11127 x_msg_count => x_msg_count,
11128 x_msg_data => x_msg_data,
11129 p_api_type => g_api_type);
11130 WHEN OTHERS THEN
11131 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
11132 p_api_name => l_api_name,
11133 p_pkg_name => G_PKG_NAME,
11134 p_exc_name => 'OTHERS',
11135 x_msg_count => x_msg_count,
11136 x_msg_data => x_msg_data,
11137 p_api_type => g_api_type);
11138 END delete_quote_streams;
11139 --------------------------------------------------------------------------------
11140 -- Start of Commnets
11141 -- Procedure Name : insert_quote_streams
11142 -- Description :
11143 -- Business Rules :
11144 -- Parameters :
11145 -- Version : 1.0
11146 -- History : RGOOTY 27-May-2009 - created
11147 -- End of Commnets
11148 --------------------------------------------------------------------------------
11149 PROCEDURE insert_quote_streams(
11150 p_api_version IN NUMBER,
11151 p_init_msg_list IN VARCHAR2,
11152 x_return_status OUT NOCOPY VARCHAR2,
11153 x_msg_count OUT NOCOPY NUMBER,
11154 x_msg_data OUT NOCOPY VARCHAR2,
11155 p_quote_id IN NUMBER,
11156 p_quote_type IN VARCHAR2,
11157 p_currency IN VARCHAR2,
11158 p_pricing_param_tbl IN OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type
11159 ) IS
11160
11161 l_return_status VARCHAR2(1):= G_RET_STS_SUCCESS;
11162 l_sty_id OKL_STRM_TYPE_B.ID%TYPE;
11163 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'insert_quote_streams';
11164 l_pricing_param_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
11165 l_stm_id NUMBER;
11166 l_sel_id NUMBER;
11167 l_residual_sty_id OKL_STRM_TYPE_B.ID%TYPE;
11168 l_residual_count NUMBER;
11169 l_residual_amt NUMBER;
11170 l_api_version CONSTANT NUMBER DEFAULT 1.0;
11171 l_sel_amount NUMBER;
11172 l_stream_rec OKL_QSH_PVT.qsh_rec_type;
11173 x_stream_rec OKL_QSH_PVT.qsh_rec_type;
11174 l_stm_element_rec OKL_QSL_PVT.qsl_rec_type;
11175 x_stm_element_rec OKL_QSL_PVT.qsl_rec_type;
11176 l_stm_element_tbl OKL_QSL_PVT.qsl_tbl_type;
11177 x_stm_element_tbl OKL_QSL_PVT.qsl_tbl_type;
11178 p_index NUMBER;
11179 l_product_type VARCHAR2(30);
11180
11181 CURSOR get_quote_details_csr IS
11182 SELECT LSE_QT.PRODUCT_ID,
11183 LSE_QT.EXPECTED_START_DATE,
11184 PDT.DEAL_TYPE
11185 FROM OKL_LEASE_QUOTES_B LSE_QT,
11186 OKL_PRODUCT_PARAMETERS_V PDT
11187 WHERE LSE_QT.PRODUCT_ID = PDT.ID
11188 AND LSE_QT.ID = p_quote_id;
11189
11190 quote_det_rec get_quote_details_csr%ROWTYPE;
11191
11192 CURSOR header_info_csr(p_cfo_id OKL_CASH_FLOW_OBJECTS.ID%TYPE) IS
11193 SELECT OTY_CODE,
11194 SOURCE_TABLE,
11195 SOURCE_ID,
11196 STY_ID,
11197 CFT_CODE
11198 FROM OKL_CASH_FLOW_OBJECTS CFLOW_OBJ,
11199 OKL_CASH_FLOWS CFLOW
11200 WHERE CFLOW.CFO_ID = CFLOW_OBJ.ID
11201 AND CFLOW_OBJ.ID = p_cfo_id;
11202
11203 header_info_rec header_info_csr%ROWTYPE;
11204
11205 CURSOR residual_sty_csr (l_product_id NUMBER, l_start_date DATE) IS
11206 SELECT PRIMARY_STY_ID
11207 FROM OKL_STRM_TMPT_LINES_UV STL
11208 WHERE STL.PRIMARY_YN = 'Y'
11209 AND STL.PDT_ID = l_product_id
11210 AND (STL.START_DATE <= l_start_date)
11211 AND (STL.END_DATE >= l_start_date OR STL.END_DATE IS NULL)
11212 AND PRIMARY_STY_PURPOSE = 'RESIDUAL_VALUE';
11213 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
11214 || G_PKG_NAME || '.' || UPPER(l_api_name);
11215 l_debug_enabled VARCHAR2(10);
11216 is_debug_procedure_on BOOLEAN;
11217 is_debug_statement_on BOOLEAN;
11218 BEGIN
11219 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
11220 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
11221 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
11222 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
11223 -- check for logging on STATEMENT level
11224 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
11225 l_return_status := OKL_API.START_ACTIVITY(
11226 p_api_name => l_api_name,
11227 p_pkg_name => G_PKG_NAME,
11228 p_init_msg_list => p_init_msg_list,
11229 l_api_version => l_api_version,
11230 p_api_version => p_api_version,
11231 p_api_type => g_api_type,
11232 x_return_status => l_return_status);
11233 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11234 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11235 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11236 RAISE OKL_API.G_EXCEPTION_ERROR;
11237 END IF;
11238 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
11239 'Executing the API ' || l_api_name );
11240 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11241 'P_QUOTE_ID=' || P_QUOTE_ID || ' P_QUOTE_TYPE=' || p_quote_type || ' p_currency=' || p_currency );
11242 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11243 'Before Executing the Cursor get_quote_details_csr');
11244 OPEN get_quote_details_csr;
11245 FETCH get_quote_details_csr INTO quote_det_rec;
11246 IF (get_quote_details_csr%NOTFOUND) THEN
11247 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11248 END IF;
11249 CLOSE get_quote_details_csr;
11250
11251 l_product_type := quote_det_rec.DEAL_TYPE;
11252 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11253 'Sucessfully executed the Cursor get_quote_details_csr. l_product_type=' || l_product_type);
11254
11255 l_pricing_param_tbl := p_pricing_param_tbl;
11256 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11257 'l_pricing_param_tbl.COUNT=' || l_pricing_param_tbl.COUNT );
11258 IF l_pricing_param_tbl.COUNT > 0 THEN
11259 FOR k IN l_pricing_param_tbl.FIRST .. l_pricing_param_tbl.LAST
11260 LOOP
11261 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11262 'Index = ' || k || ' l_pricing_param_tbl(k).line_type= ' || l_pricing_param_tbl(k).line_type );
11263 IF(l_pricing_param_tbl(k).line_type IS NOT NULL)
11264 THEN
11265 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11266 'Before Executing the Cursor header_info_csr. l_pricing_param_tbl(k).cfo_id= ' || l_pricing_param_tbl(k).cfo_id );
11267 OPEN header_info_csr(l_pricing_param_tbl(k).cfo_id);
11268 FETCH header_info_csr INTO header_info_rec;
11269 IF (header_info_csr%NOTFOUND) THEN
11270 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11271 END IF;
11272 CLOSE header_info_csr;
11273 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11274 'After Executing the Cursor header_info_csr. header_info_rec.CFT_CODE= ' || header_info_rec.CFT_CODE );
11275 IF(header_info_rec.CFT_CODE <> 'OUTFLOW_SCHEDULE')
11276 THEN
11277 l_stream_rec.object_version_number := 1;
11278 l_stream_rec.quote_type := p_quote_type;
11279 l_stream_rec.quote_id := p_quote_id;
11280 l_stream_rec.oty_code := header_info_rec.OTY_CODE;
11281 l_stream_rec.source_id := header_info_rec.SOURCE_ID;
11282 l_stream_rec.source_table := header_info_rec.SOURCE_TABLE;
11283 l_stream_rec.sty_id := header_info_rec.STY_ID;
11284 l_stream_rec.link_asset_id := l_pricing_param_tbl(k).link_asset_id; --Added by bkatraga for bug 7410991
11285
11286 l_stream_rec.say_code := 'CURR';
11287 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11288 'Before Calling the API OKL_QSH_PVT.insert_row ' );
11289 --Inserting the stream header
11290 OKL_QSH_PVT.insert_row(p_api_version => p_api_version,
11291 p_init_msg_list => p_init_msg_list,
11292 x_return_status => l_return_status,
11293 x_msg_count => x_msg_count,
11294 x_msg_data => x_msg_data,
11295 p_qsh_rec => l_stream_rec,
11296 x_qsh_rec => x_stream_rec
11297 );
11298 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11299 'After Calling the API OKL_QSH_PVT.insert_row ' || l_return_status );
11300 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11301 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11302 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11303 RAISE OKL_API.G_EXCEPTION_ERROR;
11304 END IF;
11305
11306 p_index := 1;
11307 l_stm_element_tbl.delete;
11308 IF(l_pricing_param_tbl(k).cash_inflows.COUNT > 0)
11309 THEN
11310 FOR m IN l_pricing_param_tbl(k).cash_inflows.FIRST .. l_pricing_param_tbl(k).cash_inflows.LAST
11311 LOOP
11312 l_sel_amount := okl_accounting_util.round_amount(p_amount => l_pricing_param_tbl(k).cash_inflows(m).cf_amount,
11313 p_currency_code => p_currency);
11314 l_stm_element_tbl(p_index).quote_stream_id := x_stream_rec.quote_stream_id;
11315 l_stm_element_tbl(p_index).object_version_number := 1;
11316 l_stm_element_tbl(p_index).stream_element_date := l_pricing_param_tbl(k).cash_inflows(m).cf_date;
11317 l_stm_element_tbl(p_index).amount := l_sel_amount;
11318 p_index := p_index + 1;
11319 END LOOP;
11320 END IF;
11321 --Inserting the stream elements
11322 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11323 'Before Calling the API OKL_QSL_PVT.insertv_tbl ' );
11324 OKL_QSL_PVT.insert_row(p_api_version => p_api_version,
11325 p_init_msg_list => p_init_msg_list,
11326 x_return_status => l_return_status,
11327 x_msg_count => x_msg_count,
11328 x_msg_data => x_msg_data,
11329 p_qsl_tbl => l_stm_element_tbl,
11330 x_qsl_tbl => x_stm_element_tbl
11331 );
11332 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11333 'After Calling the API OKL_QSL_PVT.insertv_tbl x_return_status=' || l_return_status );
11334 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11335 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11336 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11337 RAISE OKL_API.G_EXCEPTION_ERROR;
11338 END IF;
11339
11340 --Residual streams
11341 IF((l_pricing_param_tbl(k).residual_inflows.COUNT > 0) AND
11342 (l_product_type IN('LEASEDF','LEASEOP','LEASEST')))
11343 THEN
11344 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11345 'Before executing the cursor residual_sty_csr ' );
11346 OPEN residual_sty_csr(quote_det_rec.product_id, quote_det_rec.EXPECTED_START_DATE);
11347 FETCH residual_sty_csr INTO l_residual_sty_id;
11348 IF (residual_sty_csr%NOTFOUND) THEN
11349 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11350 END IF;
11351 CLOSE residual_sty_csr;
11352 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11353 'After executing the cursor residual_sty_csr ' );
11354 l_stream_rec.object_version_number := 1;
11355 l_stream_rec.quote_type := p_quote_type;
11356 l_stream_rec.quote_id := p_quote_id;
11357 l_stream_rec.oty_code := header_info_rec.OTY_CODE;
11358 l_stream_rec.source_id := header_info_rec.SOURCE_ID;
11359 l_stream_rec.source_table := header_info_rec.SOURCE_TABLE;
11360 l_stream_rec.sty_id := l_residual_sty_id;
11361 l_stream_rec.say_code := 'CURR';
11362 --Inserting the residual stream header
11363 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11364 'Before executing the API OKL_QSH_PVT.insert_row ' );
11365 OKL_QSH_PVT.insert_row(p_api_version => p_api_version,
11366 p_init_msg_list => p_init_msg_list,
11367 x_return_status => l_return_status,
11368 x_msg_count => x_msg_count,
11369 x_msg_data => x_msg_data,
11370 p_qsh_rec => l_stream_rec,
11371 x_qsh_rec => x_stream_rec
11372 );
11373 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11374 'After executing the API OKL_QSH_PVT.insert_row. x_return_status=' || l_return_status );
11375 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11376 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11377 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11378 RAISE OKL_API.G_EXCEPTION_ERROR;
11379 END IF;
11380
11381 l_residual_count := l_pricing_param_tbl(k).residual_inflows.COUNT;
11382 l_residual_amt := 0;
11383 FOR m IN l_pricing_param_tbl(k).residual_inflows.FIRST .. l_pricing_param_tbl(k).residual_inflows.LAST
11384 LOOP
11385 IF((header_info_rec.OTY_CODE = 'LEASE_QUOTE') AND (m <> l_residual_count)) THEN
11386 l_residual_amt := l_residual_amt + l_pricing_param_tbl(k).residual_inflows(m).cf_amount;
11387 ELSE
11388 l_sel_amount := l_pricing_param_tbl(k).residual_inflows(m).cf_amount + l_residual_amt;
11389 l_sel_amount := okl_accounting_util.round_amount(p_amount => l_sel_amount,
11390 p_currency_code => p_currency);
11391
11392 l_stm_element_rec.quote_stream_id := x_stream_rec.quote_stream_id;
11393 l_stm_element_rec.object_version_number := 1;
11394 l_stm_element_rec.stream_element_date := l_pricing_param_tbl(k).residual_inflows(m).cf_date;
11395 l_stm_element_rec.amount := l_sel_amount;
11396 --Inserting the stream element
11397 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11398 'Before executing the API OKL_QSL_PVT.insert_row. ' );
11399 OKL_QSL_PVT.insert_row(p_api_version => p_api_version,
11400 p_init_msg_list => p_init_msg_list,
11401 x_return_status => l_return_status,
11402 x_msg_count => x_msg_count,
11403 x_msg_data => x_msg_data,
11404 p_qsl_rec => l_stm_element_rec,
11405 x_qsl_rec => x_stm_element_rec
11406 );
11407 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11408 'After executing the API OKL_QSL_PVT.insert_row. x_return_status=' || l_return_status );
11409 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11410 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11411 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11412 RAISE OKL_API.G_EXCEPTION_ERROR;
11413 END IF;
11414 END IF;
11415 END LOOP; -- residual_inflows loop
11416 END IF; --Residual streams IF
11417 END IF; --OUTFLOW_SCHEDULE IF
11418 END IF; --line type IF
11419 END LOOP;
11420 END IF;
11421 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
11422 'Returning from the API ' || l_api_name || ' with x_return_status = ' || l_return_status );
11423 x_return_status := l_return_status;
11424 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
11425 x_msg_data => x_msg_data);
11426 EXCEPTION
11427 WHEN OKL_API.G_EXCEPTION_ERROR THEN
11428 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
11429 p_api_name => l_api_name,
11430 p_pkg_name => G_PKG_NAME,
11431 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
11432 x_msg_count => x_msg_count,
11433 x_msg_data => x_msg_data,
11434 p_api_type => g_api_type);
11435 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
11436 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
11437 p_api_name => l_api_name,
11438 p_pkg_name => G_PKG_NAME,
11439 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
11440 x_msg_count => x_msg_count,
11441 x_msg_data => x_msg_data,
11442 p_api_type => g_api_type);
11443 WHEN OTHERS THEN
11444 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
11445 p_api_name => l_api_name,
11446 p_pkg_name => G_PKG_NAME,
11447 p_exc_name => 'OTHERS',
11448 x_msg_count => x_msg_count,
11449 x_msg_data => x_msg_data,
11450 p_api_type => g_api_type);
11451 END insert_quote_streams;
11452 -- Bug 7440199: Quote Streams ER: RGOOTY: End
11453 --------------------------------------------------------------------------------
11454 -- Start of Commnets
11455 -- Procedure Name : Price_Standard_Quote
11456 -- Description :
11457 -- Business Rules :
11458 -- Parameters :
11459 -- Version : 1.0
11460 -- History : ssiruvol 22-May-2005 - created
11461 -- End of Commnets
11462 --------------------------------------------------------------------------------
11463 PROCEDURE price_standard_quote(x_return_status OUT NOCOPY VARCHAR2,
11464 x_msg_count OUT NOCOPY NUMBER,
11465 x_msg_data OUT NOCOPY VARCHAR2,
11466 p_api_version IN NUMBER,
11467 p_init_msg_list IN VARCHAR2,
11468 p_qte_id IN NUMBER)
11469 IS
11470 l_api_version CONSTANT NUMBER DEFAULT 1.0;
11471 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'price_standard_quote';
11472 l_return_status VARCHAR2(1);
11473 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
11474 || G_PKG_NAME || '.' || UPPER(l_api_name);
11475
11476 l_debug_enabled VARCHAR2(10);
11477 is_debug_procedure_on BOOLEAN;
11478 is_debug_statement_on BOOLEAN;
11479 -- Cursors declaration !
11480 -- Cursor to fetch the Lease Quote Header details
11481 CURSOR quote_csr(qteid NUMBER)
11482 IS
11483 SELECT qte.term term,
11484 qte.pricing_method,
11485 qte.rate_template_id,
11486 qte.expected_start_date,
11487 qte.expected_delivery_date,
11488 qte.structured_pricing structured_pricing,
11489 qte.line_level_pricing line_level_pricing,
11490 qte.target_rate_type target_rate_type,
11491 qte.target_frequency target_frequency,
11492 qte.target_arrears_yn target_arrears,
11493 qte.target_rate target_rate,
11494 qte.target_periods target_periods,
11495 qte.lease_rate_factor,
11496 qte.rate_card_id,
11497 qte.id,
11498 qte.parent_object_code,
11499 qte.parent_object_id,
11500 qte.object_version_number,
11501 qte.reference_number,
11502 qte.product_id
11503 FROM okl_lease_quotes_b qte
11504 WHERE qte.id = qteid;
11505 quote_rec quote_csr%ROWTYPE;
11506
11507 CURSOR c_strm_type ( qteID NUMBER, expStartDate DATE) IS
11508 SELECT STRM.STY_ID PAYMENT_TYPE_ID,
11509 STRM.STY_NAME PAYMENT_TYPE,
11510 STRM.START_DATE,
11511 STRM.END_DATE,
11512 STRM.STY_PURPOSE
11513 FROM OKL_STRM_TMPT_PRIMARY_UV STRM,
11514 OKL_LEASE_QUOTES_B QUOTE
11515 WHERE STY_PURPOSE = 'RENT'
11516 AND START_DATE <= expStartDate
11517 AND NVL(END_DATE, expStartDate) >= expStartDate
11518 AND STRM.PDT_ID = QUOTE.PRODUCT_ID
11519 AND QUOTE.ID = qteID;
11520
11521 r_strm_type c_strm_type%ROWTYPE;
11522
11523 l_lrs_details lrs_details_rec_type;
11524 l_lrs_factor lrs_factor_rec_type;
11525 l_lrs_levels lrs_levels_tbl_type;
11526
11527 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
11528 l_adj_factor NUMBER;
11529 l_months_per_period NUMBER;
11530 l_months_after NUMBER;
11531 cf_index NUMBER; -- Using as an index for Cash flow levels
11532 -- Cursor to fetch all the Asset and Rollover and Financed fee Details included in the Lease Quote
11533 CURSOR assets_csr(qteid NUMBER)
11534 IS
11535 SELECT ast.asset_number,
11536 ast.id ast_id,
11537 TO_NUMBER(NULL) fee_id,
11538 ast.rate_card_id,
11539 ast.rate_template_id rate_template_id,
11540 ast.structured_pricing,
11541 'FREE_FORM1' fee_type,
11542 TO_NUMBER(NULL) fee_amount,
11543 qte.expected_start_date line_start_date,
11544 qte.expected_delivery_date line_end_date,
11545 ast.lease_rate_factor lease_rate_factor,
11546 ast.target_arrears target_arrears,
11547 ast.oec_percentage oec_percentage
11548 FROM okl_assets_b ast,
11549 okl_lease_quotes_b qte
11550 WHERE ast.parent_object_code = 'LEASEQUOTE'
11551 AND ast.parent_object_id = qte.id
11552 AND qte.id = qteid
11553 UNION
11554 SELECT NULL asset_number,
11555 TO_NUMBER(NULL) ast_id,
11556 fee.id fee_id,
11557 fee.rate_card_id,
11558 fee.rate_template_id,
11559 fee.structured_pricing,
11560 fee.fee_type,
11561 fee.fee_amount,
11562 fee.effective_from line_start_date,
11563 fee.effective_to line_end_date,
11564 fee.lease_rate_factor lease_rate_factor,
11565 fee.target_arrears target_arrears,
11566 NULL oec_percentage
11567 FROM okl_fees_b fee,
11568 okl_lease_quotes_b qte
11569 WHERE fee.parent_object_code = 'LEASEQUOTE'
11570 AND fee.parent_object_id = qte.id
11571 AND qte.id = qteid;
11572 assets_rec assets_csr%ROWTYPE;
11573
11574 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
11575 CURSOR services_csr(qteid NUMBER)
11576 IS
11577 SELECT srvc.id srvc_id,
11578 srvc.effective_from line_start_date
11579 FROM okl_services_b srvc,
11580 okl_lease_quotes_b qte
11581 WHERE srvc.parent_object_code = 'LEASEQUOTE'
11582 AND srvc.parent_object_id = qte.id
11583 AND qte.id = qteid;
11584
11585 l_srvc_inflow_caf_rec so_cash_flows_rec_type;
11586 l_srvc_inflow_cfl_tbl so_cash_flow_details_tbl_type;
11587 -- Bug 7440199: Quote Streams ER: RGOOTY: End
11588 -- Cursor to fetch the Asset Component Details
11589 CURSOR asset_adj_csr(qteid NUMBER,
11590 astid NUMBER)
11591 IS
11592 SELECT ast.asset_number,
11593 ast.install_site_id,
11594 ast.rate_card_id,
11595 ast.rate_template_id,
11596 ast.oec,
11597 nvl(nvl(ast.end_of_term_value, ast.end_of_term_value_default),0) end_of_term_value,
11598 ast.oec_percentage,
11599 cmp.unit_cost,
11600 cmp.number_of_units,
11601 cmp.primary_component
11602 FROM okl_assets_b ast,
11603 okl_lease_quotes_b qte,
11604 okl_asset_components_b cmp
11605 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
11606 ast.parent_object_id = qte.id AND
11607 qte.id = qteid AND
11608 ast.id = astid AND
11609 cmp.primary_component = 'YES' AND
11610 cmp.asset_id = ast.id;
11611 -- Cursor to fetch the Asset Cost Adjustment Details
11612 CURSOR asset_cost_adj_csr(qteid NUMBER,
11613 astid NUMBER)
11614 IS
11615 SELECT adj.adjustment_source_type,
11616 adj.adjustment_source_id,
11617 adj.basis,
11618 -- Start : DJANASWA : Bug# 6347118
11619 nvl(adj.value,adj.default_subsidy_amount) value
11620 -- End : DJANASWA : Bug# 6347118
11621 FROM okl_assets_b ast,
11622 okl_lease_quotes_b qte,
11623 okl_cost_adjustments_b adj
11624 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
11625 ast.parent_object_id = qte.id AND
11626 qte.id = qteid AND
11627 ast.id = astid AND
11628 adj.parent_object_id = ast.id;
11629
11630 Cursor subsidy_adj_csr( subId NUMBER)
11631 IS
11632 -- Bug 6622178 : Start
11633 -- Fetch the Subsidy Calculation Basis
11634 Select amount, SUBSIDY_CALC_BASIS
11635 -- Bug 6622178 : End
11636 From okl_subsidies_b
11637 where id = subId;
11638 subsidy_adj_rec subsidy_adj_csr%ROWTYPE;
11639 -- Cursor to fetch the Territory ID, Customer Credit Class
11640 CURSOR get_cust_details_csr( p_lq_id NUMBER )
11641 IS
11642 SELECT lopp.id parent_id
11643 ,lopp.prospect_id prospect_id
11644 ,lopp.cust_acct_id cust_acct_id
11645 ,lopp.sales_territory_id sales_territory_id
11646 ,lopp.currency_code currency_code
11647 FROM okl_lease_quotes_b lq,
11648 okl_lease_opportunities_b lopp
11649 WHERE parent_object_code = 'LEASEOPP'
11650 AND parent_object_id = lopp.id
11651 AND lq.id = p_lq_id;
11652
11653 CURSOR get_cust_details_csr_lapp( p_lq_id NUMBER )
11654 IS
11655 SELECT lapp.id parent_id
11656 ,lapp.prospect_id prospect_id
11657 ,lapp.cust_acct_id cust_acct_id
11658 ,lapp.sales_territory_id sales_territory_id
11659 ,lapp.currency_code currency_code
11660 FROM okl_lease_quotes_b lq,
11661 okl_lease_applications_b lapp
11662 WHERE parent_object_code = 'LEASEAPP'
11663 AND parent_object_id = lapp.id
11664 AND lq.id = p_lq_id;
11665 -- Cursor for checking whether the CFO Exists or not
11666 CURSOR check_cfo_exists_csr(
11667 p_oty_code IN VARCHAR2,
11668 p_source_table IN VARCHAR2,
11669 p_source_id IN VARCHAR2,
11670 p_sts_code IN VARCHAR2 )
11671 IS
11672 SELECT 'YES' cfo_exists,
11673 cfo.id cfo_id,
11674 caf.id caf_id
11675 FROM OKL_CASH_FLOW_OBJECTS cfo,
11676 OKL_CASH_FLOWS caf
11677 WHERE OTY_CODE = p_oty_code
11678 AND SOURCE_TABLE = p_source_table
11679 AND SOURCE_ID = p_source_id
11680 AND caf.cfo_id = cfo.id;
11681 check_cfo_exists_rec check_cfo_exists_csr%ROWTYPE;
11682 -- Cursor to fetch EOT Type
11683 CURSOR get_eot_type( p_lq_id NUMBER )
11684 IS
11685 SELECT lq.id
11686 ,lq.reference_number
11687 ,eot.end_of_term_name
11688 ,eot.eot_type_code eot_type_code
11689 ,eot.end_of_term_id end_of_term_id
11690 ,eotversion.end_of_term_ver_id
11691 FROM OKL_LEASE_QUOTES_B lq,
11692 okl_fe_eo_term_vers eotversion,
11693 okl_fe_eo_terms_all_b eot
11694 WHERE lq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
11695 AND eot.end_of_term_id = eotversion.end_of_term_id
11696 AND lq.id = p_lq_id;
11697 l_eot_type_code VARCHAR2(30);
11698 -- Cursor to handle the CAPITALIZED Fee amount for each Asset
11699 CURSOR get_asset_cap_fee_amt(p_source_type VARCHAR2,
11700 p_source_id OKL_LINE_RELATIONSHIPS_B.source_line_ID%TYPE,
11701 p_related_line_type OKL_LINE_RELATIONSHIPS_B.related_line_type%TYPE)
11702 IS
11703 SELECT SUM(amount) capitalized_amount
11704 FROM okl_line_relationships_v lre
11705 WHERE source_line_type = p_source_type
11706 AND related_line_type = 'CAPITALIZED'
11707 AND source_line_id = p_source_id;
11708
11709 --Bug 5884825 PAGARG start
11710 CURSOR product_name_csr(qteid NUMBER)
11711 IS
11712 SELECT PDT.NAME PRODUCTNAME
11713 FROM OKL_LEASE_QUOTES_B QTE
11714 , OKL_PRODUCTS PDT
11715 WHERE QTE.PRODUCT_ID = PDT.ID
11716 AND QTE.ID = qteid;
11717 --Bug 5884825 PAGARG end
11718
11719 l_product_name okl_products.NAME%TYPE;--Bug 5884825 PAGARG
11720 l_day_count_method VARCHAR2(30);
11721 l_days_in_month VARCHAR2(30);
11722 l_days_in_year VARCHAR2(30);
11723 l_currency VARCHAR2(30);
11724 l_srt_details OKL_PRICING_UTILS_PVT.srt_details_rec_type;
11725 l_ast_srt_details OKL_PRICING_UTILS_PVT.srt_details_rec_type;
11726 x_iir NUMBER;
11727 l_initial_guess NUMBER := 0.1;
11728 x_payment NUMBER;
11729 l_lq_cash_flow_rec OKL_PRICING_UTILS_PVT.so_cash_flows_rec_type; -- Quote Level Cash Flow Object
11730 l_lq_cash_flow_det_tbl OKL_PRICING_UTILS_PVT.so_cash_flow_details_tbl_type; -- Quote Level Cash Flow levels
11731 l_lq_cash_inflows OKL_PRICING_UTILS_PVT.cash_inflows_tbl_type; -- Lease Quote level Streams
11732 l_lq_pricing_parameter_rec OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
11733 l_tmp_pricing_parameter_rec OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
11734 l_pricing_parameter_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
11735 l_pp_non_sub_iir_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
11736 l_pp_non_sub_irr_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
11737 l_pp_lq_fee_srv_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
11738 l_lq_residual_inflows OKL_PRICING_UTILS_PVT.cash_inflows_tbl_type;
11739 l_overridden BOOLEAN;
11740 l_non_overiding_assets_tbl OKL_STREAMS_UTIL.NumberTabTyp;
11741 l_noa_pp_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
11742 lnoa_index BINARY_INTEGER;
11743 ppfs_index BINARY_INTEGER;
11744 l_eot_date DATE;
11745 l_cf_dpp NUMBER;
11746 l_cf_ppy NUMBER;
11747 res_index BINARY_INTEGER;
11748 pp_index BINARY_INTEGER;
11749 l_yields_rec yields_rec;
11750 l_subsidized_yields_rec yields_rec;
11751 l_iir_noa_dts NUMBER; -- IIR @ LQ level for Non-overriding assets considering
11752 -- Downpayment/Subsidy/Trade-In
11753 l_iir_noa NUMBER; -- IIR @ LQ level for Non-overriding assets with out
11754 -- considering Downpayment/Subsidy/Trade-In
11755 l_lq_pp_noa_dts OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
11756 l_lq_pp_noa OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
11757 l_iir_temp NUMBER;
11758 l_adj_mat_cat_rec adj_mat_cat_rec;
11759 l_ass_adj_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_adjustment_tbl_type;
11760 l_cash_flow_rec so_cash_flows_rec_type;
11761 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
11762 l_cash_inflows OKL_PRICING_UTILS_PVT.cash_inflows_tbl_type;
11763 l_lease_qte_rec OKL_LEASE_QUOTE_PVT.lease_qte_rec_type;
11764 x_lease_qte_rec OKL_LEASE_QUOTE_PVT.lease_qte_rec_type;
11765 l_lq_payment_header_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
11766 l_lq_payment_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
11767 l_cfo_exists_at_lq VARCHAR2(30);
11768 l_cfo_exists_at_noa VARCHAR2(30);
11769 l_tot_noa_oec NUMBER;
11770 l_noa_cash_flow_rec OKL_PRICING_UTILS_PVT.so_cash_flows_rec_type;
11771 l_noa_cash_flow_det_tbl OKL_PRICING_UTILS_PVT.so_cash_flow_details_tbl_type;
11772 l_noa_payment_header_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
11773 l_noa_payment_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
11774 l_fee_outflow_caf_rec so_cash_flows_rec_type;
11775 l_fee_outflow_cfl_tbl so_cash_flow_details_tbl_type;
11776 l_fee_inflow_caf_rec so_cash_flows_rec_type;
11777 l_fee_inflow_cfl_tbl so_cash_flow_details_tbl_type;
11778 l_adj_type VARCHAR2(30);
11779 l_pricing_method OKL_LEASE_QUOTES_B.PRICING_METHOD%TYPE;
11780 l_sp_for_assets BOOLEAN;
11781 l_an_ass_follow_lq BOOLEAN;
11782 l_lq_details_prc_rec OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
11783 l_rent_sty_id OKL_STRM_TYPE_B.ID%TYPE;
11784 l_asset_caf_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
11785 l_asset_cfl_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
11786 l_ast_level_fin_amt NUMBER;
11787 l_lq_level_fin_amt NUMBER;
11788 l_quote_type_code OKL_LEASE_QUOTES_B.PARENT_OBJECT_CODE%TYPE;
11789 l_solved VARCHAR2(30);
11790 l_tmp_amount NUMBER;
11791 l_lq_con_cash_inflows cash_inflows_tbl_type;
11792 l_iir NUMBER;
11793 l_miss_payment NUMBER;
11794 l_rnd_sum_assets_pmnts_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
11795 l_rnd_lq_payment_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
11796 l_sum_of_noa_oec_percent NUMBER;
11797 -- Bug 6622178 : Start
11798 l_disp_sf_msg BOOLEAN;
11799 -- Bug 6622178 : End
11800 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
11801 l_amount NUMBER;
11802 l_sum_assoc_assets_amt NUMBER;
11803 l_assoc_assets_count NUMBER;
11804 l_assets_indx NUMBER;
11805 l_fee_id OKL_FEES_B.ID%TYPE;
11806
11807 TYPE amount_tabtype IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
11808 l_amount_tbl amount_tabtype;
11809
11810 --Cursor to get the associated assets count and amount for Service Line
11811 CURSOR CHECK_ASSOC_ASSETS(P_LINE_TYPE VARCHAR2,
11812 P_FEE_SRVC_ID OKL_LINE_RELATIONSHIPS_B.RELATED_LINE_ID%TYPE) IS
11813 SELECT SUM(AMOUNT),
11814 COUNT(*)
11815 FROM OKL_LINE_RELATIONSHIPS_B
11816 WHERE SOURCE_LINE_TYPE = 'ASSET'
11817 AND RELATED_LINE_TYPE = P_LINE_TYPE
11818 AND RELATED_LINE_ID = P_FEE_SRVC_ID;
11819
11820 --Cursor to get the Associated Asset ID and Amount for Service Line
11821 CURSOR GET_ASSOC_ASSETS(P_LINE_TYPE VARCHAR2,
11822 P_FEE_SRVC_ID OKL_LINE_RELATIONSHIPS_B.RELATED_LINE_ID%TYPE) IS
11823 SELECT SOURCE_LINE_ID,
11824 AMOUNT
11825 FROM OKL_LINE_RELATIONSHIPS_B
11826 WHERE SOURCE_LINE_TYPE = 'ASSET'
11827 AND RELATED_LINE_TYPE = P_LINE_TYPE
11828 AND RELATED_LINE_ID = P_FEE_SRVC_ID;
11829
11830 CURSOR GET_FEE_ID(P_CFO_ID OKL_CASH_FLOW_OBJECTS.ID%TYPE) IS
11831 SELECT SOURCE_ID
11832 FROM OKL_CASH_FLOW_OBJECTS
11833 WHERE ID = P_CFO_ID;
11834 -- Bug 7440199: Quote Streams ER: RGOOTY: End
11835 BEGIN
11836 l_return_status := OKL_API.G_RET_STS_SUCCESS;
11837 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
11838 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
11839 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
11840 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
11841 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
11842 l_return_status := OKL_API.START_ACTIVITY(
11843 p_api_name => l_api_name,
11844 p_pkg_name => G_PKG_NAME,
11845 p_init_msg_list => p_init_msg_list,
11846 l_api_version => l_api_version,
11847 p_api_version => p_api_version,
11848 p_api_type => g_api_type,
11849 x_return_status => l_return_status);
11850 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11851 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11852 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11853 RAISE OKL_API.G_EXCEPTION_ERROR;
11854 END IF;
11855
11856 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
11857 delete_quote_streams(p_api_version => p_api_version,
11858 p_init_msg_list => p_init_msg_list,
11859 x_return_status => l_return_status,
11860 x_msg_count => x_msg_count,
11861 x_msg_data => x_msg_data,
11862 p_quote_id => p_qte_id
11863 );
11864 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11865 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11866 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11867 RAISE OKL_API.G_EXCEPTION_ERROR;
11868 END IF;
11869 -- Bug 7440199: Quote Streams ER: RGOOTY: End
11870 --Bug 5884825 PAGARG start
11871 OPEN product_name_csr(p_qte_id);
11872 FETCH product_name_csr INTO l_product_name;
11873 CLOSE product_name_csr;
11874 --Bug 5884825 PAGARG end
11875
11876 -- Fetch the Lease Quote Header Details !
11877 OPEN quote_csr(p_qte_id);
11878 FETCH quote_csr INTO quote_rec;
11879 IF (quote_csr%NOTFOUND) THEN
11880 RAISE okl_api.g_exception_unexpected_error;
11881 END IF;
11882 CLOSE quote_csr;
11883 IF quote_rec.parent_object_code = 'LEASEAPP' THEN
11884 l_quote_type_code := 'LA';
11885 ELSE
11886 l_quote_type_code := 'LQ';
11887 END IF;
11888 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11889 '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ');
11890 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11891 '!!!!!!!!!!!!Pricing of ' || quote_rec.reference_number || '!!!!!!!!!!!! ');
11892 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11893 '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ');
11894 -- Derieve the End of Term Date of the Lease Quote
11895 okl_stream_generator_pvt.add_months_new(
11896 p_start_date => quote_rec.expected_start_date,
11897 p_months_after => quote_rec.term,
11898 x_date => l_eot_date,
11899 x_return_status => l_return_status);
11900 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11901 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11902 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11903 RAISE OKL_API.G_EXCEPTION_ERROR;
11904 END IF;
11905 l_eot_date := l_eot_date - 1;
11906 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11907 'Effective To of the LQ ' || l_eot_date );
11908 -- Populate the l_adj_mat_cat_rec !
11909 -- Here instead of straightly assuming that user will only pick the SRT at the
11910 -- Quote level, we should be writing an API, which will build the cash flows and cash flow levels
11911 -- if the user has picked the SRT, or otherwise the API will fetch directly from
11912 -- the Cash flows in case of User picked the Structured Pricing option ...
11913 l_adj_mat_cat_rec.target_eff_from := quote_rec.expected_start_date;
11914 l_adj_mat_cat_rec.term := quote_rec.term;
11915 IF quote_rec.parent_object_code = 'LEASEOPP'
11916 THEN
11917 -- Fetch from the Lease Opportunity
11918 FOR t_rec IN get_cust_details_csr( p_lq_id => p_qte_id )
11919 LOOP
11920 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
11921 l_adj_mat_cat_rec.customer_credit_class :=
11922 okl_lease_app_pvt.get_credit_classfication(
11923 p_party_id => t_rec.prospect_id,
11924 p_cust_acct_id => t_rec.cust_acct_id,
11925 p_site_use_id => -99);
11926 -- Store the currency now
11927 l_currency := t_rec.currency_code;
11928 END LOOP;
11929 ELSE
11930 -- Fetch from the Lease Application
11931 FOR t_rec IN get_cust_details_csr_lapp( p_lq_id => p_qte_id )
11932 LOOP
11933 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
11934 l_adj_mat_cat_rec.customer_credit_class :=
11935 okl_lease_app_pvt.get_credit_classfication(
11936 p_party_id => t_rec.prospect_id,
11937 p_cust_acct_id => t_rec.cust_acct_id,
11938 p_site_use_id => -99);
11939 -- Store the currency now
11940 l_currency := t_rec.currency_code;
11941 END LOOP;
11942 END IF;
11943 l_adj_mat_cat_rec.deal_size := NULL; -- Dont know how to get these value !
11944 -- Know the type of the EOT
11945 FOR t_rec IN get_eot_type( p_lq_id => p_qte_id )
11946 LOOP
11947 l_eot_type_code := t_rec.eot_type_code;
11948 END LOOP;
11949 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11950 '****Currency Code = ' || l_currency || '****EOT Type ' || l_eot_type_code);
11951 IF quote_rec.pricing_method <> 'RC'
11952 THEN
11953 get_lq_cash_flows(
11954 p_api_version => p_api_version,
11955 p_init_msg_list => p_init_msg_list,
11956 x_return_status => l_return_status,
11957 x_msg_count => x_msg_count,
11958 x_msg_data => x_msg_data,
11959 p_id => p_qte_id,
11960 p_lq_srt_id => quote_rec.rate_template_id,
11961 p_cf_source => G_CF_SOURCE_LQ, -- Fetch SRT / Strucutured Pricing details at Lease Quote Level
11962 p_adj_mat_cat_rec => l_adj_mat_cat_rec,
11963 p_pricing_method => quote_rec.pricing_method,
11964 x_days_in_month => l_days_in_month,
11965 x_days_in_year => l_days_in_year,
11966 x_cash_flow_rec => l_lq_cash_flow_rec,
11967 x_cash_flow_det_tbl => l_lq_cash_flow_det_tbl);
11968 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11969 'After get_lq_cash_flows ' || l_return_status);
11970 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11971 'No. of Cash Flow Levels ' || l_lq_cash_flow_det_tbl.COUNT );
11972 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11973 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11974 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11975 RAISE OKL_API.G_EXCEPTION_ERROR;
11976 END IF;
11977 l_cfo_exists_at_lq := 'NO';
11978 FOR t_rec IN check_cfo_exists_csr(
11979 p_oty_code => 'LEASE_QUOTE',
11980 p_source_table => 'OKL_LEASE_QUOTES_B',
11981 p_source_id => p_qte_id,
11982 p_sts_code => 'CURRENT')
11983 LOOP
11984 l_cfo_exists_at_lq := t_rec.cfo_exists;
11985 END LOOP;
11986 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11987 'After check_cfo_exists_csr. l_cfo_exists_at_lq' || l_cfo_exists_at_lq);
11988 -- Populate the l_payment_header_rec and l_payment_level_tbl structures
11989 -- CFO, CFH Population
11990 IF l_cfo_exists_at_lq = 'YES'
11991 THEN
11992 l_lq_payment_header_rec.cashflow_header_id := l_lq_cash_flow_rec.caf_id;
11993 l_lq_payment_header_rec.cashflow_object_id := l_lq_cash_flow_rec.cfo_id;
11994 l_lq_payment_header_rec.stream_type_id := l_lq_cash_flow_rec.sty_id;
11995 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11996 'Passing l_lq_payment_header_rec.cashflow_header_id ' ||
11997 l_lq_payment_header_rec.cashflow_header_id );
11998 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11999 ' l_lq_payment_header_rec.cashflow_object_id ' ||
12000 l_lq_payment_header_rec.cashflow_object_id);
12001 END IF;
12002 IF l_lq_payment_header_rec.stream_type_id IS NULL OR
12003 l_cfo_exists_at_lq = 'NO'
12004 THEN
12005 OPEN c_strm_type ( quote_rec.id, quote_rec.expected_start_date );
12006 FETCH c_strm_type INTO r_strm_type;
12007 CLOSE c_strm_type;
12008 l_lq_payment_header_rec.stream_type_id := r_strm_type.payment_type_id;
12009 END IF;
12010 -- Store the rent Stream ID
12011 l_rent_sty_id := l_lq_payment_header_rec.stream_type_id;
12012 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12013 'Fetched the RENT Stream Type ID ' || l_lq_payment_header_rec.stream_type_id
12014 || ' Quote ID ' || quote_rec.id || ' Start Date ' || quote_rec.expected_start_date );
12015 l_lq_payment_header_rec.parent_object_id := p_qte_id;
12016 l_lq_payment_header_rec.quote_id := p_qte_id;
12017 l_lq_payment_header_rec.type_code := 'INFLOW';
12018 IF l_lq_cash_flow_rec.sts_code = 'CURRENT' THEN
12019 l_lq_payment_header_rec.status_code:= 'CURRENT';
12020 ELSE
12021 l_lq_payment_header_rec.status_code:= 'WORK';
12022 END IF;
12023 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12024 '****** Cash flow status code ' || l_lq_payment_header_rec.status_code );
12025 l_lq_payment_header_rec.parent_object_code := 'LEASE_QUOTE';
12026 l_lq_payment_header_rec.arrears_flag := l_lq_cash_flow_rec.due_arrears_yn;
12027 l_lq_payment_header_rec.quote_type_code := l_quote_type_code;
12028 -- Populate the Cash flow levels
12029 IF l_lq_cash_flow_det_tbl.COUNT > 0
12030 THEN
12031 l_lq_payment_header_rec.frequency_code :=
12032 l_lq_cash_flow_det_tbl(l_lq_cash_flow_det_tbl.FIRST).fqy_code;
12033 FOR t_index IN l_lq_cash_flow_det_tbl.FIRST .. l_lq_cash_flow_det_tbl.LAST
12034 LOOP
12035 IF l_cfo_exists_at_lq = 'YES'
12036 THEN
12037 l_lq_payment_level_tbl(t_index).cashflow_level_id := l_lq_cash_flow_det_tbl(t_index).cfl_id;
12038 l_lq_payment_level_tbl(t_index).record_mode := 'UPDATE';
12039 l_lq_payment_level_tbl(t_index).cashflow_level_ovn := NULL;
12040 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12041 ' l_lq_payment_level_tbl(t_index).cashflow_level_id ' ||
12042 l_lq_payment_level_tbl(t_index).cashflow_level_id);
12043 ELSE
12044 l_lq_payment_level_tbl(t_index).record_mode := 'CREATE';
12045 END IF;
12046 l_lq_payment_level_tbl(t_index).rate := l_lq_cash_flow_det_tbl(t_index).rate;
12047 l_lq_payment_level_tbl(t_index).stub_days := l_lq_cash_flow_det_tbl(t_index).stub_days;
12048 l_lq_payment_level_tbl(t_index).stub_amount := l_lq_cash_flow_det_tbl(t_index).stub_amount;
12049 l_lq_payment_level_tbl(t_index).periods := l_lq_cash_flow_det_tbl(t_index).number_of_periods;
12050 l_lq_payment_level_tbl(t_index).periodic_amount := l_lq_cash_flow_det_tbl(t_index).amount;
12051 l_lq_payment_level_tbl(t_index).start_date := l_lq_cash_flow_det_tbl(t_index).start_date;
12052 END LOOP;
12053 END IF;
12054 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12055 'Stored the Cash Flows in the l_lq_payment_level_tbl' );
12056 -- Populated the payment_header_rec and payment_level for use at later Stage !
12057 get_day_count_method(
12058 p_days_in_month => l_days_in_month,
12059 p_days_in_year => l_days_in_year,
12060 x_day_count_method => l_day_count_method,
12061 x_return_status => l_return_status );
12062 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12063 'Return Status | l_days_in_month | l_days_in_year | l_day_count_method ' );
12064 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12065 l_return_status || ' | ' || l_days_in_month || ' | ' || l_days_in_year || ' | ' || l_day_count_method );
12066 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12067 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12068 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12069 --Bug 5884825 PAGARG start
12070 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
12071 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
12072 p_token1 => 'PRODUCT_NAME',
12073 p_token1_value => l_product_name);
12074 --Bug 5884825 PAGARG end
12075 RAISE OKL_API.G_EXCEPTION_ERROR;
12076 END IF;
12077 -- Generate the Streams for the payment at the Quote Level !
12078 IF l_lq_cash_flow_det_tbl IS NOT NULL AND
12079 l_lq_cash_flow_det_tbl.COUNT > 0
12080 THEN
12081 -- Initialize the Strm Count to Zero
12082 gen_so_cf_strms(
12083 p_api_version => p_api_version,
12084 p_init_msg_list => p_init_msg_list,
12085 x_return_status => l_return_status,
12086 x_msg_count => x_msg_count,
12087 x_msg_data => x_msg_data,
12088 p_cash_flow_rec => l_lq_cash_flow_rec,
12089 p_cf_details_tbl => l_lq_cash_flow_det_tbl,
12090 x_cash_inflow_strms_tbl => l_lq_cash_inflows);
12091 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12092 'After gen_so_cf_strms ' || l_return_status);
12093 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12094 'Number of Stream Elements generated ' || l_lq_cash_inflows.COUNT);
12095 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12096 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12097 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12098 RAISE OKL_API.G_EXCEPTION_ERROR;
12099 END IF;
12100 -- Get the DPP and PPY inorder to populate for the Residuals Table
12101 get_dpp_ppy(
12102 p_frequency => l_lq_cash_flow_det_tbl(l_lq_cash_flow_det_tbl.FIRST).fqy_code,
12103 x_dpp => l_cf_dpp,
12104 x_ppy => l_cf_ppy,
12105 x_return_status => l_return_status );
12106 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12107 'After get_dpp_ppy ' || l_return_status );
12108 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12109 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12110 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12111 RAISE OKL_API.G_EXCEPTION_ERROR;
12112 END IF;
12113 ELSE
12114 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12115 '********** No pricing option picked @ LQ ! *******' );
12116 END IF; -- IF l_cash_flow_det_tbl.COUNT > 0
12117 END IF; -- IF pricing_method <> 'RC'
12118 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module,
12119 'price method ' || quote_rec.pricing_method, l_return_status );
12120 IF quote_rec.pricing_method = 'SP' OR
12121 quote_rec.pricing_method = 'SM'
12122 THEN
12123 -- Solve for Payment
12124 l_lq_pricing_parameter_rec.financed_amount := 0;
12125 l_lq_pricing_parameter_rec.down_payment := 0;
12126 l_lq_pricing_parameter_rec.trade_in := 0;
12127 l_lq_pricing_parameter_rec.subsidy := 0;
12128 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
12129 pp_index := 1;
12130 lnoa_index := 1;
12131 res_index := 1;
12132 l_non_overiding_assets_tbl.DELETE;
12133 -- Loop through the Assets and check price the asset seperately
12134 -- which has overriddent the payment option picked at the Quote Level
12135 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
12136 LOOP
12137 -- Check whether this Asset has overridden the Payment option defined
12138 -- at the quote level !
12139 IF assets_rec.fee_type <> 'FREE_FORM1'
12140 THEN
12141 l_overridden := TRUE;
12142 ELSE
12143 l_overridden := is_asset_overriding(
12144 p_qte_id => p_qte_id,
12145 p_ast_id => assets_rec.ast_id,
12146 p_lq_line_level_pricing => quote_rec.line_level_pricing,
12147 p_lq_srt_id => quote_rec.rate_template_id,
12148 p_ast_srt_id => assets_rec.rate_template_id,
12149 p_lq_struct_pricing => quote_rec.structured_pricing,
12150 p_ast_struct_pricing => assets_rec.structured_pricing,
12151 p_lq_arrears_yn => quote_rec.target_arrears,
12152 p_ast_arrears_yn => assets_rec.target_arrears,
12153 x_return_status => l_return_status);
12154 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12155 'After is_asset_overriding assets_rec.id =' || assets_rec.ast_id);
12156 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12157 ' l_return_status =' || l_return_status );
12158 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12159 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12160 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12161 RAISE OKL_API.G_EXCEPTION_ERROR;
12162 END IF;
12163 END IF;
12164 IF l_overridden = FALSE
12165 THEN
12166 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12167 ' Asset follows the Payment Structure defined @ Lease Quote level ' || assets_rec.asset_number );
12168 -- The current Asset is following the pricing option defined at the LQ level !
12169 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
12170 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
12171 astid => assets_rec.ast_id)
12172 LOOP
12173 -- Fetch the Asset Cost Adjustment information like ..
12174 -- Down Payment/Subsidy/Trade-in
12175 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
12176 THEN
12177 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
12178 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
12179 THEN
12180 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
12181 THEN
12182 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
12183 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
12184 CLOSE subsidy_adj_csr;
12185 -- Bug 6622178 : Start
12186 -- Consider all subsidies for the asset
12187 IF l_noa_pp_tbl.EXISTS(lnoa_index) then
12188 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(subsidy_adj_rec.amount,0);
12189 ELSE
12190 l_noa_pp_tbl(lnoa_index).subsidy := NVL(subsidy_adj_rec.amount,0);
12191 -- Bug 6622178 : End
12192 END IF;
12193 ELSE
12194 -- Bug 6622178 : Start
12195 -- Consider all subsidies for the asset
12196 IF l_noa_pp_tbl.EXISTS(lnoa_index) then
12197 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(asset_cost_adj_rec.value,0);
12198 ELSE
12199 l_noa_pp_tbl(lnoa_index).subsidy := NVL(asset_cost_adj_rec.value,0);
12200 -- Bug 6622178 : End
12201 END IF;
12202 END IF;
12203 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
12204 THEN
12205 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
12206 END IF;
12207 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12208 'After Retrieving the Asset Cost Adjustments ');
12209 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12210 'Down Payment| Trade In | Subsidy ' );
12211 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12212 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' || l_noa_pp_tbl(lnoa_index).trade_in || ' | ' || l_noa_pp_tbl(lnoa_index).subsidy );
12213 END LOOP;
12214 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
12215 LOOP
12216 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec,0);
12217 -- Calculate the Capitalized Fee for this Asset
12218 FOR ct_rec IN get_asset_cap_fee_amt(
12219 p_source_type => 'ASSET',
12220 p_source_id => assets_rec.ast_id,
12221 p_related_line_type => 'CAPITALIZED')
12222 LOOP
12223 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
12224 END LOOP;
12225 l_lq_residual_inflows(res_index).line_number := res_index;
12226 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
12227 THEN
12228 -- Store EOT %age in terms of Decimal like 0.25 for 25%
12229 l_lq_residual_inflows(res_index).cf_amount :=
12230 nvl((asset_adj_rec.end_of_term_value /100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0);
12231 ELSE
12232 -- EOT is mentioned in terms of Amount
12233 l_lq_residual_inflows(res_index).cf_amount := nvl(asset_adj_rec.end_of_term_value, 0);
12234 END IF;
12235 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
12236 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
12237 l_lq_residual_inflows(res_index).is_stub := 'N';
12238 l_lq_residual_inflows(res_index).is_arrears := 'Y';
12239 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
12240 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
12241 -- Store the Asset Residuals in the corresponding NOA Assets table
12242 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
12243 -- Increment the res_index
12244 res_index := res_index + 1;
12245 END LOOP;
12246 -- Bug 6669429 : Start
12247 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
12248 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
12249 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
12250 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
12251 l_lq_pricing_parameter_rec.cap_fee_amount := l_lq_pricing_parameter_rec.cap_fee_amount + nvl(l_noa_pp_tbl(lnoa_index).cap_fee_amount,0);
12252 -- Bug 6669429 : End
12253 lnoa_index := lnoa_index + 1;
12254 ELSE -- IF l_overridden = FALSE
12255 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
12256 IF assets_rec.fee_type = 'FREE_FORM1'
12257 THEN
12258 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12259 ' Asset with ID '|| assets_rec.ast_id || ' overrides the payment structure @ LQ level' );
12260 price_standard_quote_asset(
12261 x_return_status => l_return_status,
12262 x_msg_count => x_msg_count,
12263 x_msg_data => x_msg_data,
12264 p_api_version => p_api_version,
12265 p_init_msg_list => p_init_msg_list,
12266 p_qte_id => p_qte_id,
12267 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
12268 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
12269 p_target_rate => NULL,
12270 p_line_type => assets_rec.fee_type,
12271 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
12272 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12273 'After price_standard_quote_asset ' || l_return_status );
12274 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12275 RAISE okl_api.g_exception_unexpected_error;
12276 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12277 RAISE okl_api.g_exception_error;
12278 END IF;
12279 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
12280 -- Increment the pp_index
12281 pp_index := pp_index + 1;
12282 END IF;
12283 END IF;
12284 END LOOP; -- Loop on the Assets csr
12285 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12286 ' Number of Overriding Lines = ' || l_pricing_parameter_tbl.COUNT || ' | ' ||
12287 ' Number of Non-Overriding Lines = ' || l_non_overiding_assets_tbl.COUNT );
12288 IF l_non_overiding_assets_tbl.COUNT > 0
12289 THEN
12290 -- Store into Pricing Params only if there is atleast one noa assets
12291 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
12292 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
12293 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12294 ' Before Calling compute_iir to solve for payment @ LQ level ' );
12295 -- Now Solve for Payment at the Lease Quote Level using amortization logic !
12296 compute_iir(
12297 p_api_version => p_api_version,
12298 p_init_msg_list => p_init_msg_list,
12299 x_return_status => l_return_status,
12300 x_msg_count => x_msg_count,
12301 x_msg_data => x_msg_data,
12302 p_start_date => quote_rec.expected_start_date,
12303 p_day_count_method => l_day_count_method,
12304 p_pricing_method => quote_rec.pricing_method,
12305 p_initial_guess => l_initial_guess,
12306 px_pricing_parameter_rec => l_lq_pricing_parameter_rec,
12307 px_iir => x_iir,
12308 x_payment => x_payment);
12309 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12310 'After compute_iir ' || l_return_status );
12311 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12312 RAISE okl_api.g_exception_unexpected_error;
12313 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12314 RAISE okl_api.g_exception_error;
12315 END IF;
12316 IF x_payment < 0
12317 THEN
12318 OKL_API.SET_MESSAGE (
12319 p_app_name => G_APP_NAME,
12320 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
12321 p_token1 => 'TYPE',
12322 p_token1_value => 'Payment',
12323 p_token2 => 'AMOUNT',
12324 p_token2_value => round(x_payment,2) );
12325 RAISE okl_api.g_exception_error;
12326 END IF;
12327 -- Now, we need to populate back the Payment Amount back
12328 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12329 '***** **** Updating the stream elements and cash flow with the amount ' || x_payment );
12330 -- Update the Cash inflows with the Solved Amount ..
12331 FOR t_in IN l_lq_pricing_parameter_rec.cash_inflows.FIRST ..
12332 l_lq_pricing_parameter_rec.cash_inflows.LAST
12333 LOOP
12334 IF l_lq_pricing_parameter_rec.cash_inflows(t_in).cf_miss_pay = 'Y' OR
12335 quote_rec.pricing_method = 'SP'
12336 THEN
12337 l_lq_pricing_parameter_rec.cash_inflows(t_in).cf_amount := x_payment;
12338 END IF;
12339 END LOOP;
12340 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12341 'After Updating the PP_REC.cash_inflows with the solved payment amount ' || round( x_payment, 4) );
12342 -- Update the LQ Cash inflows with the Solved Payment Amount
12343 FOR t_in IN l_lq_cash_flow_det_tbl.FIRST..l_lq_cash_flow_det_tbl.LAST
12344 LOOP
12345 IF quote_rec.pricing_method = 'SP' OR
12346 (quote_rec.pricing_method = 'SM' AND l_lq_cash_flow_det_tbl(t_in).number_of_periods > 0 AND l_lq_cash_flow_det_tbl(t_in).amount IS NULL ) OR
12347 ( quote_rec.pricing_method = 'SM' AND l_lq_cash_flow_det_tbl(t_in).stub_days > 0 AND l_lq_cash_flow_det_tbl(t_in).stub_amount IS NULL ) THEN
12348 IF l_lq_cash_flow_det_tbl(t_in).number_of_periods > 0
12349 THEN
12350 l_lq_payment_level_tbl(t_in).periodic_amount := x_payment;
12351 l_lq_payment_level_tbl(t_in).missing_pmt_flag := 'Y';
12352 ELSE
12353 l_lq_payment_level_tbl(t_in).stub_amount := x_payment;
12354 l_lq_payment_level_tbl(t_in).missing_pmt_flag := 'Y';
12355 END IF;
12356 END IF;
12357 END LOOP;
12358 -- Storing the l_lq_pricing_parameter_rec for derieving payments @ every NOA Asset Level.
12359 l_an_ass_follow_lq := TRUE; -- Store the flag
12360 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
12361 IF l_cfo_exists_at_lq = 'YES'
12362 THEN
12363 -- Delete the Cash Flow Levels which may be already created by Pricing ..
12364 okl_lease_quote_cashflow_pvt.delete_cashflows (
12365 p_api_version => p_api_version,
12366 p_init_msg_list => p_init_msg_list,
12367 p_transaction_control => NULL,
12368 p_source_object_code => 'LEASE_QUOTE',
12369 p_source_object_id => p_qte_id,
12370 x_return_status => l_return_status,
12371 x_msg_count => x_msg_count,
12372 x_msg_data => x_msg_data);
12373 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12374 ' ----- After deleting the Cash flows for the asset ' || l_return_status );
12375 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12376 RAISE okl_api.g_exception_unexpected_error;
12377 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12378 RAISE okl_api.g_exception_error;
12379 END IF;
12380 END IF;
12381 FOR cfl_index IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
12382 LOOP
12383 l_lq_payment_level_tbl(cfl_index).record_mode := 'CREATE';
12384 END LOOP;
12385 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12386 'Before creating the cash flows call' );
12387 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
12388 p_api_version => p_api_version,
12389 p_init_msg_list => p_init_msg_list,
12390 p_transaction_control => NULL,
12391 p_cashflow_header_rec => l_lq_payment_header_rec,
12392 p_cashflow_level_tbl => l_lq_payment_level_tbl,
12393 x_return_status => l_return_status,
12394 x_msg_count => x_msg_count,
12395 x_msg_data => x_msg_data);
12396 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12397 'After update_cashflow call ' || l_Return_Status );
12398 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12399 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12400 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12401 RAISE OKL_API.G_EXCEPTION_ERROR;
12402 END IF;
12403 -- pp_index is an post-assigned incremented index!
12404 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
12405 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
12406 l_lq_pricing_parameter_rec.cfo_id := l_lq_payment_header_rec.cashflow_object_id;
12407 -- Bug 7440199: Quote Streams ER: RGOOTY: End
12408 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
12409 -- Increment the pp_index
12410 pp_index := pp_index + 1;
12411 END IF;
12412 -- Store the Pricing Params to solve again for Non-Subsidized Yields
12413 -- Handling the ROLLOVER AND FINANCED FEES
12414 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
12415 LOOP
12416 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
12417 THEN
12418 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12419 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
12420 -- Price the fees ROLLOVER OR FINANCED
12421 price_standard_quote_asset(
12422 x_return_status => l_return_status,
12423 x_msg_count => x_msg_count,
12424 x_msg_data => x_msg_data,
12425 p_api_version => p_api_version,
12426 p_init_msg_list => p_init_msg_list,
12427 p_qte_id => p_qte_id,
12428 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
12429 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
12430 p_target_rate => NULL,
12431 p_line_type => assets_rec.fee_type,
12432 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
12433 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12434 'After price_standard_quote_asset ' || l_return_status );
12435 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12436 RAISE okl_api.g_exception_unexpected_error;
12437 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12438 RAISE okl_api.g_exception_error;
12439 END IF;
12440 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
12441 -- Increment the pp_index
12442 pp_index := pp_index + 1;
12443 END IF;
12444 END LOOP;
12445 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
12446 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
12447 compute_irr(
12448 p_api_version => p_api_version,
12449 p_init_msg_list => p_init_msg_list,
12450 x_return_status => l_return_status,
12451 x_msg_count => x_msg_count,
12452 x_msg_data => x_msg_data,
12453 p_start_date => quote_rec.expected_start_date,
12454 p_day_count_method => l_day_count_method,
12455 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12456 p_pricing_method => 'SY',
12457 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
12458 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
12459 px_irr => x_iir,
12460 x_payment => x_payment);
12461 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12462 '1/ After Computation of SUBSIDIZED-IIR @ LQ Level ' || l_return_status );
12463 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12464 'SOLVED FOR IIR ' || x_iir );
12465 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12466 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12467 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12468 RAISE OKL_API.G_EXCEPTION_ERROR;
12469 END IF;
12470 l_subsidized_yields_rec.iir := x_iir;
12471 l_subsidized_yields_rec.bk_yield := l_subsidized_yields_rec.iir;
12472 -- Populate the Pricing Params with all the other configuration lines
12473 -- for solving the SUBSIDIZED YIELDS @ Lease Quote Level
12474 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
12475 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
12476 LOOP
12477 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
12478 THEN
12479 -- Delete the previous fees cash flows
12480 l_fee_outflow_cfl_tbl.DELETE;
12481 l_fee_inflow_cfl_tbl.DELETE;
12482 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12483 '!!!!!! Handling fee ' || assets_rec.fee_type );
12484 get_lq_fee_cash_flows(
12485 p_api_version => p_api_version,
12486 p_init_msg_list => p_init_msg_list,
12487 x_return_status => l_return_status,
12488 x_msg_count => x_msg_count,
12489 x_msg_data => x_msg_data,
12490 p_fee_type => assets_rec.fee_type,
12491 p_lq_id => p_qte_id,
12492 p_fee_id => assets_rec.fee_id,
12493 x_outflow_caf_rec => l_fee_outflow_caf_rec,
12494 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
12495 x_inflow_caf_rec => l_fee_inflow_caf_rec,
12496 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
12497 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12498 'After get_lq_fee_cash_flows ' || l_return_status );
12499 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12500 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12501 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12502 RAISE OKL_API.G_EXCEPTION_ERROR;
12503 END IF;
12504 -- Based on the outflows/Inflows obtained generate the streams
12505 IF l_fee_outflow_cfl_tbl.COUNT > 0
12506 THEN
12507 l_cash_inflows.DELETE;
12508 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12509 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
12510 gen_so_cf_strms(
12511 p_api_version => p_api_version,
12512 p_init_msg_list => p_init_msg_list,
12513 x_return_status => l_return_status,
12514 x_msg_count => x_msg_count,
12515 x_msg_data => x_msg_data,
12516 p_cash_flow_rec => l_fee_outflow_caf_rec,
12517 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
12518 x_cash_inflow_strms_tbl => l_cash_inflows);
12519 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12520 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12521 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12522 RAISE OKL_API.G_EXCEPTION_ERROR;
12523 END IF;
12524 -- Place the information in the pricing params
12525 pp_index := pp_index + 1;
12526 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
12527 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
12528 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
12529 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
12530 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
12531 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
12532 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_outflow_caf_rec.cfo_id;
12533 -- Bug 7440199: Quote Streams ER: RGOOTY: End
12534 END IF;
12535 -- Based on the outflows/Inflows obtained generate the streams
12536 IF l_fee_inflow_cfl_tbl.COUNT > 0
12537 THEN
12538 l_cash_inflows.DELETE;
12539 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12540 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
12541 gen_so_cf_strms(
12542 p_api_version => p_api_version,
12543 p_init_msg_list => p_init_msg_list,
12544 x_return_status => l_return_status,
12545 x_msg_count => x_msg_count,
12546 x_msg_data => x_msg_data,
12547 p_cash_flow_rec => l_fee_inflow_caf_rec,
12548 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
12549 x_cash_inflow_strms_tbl => l_cash_inflows);
12550 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12551 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12552 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12553 RAISE OKL_API.G_EXCEPTION_ERROR;
12554 END IF;
12555 -- Place the information in the pricing params
12556 pp_index := pp_index + 1;
12557 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
12558 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
12559 THEN
12560 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
12561 ELSE
12562 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
12563 END IF;
12564 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
12565 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
12566 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
12567 -- Bug 7440199: Quote Streams ER: RGOOTY: End
12568 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_inflow_caf_rec.cfo_id;
12569 -- Bug 7440199: Quote Streams ER: RGOOTY: End
12570 END IF;
12571 END IF; -- IF on Fee_type not in ...
12572 IF assets_rec.fee_type = 'ABSORBED'
12573 THEN
12574 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12575 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
12576 -- Increment the pp_index and store the pricng params
12577 pp_index := pp_index + 1;
12578 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
12579 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
12580 END IF;
12581 END LOOP;
12582 -- Store the Pricing Params to solve again for Non-Subsidized IRR Yields
12583 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
12584 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12585 '1/ Before Computation of SUBSIDIZED-IRR @ LQ Level ' );
12586 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
12587 l_iir_temp := NULL;
12588 l_iir_temp := l_subsidized_yields_rec.pre_tax_irr;
12589 compute_irr(
12590 p_api_version => p_api_version,
12591 p_init_msg_list => p_init_msg_list,
12592 x_return_status => l_return_status,
12593 x_msg_count => x_msg_count,
12594 x_msg_data => x_msg_data,
12595 p_start_date => quote_rec.expected_start_date,
12596 p_day_count_method => l_day_count_method,
12597 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12598 p_pricing_method => 'SY',
12599 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
12600 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
12601 -- px_irr => l_subsidized_yields_rec.pre_tax_irr,
12602 px_irr => l_iir_temp,
12603 x_payment => x_payment);
12604 l_subsidized_yields_rec.pre_tax_irr := l_iir_temp;
12605 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12606 '1/ After Computation of SUBSIDIZED-IRR @ LQ Level ' || l_return_status );
12607 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12608 'SOLVED FOR IRR ' || l_subsidized_yields_rec.pre_tax_irr );
12609 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12610 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12611 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12612 RAISE OKL_API.G_EXCEPTION_ERROR;
12613 END IF;
12614 -- Calculation of the Non-Subsidized Yields
12615 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12616 '!!!!!!!!!! Before Computation of NON-SUBSIDIZED-IIR @ LQ Level !!!!!!!!' );
12617 -- Remove subsidy Amount and then solve the IIR now
12618 FOR t_in IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
12619 LOOP
12620 l_pp_non_sub_iir_tbl(t_in).subsidy := 0;
12621 END LOOP;
12622 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
12623 l_iir_temp := NULL;
12624 l_iir_temp := l_yields_rec.iir;
12625 compute_irr(
12626 p_api_version => p_api_version,
12627 p_init_msg_list => p_init_msg_list,
12628 x_return_status => l_return_status,
12629 x_msg_count => x_msg_count,
12630 x_msg_data => x_msg_data,
12631 p_start_date => quote_rec.expected_start_date,
12632 p_day_count_method => l_day_count_method,
12633 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12634 p_pricing_method => 'SY',
12635 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
12636 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
12637 -- px_irr => l_yields_rec.iir,
12638 px_irr => l_iir_temp,
12639 x_payment => x_payment);
12640 l_yields_rec.iir := l_iir_temp;
12641 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12642 '1/ After Computation of NON-SUBSIDIZED-IIR @ LQ Level ' || l_return_status );
12643 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12644 'SOLVED FOR NON-SUBSIDIZED-IIR ' || l_yields_rec.iir );
12645 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12646 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12647 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12648 RAISE OKL_API.G_EXCEPTION_ERROR;
12649 END IF;
12650 l_yields_rec.bk_yield := l_yields_rec.iir;
12651 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12652 '1/ Before Computation of NON-SUBSIDIZED-IRR @ LQ Level ' );
12653 FOR t_in IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
12654 LOOP
12655 l_pp_non_sub_irr_tbl(t_in).subsidy := 0;
12656 END LOOP;
12657 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
12658 l_iir_temp := NULL;
12659 l_iir_temp := l_yields_rec.pre_tax_irr;
12660 compute_irr(
12661 p_api_version => p_api_version,
12662 p_init_msg_list => p_init_msg_list,
12663 x_return_status => l_return_status,
12664 x_msg_count => x_msg_count,
12665 x_msg_data => x_msg_data,
12666 p_start_date => quote_rec.expected_start_date,
12667 p_day_count_method => l_day_count_method,
12668 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12669 p_pricing_method => 'SY',
12670 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
12671 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
12672 -- px_irr => l_yields_rec.pre_tax_irr,
12673 px_irr => l_iir_temp,
12674 x_payment => x_payment);
12675 l_yields_rec.pre_tax_irr := l_iir_temp;
12676 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12677 'After Computation of NON-SUBSIDIZED-IRR @ LQ Level ' || l_return_status );
12678 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12679 'SOLVED FOR NON-SUBSIDIZED-IRR ' || l_yields_rec.pre_tax_irr );
12680 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12681 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12682 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12683 RAISE OKL_API.G_EXCEPTION_ERROR;
12684 END IF;
12685 ELSIF quote_rec.pricing_method = 'SF'
12686 THEN
12687 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12688 ' SOLVING FOR FINANCED AMOUNT ' || l_return_status );
12689 -- End of IF p_pricing_method = 'SP' / 'SM' and begin 'SF'.
12690 -- Solve for Financed Amount
12691 l_lq_pricing_parameter_rec.financed_amount := 0;
12692 l_lq_pricing_parameter_rec.down_payment := 0;
12693 l_lq_pricing_parameter_rec.trade_in := 0;
12694 l_lq_pricing_parameter_rec.subsidy := 0;
12695 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
12696 l_sum_of_noa_oec_percent := 0;
12697 pp_index := 1;
12698 lnoa_index := 1;
12699 res_index := 1;
12700 l_non_overiding_assets_tbl.DELETE;
12701 -- Bug 6622178 : Start
12702 l_disp_sf_msg := FALSE;
12703 -- Bug 6622178 : End
12704 FOR assets_rec IN assets_csr(p_qte_id)
12705 LOOP
12706 -- Loop through all the assets !
12707 IF assets_rec.fee_type <> 'FREE_FORM1'
12708 THEN
12709 l_overridden := TRUE;
12710 ELSE
12711 l_overridden := is_asset_overriding(
12712 p_qte_id => p_qte_id,
12713 p_ast_id => assets_rec.ast_id,
12714 p_lq_line_level_pricing => quote_rec.line_level_pricing,
12715 p_lq_srt_id => quote_rec.rate_template_id,
12716 p_ast_srt_id => assets_rec.rate_template_id,
12717 p_lq_struct_pricing => quote_rec.structured_pricing,
12718 p_ast_struct_pricing => assets_rec.structured_pricing,
12719 p_lq_arrears_yn => quote_rec.target_arrears,
12720 p_ast_arrears_yn => assets_rec.target_arrears,
12721 x_return_status => l_return_status);
12722 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12723 ' Pricing method = SF | x_return_status = ' || l_return_status );
12724 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12725 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12726 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12727 RAISE OKL_API.G_EXCEPTION_ERROR;
12728 END IF;
12729 END IF;
12730 IF l_overridden = FALSE
12731 THEN
12732 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12733 ' Asset follows the Payment Structure defined @ Lease Quote level ' || assets_rec.asset_number );
12734 -- The current Asset is following the pricing option defined at the LQ level !
12735 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
12736 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
12737 astid => assets_rec.ast_id)
12738 LOOP
12739 -- Fetch the Asset Cost Adjustment information like ..
12740 -- Down Payment/Subsidy/Trade-in
12741 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
12742 THEN
12743 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
12744 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
12745 THEN
12746 -- Bug 6622178 : Start
12747 /* IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
12748 THEN
12749 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
12750 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
12751 CLOSE subsidy_adj_csr;
12752 l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
12753 ELSE
12754 l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
12755 END IF;
12756 */
12757 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
12758 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
12759 CLOSE subsidy_adj_csr;
12760 IF ( UPPER(subsidy_adj_rec.SUBSIDY_CALC_BASIS) = 'FINANCED_AMOUNT' AND
12761 asset_cost_adj_rec.value IS NULL)
12762 THEN
12763 l_disp_sf_msg := TRUE;
12764 END IF;
12765 -- Bug 6622178 : End
12766 -- Bug 7429169 : Start
12767 IF l_noa_pp_tbl.EXISTS(lnoa_index)
12768 THEN
12769 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0)
12770 + NVL(asset_cost_adj_rec.value,0);
12771 ELSE
12772 l_noa_pp_tbl(lnoa_index).subsidy := NVL(asset_cost_adj_rec.value,0);
12773 END IF;
12774 -- l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
12775 -- Bug 7429169 : End
12776 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
12777 THEN
12778 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
12779 END IF;
12780 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12781 'After Retrieving the Asset Cost Adjustments ');
12782 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12783 'Down Payment| Trade In | Subsidy ' );
12784 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12785 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' || l_noa_pp_tbl(lnoa_index).trade_in || ' | ' || l_noa_pp_tbl(lnoa_index).subsidy );
12786 END LOOP;
12787 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
12788 LOOP
12789 -- Dont know how to store the financed amount here
12790 l_noa_pp_tbl(lnoa_index).financed_amount := 0;
12791 -- Calculate the Capitalized Fee for this Asset
12792 FOR ct_rec IN get_asset_cap_fee_amt(
12793 p_source_type => 'ASSET',
12794 p_source_id => assets_rec.ast_id,
12795 p_related_line_type => 'CAPITALIZED')
12796 LOOP
12797 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
12798 END LOOP;
12799 l_lq_residual_inflows(res_index).line_number := res_index;
12800 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
12801 THEN
12802 -- Store EOT %age in terms of Decimal like 0.25 for 25%
12803 l_lq_residual_inflows(res_index).cf_amount :=
12804 (asset_adj_rec.end_of_term_value /100) * (assets_rec.oec_percentage/100);
12805 -- Accumulate Assets OEC in the l_sum_of_noa_oec_percent
12806 l_sum_of_noa_oec_percent := l_sum_of_noa_oec_percent + nvl(assets_rec.oec_percentage,0);
12807 ELSE
12808 -- EOT is mentioned in terms of Amount
12809 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
12810 END IF;
12811 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
12812 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
12813 l_lq_residual_inflows(res_index).is_stub := 'N';
12814 l_lq_residual_inflows(res_index).is_arrears := 'Y';
12815 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
12816 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
12817 -- Store the Asset Residuals in the corresponding NOA Assets table
12818 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
12819 -- Increment the res_index
12820 res_index := res_index + 1;
12821 END LOOP;
12822 -- Bug 6669429 : Start
12823 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
12824 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
12825 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
12826 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
12827 l_lq_pricing_parameter_rec.cap_fee_amount := l_lq_pricing_parameter_rec.cap_fee_amount + nvl(l_noa_pp_tbl(lnoa_index).cap_fee_amount,0);
12828 -- Bug 6669429 : End
12829 lnoa_index := lnoa_index + 1;
12830 ELSE -- IF l_overridden = FALSE in pricing method 'SF'
12831 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
12832 IF assets_rec.fee_type = 'FREE_FORM1' --, 'ROLLOVER', 'FINANCED' )
12833 THEN
12834 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12835 ' Asset Overrides the Payment Structure defined @ Lease Quote level ' || assets_rec.asset_number );
12836 price_standard_quote_asset(
12837 x_return_status => l_return_status,
12838 x_msg_count => x_msg_count,
12839 x_msg_data => x_msg_data,
12840 p_api_version => p_api_version,
12841 p_init_msg_list => p_init_msg_list,
12842 p_qte_id => p_qte_id,
12843 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
12844 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
12845 p_target_rate => NULL,
12846 p_line_type => assets_rec.fee_type,
12847 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
12848 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12849 'PM = SF | After price_Standard_quote_asset l_return_Status = '|| l_return_status );
12850 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12851 RAISE okl_api.g_exception_unexpected_error;
12852 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12853 RAISE okl_api.g_exception_error;
12854 END IF;
12855 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
12856 -- Increment the pp_index
12857 pp_index := pp_index + 1;
12858 END IF;
12859 END IF;
12860 END LOOP; -- Loop on the Assets csr
12861 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12862 ' Number of Overriding Lines = ' || l_pricing_parameter_tbl.COUNT );
12863 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12864 ' Number of Non-Overriding Lines = ' || l_non_overiding_assets_tbl.COUNT );
12865 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
12866 -- using amortization logic !
12867 IF l_non_overiding_assets_tbl.COUNT > 0
12868 THEN
12869 -- Manipulate the l_lq_residual_inflows such that the Effective EOT %age is based on
12870 -- OEC Percentage of only non-overriding Assets. Refer eg. in Bug. 5167302
12871 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' ) AND
12872 nvl(l_sum_of_noa_oec_percent,100) <> 100
12873 THEN
12874 IF l_lq_residual_inflows IS NOT NULL AND
12875 l_lq_residual_inflows.COUNT > 0
12876 THEN
12877 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12878 ' !!!! Manipulating the Effective EOT %age. l_sum_of_noa_oec_percent = ' || round(l_sum_of_noa_oec_percent, 4) );
12879 FOR r_in IN l_lq_residual_inflows.FIRST .. l_lq_residual_inflows.LAST
12880 LOOP
12881 l_lq_residual_inflows(r_in).cf_amount := l_lq_residual_inflows(r_in).cf_amount * 100 /l_sum_of_noa_oec_percent;
12882 END LOOP;
12883 END IF;
12884 IF l_noa_pp_tbl IS NOT NULL AND l_noa_pp_tbl.COUNT > 0
12885 THEN
12886 FOR t_in IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
12887 LOOP
12888 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount :=
12889 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount * 100 /l_sum_of_noa_oec_percent;
12890 END LOOP;
12891 END IF;
12892 END IF;
12893 -- If there is atleast one asset which follows the Payment Structure
12894 -- defined at Lease Quote Level, then pass the Pricing param table
12895 -- withe the Cash flows information at lease quote level else DON'T !!
12896 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
12897 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
12898 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
12899 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
12900 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12901 'SF | ------------------ Before compute_iir ------------------ ' );
12902 IF l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT'
12903 THEN
12904 l_pricing_method := 'SFP';
12905 ELSE
12906 l_pricing_method := 'SF';
12907 END IF;
12908 compute_iir(
12909 p_api_version => p_api_version,
12910 p_init_msg_list => p_init_msg_list,
12911 x_return_status => l_return_status,
12912 x_msg_count => x_msg_count,
12913 x_msg_data => x_msg_data,
12914 p_start_date => quote_rec.expected_start_date,
12915 p_day_count_method => l_day_count_method,
12916 p_pricing_method => l_pricing_method,
12917 p_initial_guess => l_initial_guess,
12918 px_pricing_parameter_rec => l_lq_pricing_parameter_rec,
12919 px_iir => x_iir,
12920 x_payment => x_payment);
12921 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12922 'Pricing method = SF | After compute_iir l_return_Status = ' || l_return_status || ' Financed Amount = ' ||
12923 round(l_lq_pricing_parameter_rec.financed_amount, 4) );
12924 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12925 RAISE okl_api.g_exception_unexpected_error;
12926 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12927 RAISE okl_api.g_exception_error;
12928 END IF;
12929 IF l_pricing_method = 'SFP'
12930 THEN
12931 l_pricing_method := 'SF'; -- Revert back the pricing method to 'SF'
12932 -- Calculate the Residual Amount for each of the Non-overridden Asset for furhter yields calculation
12933 IF l_lq_pricing_parameter_rec.residual_inflows IS NOT NULL AND
12934 l_lq_pricing_parameter_rec.residual_inflows.COUNT > 0
12935 THEN
12936 FOR t_in IN l_lq_pricing_parameter_rec.residual_inflows.FIRST ..
12937 l_lq_pricing_parameter_rec.residual_inflows.LAST
12938 LOOP
12939 l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount :=
12940 l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount *
12941 l_lq_pricing_parameter_rec.financed_amount;
12942 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12943 'l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount = ' || round(l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount, 4) );
12944
12945 END LOOP;
12946 END IF; -- Count on Residual Table
12947 -- Calculate the Residual Amount for each of the Non-overridden Asset for pmnt calculation
12948 IF l_noa_pp_tbl IS NOT NULL AND l_noa_pp_tbl.COUNT > 0
12949 THEN
12950 FOR t_in IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
12951 LOOP
12952 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount :=
12953 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount * l_lq_pricing_parameter_rec.financed_amount;
12954 END LOOP;
12955 END IF;
12956 END IF; -- IF l_pricing_method = 'SFP'
12957 -- So, we have now already solved for financed amount at lease quote level !
12958 -- We need to distribute the solved financed amount ( which is at the LQ level )
12959 -- to individual assets !
12960 l_an_ass_follow_lq := TRUE; -- Store the flag
12961 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
12962 distribute_fin_amount_lq(
12963 p_api_version => p_api_version,
12964 p_init_msg_list => p_init_msg_list,
12965 x_return_status => l_return_status,
12966 x_msg_count => x_msg_count,
12967 x_msg_data => x_msg_data,
12968 p_lq_id => p_qte_id,
12969 p_tot_fin_amount => l_lq_pricing_parameter_rec.financed_amount);
12970 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12971 'After distribute_fin_amount_lq ' || l_return_status );
12972 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12973 RAISE okl_api.g_exception_unexpected_error;
12974 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12975 RAISE okl_api.g_exception_error;
12976 END IF;
12977 -- After compute_iir above, the l_lq_pricing_parameter_rec
12978 -- should have been populated with the appropriate values for
12979 -- Financed Amount, Down Payment, Subsidy and all
12980 -- pp_index is an post-assigned incremented index!
12981 --Commented. Bug 7440199: Quote Streams ER: RGOOTY: Start
12982 /*l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
12983 pp_index := pp_index + 1;*/
12984 -- Bug 7440199: Quote Streams ER: RGOOTY: End
12985 -- Pricing has to create the Cash Flow levels when the Pricing option is SRT.
12986 -- So, check whether the Cash flows have been already created by the Pricing or not
12987 -- If already created, then delete and create new else, create new cash flow levels.
12988 IF quote_rec.rate_template_id IS NOT NULL
12989 THEN
12990 IF l_cfo_exists_at_lq = 'YES'
12991 THEN
12992 -- Delete the Cash Flow Levels which may be already created by Pricing ..
12993 okl_lease_quote_cashflow_pvt.delete_cashflows (
12994 p_api_version => p_api_version,
12995 p_init_msg_list => p_init_msg_list,
12996 p_transaction_control => NULL,
12997 p_source_object_code => 'LEASE_QUOTE',
12998 p_source_object_id => p_qte_id,
12999 x_return_status => l_return_status,
13000 x_msg_count => x_msg_count,
13001 x_msg_data => x_msg_data);
13002 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13003 ' ----- "SF" ---- After deleting the Cash flows @ LQ Level ' || l_return_status );
13004 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13005 RAISE okl_api.g_exception_unexpected_error;
13006 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13007 RAISE okl_api.g_exception_error;
13008 END IF;
13009 END IF;
13010 FOR cfl_index IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
13011 LOOP
13012 l_lq_payment_level_tbl(cfl_index).record_mode := 'CREATE';
13013 END LOOP;
13014 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13015 'Before creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
13016 || 'Status_code ' || l_lq_payment_header_rec.status_code );
13017 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
13018 p_api_version => p_api_version,
13019 p_init_msg_list => p_init_msg_list,
13020 p_transaction_control => NULL,
13021 p_cashflow_header_rec => l_lq_payment_header_rec,
13022 p_cashflow_level_tbl => l_lq_payment_level_tbl,
13023 x_return_status => l_return_status,
13024 x_msg_count => x_msg_count,
13025 x_msg_data => x_msg_data);
13026 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13027 'After update_cashflow call ' || l_Return_Status );
13028 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13029 'After creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
13030 || 'Status_code ' || l_lq_payment_header_rec.status_code );
13031 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13032 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13033 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13034 RAISE OKL_API.G_EXCEPTION_ERROR;
13035 END IF;
13036 END IF; -- Check if Pricing Option = SRT
13037 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
13038 -- After compute_iir above, the l_lq_pricing_parameter_rec
13039 -- should have been populated with the appropriate values for
13040 -- Financed Amount, Down Payment, Subsidy and all
13041 -- pp_index is an post-assigned incremented index!
13042 l_lq_pricing_parameter_rec.cfo_id := l_lq_payment_header_rec.cashflow_object_id;
13043 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
13044 pp_index := pp_index + 1;
13045 -- Bug 7440199: Quote Streams ER: RGOOTY: End
13046 END IF;
13047 -- Handling the ROLLOVER AND FINANCED FEES
13048 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
13049 LOOP
13050 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
13051 THEN
13052 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13053 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
13054 -- Price the fees ROLLOVER OR FINANCED
13055 price_standard_quote_asset(
13056 x_return_status => l_return_status,
13057 x_msg_count => x_msg_count,
13058 x_msg_data => x_msg_data,
13059 p_api_version => p_api_version,
13060 p_init_msg_list => p_init_msg_list,
13061 p_qte_id => p_qte_id,
13062 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
13063 p_price_at_lq_level => FALSE, -- Use Fee Level Cash flows only !
13064 p_target_rate => NULL,
13065 p_line_type => assets_rec.fee_type,
13066 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
13067 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13068 'After price_standard_quote_asset ' || l_return_status );
13069 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13070 RAISE okl_api.g_exception_unexpected_error;
13071 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13072 RAISE okl_api.g_exception_error;
13073 END IF;
13074 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
13075 -- Increment the pp_index
13076 pp_index := pp_index + 1;
13077 END IF;
13078 END LOOP;
13079 -- Build Pricing Params for solving IIR @ LQ level
13080 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
13081 -- Now call the compute_iir api to solve the IIR @ Lease Quote Level
13082 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13083 '!!!!!!!! Before Calculating the Subsidized IIR !!!!!!!!!!!' );
13084 l_iir_temp := NULL;
13085 l_iir_temp := l_subsidized_yields_rec.iir;
13086 compute_irr(
13087 p_api_version => p_api_version,
13088 p_init_msg_list => p_init_msg_list,
13089 x_return_status => l_return_status,
13090 x_msg_count => x_msg_count,
13091 x_msg_data => x_msg_data,
13092 p_start_date => quote_rec.expected_start_date,
13093 p_day_count_method => l_day_count_method,
13094 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13095 p_pricing_method => 'SY',
13096 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
13097 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
13098 -- px_irr => l_subsidized_yields_rec.iir,
13099 px_irr => l_iir_temp,
13100 x_payment => x_payment);
13101 l_subsidized_yields_rec.iir := l_iir_temp;
13102 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13103 'After Calculating the Subsidized IIR ' || round(l_subsidized_yields_rec.iir, 4) );
13104 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13105 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13106 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13107 RAISE OKL_API.G_EXCEPTION_ERROR;
13108 END IF;
13109 -- Store the IIR as the Booking Yield
13110 l_subsidized_yields_rec.bk_yield := l_subsidized_yields_rec.iir;
13111 -- Now Build the pricing params table for the calculation of the
13112 -- IRR @ Lease Quote level
13113 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
13114 ppfs_index := nvl(l_pp_non_sub_irr_tbl.LAST, 0);
13115 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
13116 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
13117 LOOP
13118 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
13119 THEN
13120 -- Delete the previous fees cash flows
13121 l_fee_outflow_cfl_tbl.DELETE;
13122 l_fee_inflow_cfl_tbl.DELETE;
13123 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13124 '!!!!!! Handling fee ' || assets_rec.fee_type );
13125 get_lq_fee_cash_flows(
13126 p_api_version => p_api_version,
13127 p_init_msg_list => p_init_msg_list,
13128 x_return_status => l_return_status,
13129 x_msg_count => x_msg_count,
13130 x_msg_data => x_msg_data,
13131 p_fee_type => assets_rec.fee_type,
13132 p_lq_id => p_qte_id,
13133 p_fee_id => assets_rec.fee_id,
13134 x_outflow_caf_rec => l_fee_outflow_caf_rec,
13135 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
13136 x_inflow_caf_rec => l_fee_inflow_caf_rec,
13137 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
13138 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13139 'After get_lq_fee_cash_flows ' || l_return_status );
13140 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13141 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13142 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13143 RAISE OKL_API.G_EXCEPTION_ERROR;
13144 END IF;
13145 -- Based on the outflows/Inflows obtained generate the streams
13146 IF l_fee_outflow_cfl_tbl.COUNT > 0
13147 THEN
13148 l_cash_inflows.DELETE;
13149 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13150 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
13151 gen_so_cf_strms(
13152 p_api_version => p_api_version,
13153 p_init_msg_list => p_init_msg_list,
13154 x_return_status => l_return_status,
13155 x_msg_count => x_msg_count,
13156 x_msg_data => x_msg_data,
13157 p_cash_flow_rec => l_fee_outflow_caf_rec,
13158 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
13159 x_cash_inflow_strms_tbl => l_cash_inflows);
13160 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13161 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13162 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13163 RAISE OKL_API.G_EXCEPTION_ERROR;
13164 END IF;
13165 -- Place the information in the pricing params
13166 ppfs_index := ppfs_index + 1;
13167 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
13168 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
13169 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
13170 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
13171 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
13172 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
13173 l_pp_non_sub_irr_tbl(ppfs_index).cfo_id := l_fee_outflow_caf_rec.cfo_id;
13174 -- Bug 7440199: Quote Streams ER: RGOOTY: End
13175 END IF;
13176 -- Based on the outflows/Inflows obtained generate the streams
13177 IF l_fee_inflow_cfl_tbl.COUNT > 0
13178 THEN
13179 l_cash_inflows.DELETE;
13180 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13181 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
13182 gen_so_cf_strms(
13183 p_api_version => p_api_version,
13184 p_init_msg_list => p_init_msg_list,
13185 x_return_status => l_return_status,
13186 x_msg_count => x_msg_count,
13187 x_msg_data => x_msg_data,
13188 p_cash_flow_rec => l_fee_inflow_caf_rec,
13189 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
13190 x_cash_inflow_strms_tbl => l_cash_inflows);
13191 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13192 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13193 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13194 RAISE OKL_API.G_EXCEPTION_ERROR;
13195 END IF;
13196 -- Place the information in the pricing params
13197 ppfs_index := ppfs_index + 1;
13198 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
13199 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
13200 THEN
13201 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'INCOME';
13202 ELSE
13203 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'SECDEPOSIT';
13204 END IF;
13205 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
13206 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
13207 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
13208 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
13209 l_pp_non_sub_irr_tbl(ppfs_index).cfo_id := l_fee_inflow_caf_rec.cfo_id;
13210 -- Bug 7440199: Quote Streams ER: RGOOTY: End
13211 END IF;
13212 END IF; -- IF on Fee_type not in ...
13213 IF assets_rec.fee_type = 'ABSORBED'
13214 THEN
13215 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13216 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
13217 -- Increment the pp_index and store the pricng params
13218 ppfs_index := ppfs_index + 1;
13219 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
13220 l_pp_non_sub_irr_tbl(ppfs_index).financed_amount := assets_rec.fee_amount;
13221 END IF;
13222 END LOOP;
13223 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13224 'Populated the Fees and Service Pricing Params ' );
13225 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
13226 l_iir_temp := NULL;
13227 l_iir_temp := l_subsidized_yields_rec.pre_tax_irr;
13228 compute_irr(
13229 p_api_version => p_api_version,
13230 p_init_msg_list => p_init_msg_list,
13231 x_return_status => l_return_status,
13232 x_msg_count => x_msg_count,
13233 x_msg_data => x_msg_data,
13234 p_start_date => quote_rec.expected_start_date,
13235 p_day_count_method => l_day_count_method,
13236 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13237 p_pricing_method => 'SY',
13238 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13239 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
13240 -- px_irr => l_subsidized_yields_rec.pre_tax_irr,
13241 px_irr => l_iir_temp,
13242 x_payment => x_payment);
13243 l_subsidized_yields_rec.pre_tax_irr := l_iir_temp;
13244 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13245 'After Calculating the Subsidized IRR ' || round(l_subsidized_yields_rec.pre_tax_irr, 4) );
13246 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13247 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13248 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13249 RAISE OKL_API.G_EXCEPTION_ERROR;
13250 END IF;
13251 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13252 '!!!!!!!!!!! NON-SUBSIDIZIED YIELDS CALCULATION !!!!!!!!!!!' );
13253 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13254 'Removing subsidy from the l_pp_non_sub_iir_tbl ' );
13255 FOR t IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
13256 LOOP
13257 IF l_pp_non_sub_iir_tbl(t).line_type = 'FREE_FORM1'
13258 THEN
13259 l_pp_non_sub_iir_tbl(t).subsidy := 0;
13260 END IF;
13261 END LOOP;
13262 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13263 'Before calculating the IIR ( NON-SUBSIDY ) ' );
13264 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
13265 l_iir_temp := NULL;
13266 l_iir_temp := l_yields_rec.iir;
13267 compute_irr(
13268 p_api_version => p_api_version,
13269 p_init_msg_list => p_init_msg_list,
13270 x_return_status => l_return_status,
13271 x_msg_count => x_msg_count,
13272 x_msg_data => x_msg_data,
13273 p_start_date => quote_rec.expected_start_date,
13274 p_day_count_method => l_day_count_method,
13275 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13276 p_pricing_method => 'SY',
13277 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13278 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
13279 -- px_irr => l_yields_rec.iir,
13280 px_irr => l_iir_temp,
13281 x_payment => x_payment);
13282 l_yields_rec.iir := l_iir_temp;
13283 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13284 'After Calculating the NON-Subsidized IIR ' || round(l_yields_rec.pre_tax_irr, 4) );
13285 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13286 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13287 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13288 RAISE OKL_API.G_EXCEPTION_ERROR;
13289 END IF;
13290 l_yields_rec.bk_yield := l_yields_rec.iir;
13291 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13292 'Removing subsidy from the l_pp_non_sub_irr_tbl ' );
13293 FOR t IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
13294 LOOP
13295 IF l_pp_non_sub_irr_tbl(t).line_type = 'FREE_FORM1'
13296 THEN
13297 l_pp_non_sub_irr_tbl(t).subsidy := 0;
13298 END IF;
13299 END LOOP;
13300 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13301 'Before calculating the IIR ( NON-SUBSIDY ) ' );
13302 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
13303 l_iir_temp := NULL;
13304 l_iir_temp := l_yields_rec.pre_tax_irr;
13305 compute_irr(
13306 p_api_version => p_api_version,
13307 p_init_msg_list => p_init_msg_list,
13308 x_return_status => l_return_status,
13309 x_msg_count => x_msg_count,
13310 x_msg_data => x_msg_data,
13311 p_start_date => quote_rec.expected_start_date,
13312 p_day_count_method => l_day_count_method,
13313 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13314 p_pricing_method => 'SY',
13315 p_initial_guess => l_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13316 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
13317 -- px_irr => l_yields_rec.pre_tax_irr,
13318 px_irr => l_iir_temp,
13319 x_payment => x_payment);
13320 l_yields_rec.pre_tax_irr := l_iir_temp;
13321 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13322 'After Calculating the NON-Subsidized IRR ' || round(l_yields_rec.pre_tax_irr, 4) );
13323 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13324 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13325 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13326 RAISE OKL_API.G_EXCEPTION_ERROR;
13327 END IF;
13328 IF (l_disp_sf_msg) THEN
13329 OKL_API.SET_MESSAGE (
13330 p_app_name => G_APP_NAME,
13331 p_msg_name => 'OKL_UNSUB_RATES_SF');
13332 END IF;
13333 ELSIF quote_rec.pricing_method = 'SI' OR
13334 quote_rec.pricing_method = 'SD' OR
13335 quote_rec.pricing_method = 'SS'
13336 THEN
13337 -- End of IF p_pricing_method = 'SF' and begin SI/SD/SS
13338 l_lq_pricing_parameter_rec.financed_amount := 0;
13339 l_lq_pricing_parameter_rec.down_payment := 0;
13340 l_lq_pricing_parameter_rec.trade_in := 0;
13341 l_lq_pricing_parameter_rec.subsidy := 0;
13342 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
13343 pp_index := 1;
13344 lnoa_index := 1;
13345 res_index := 1;
13346 l_non_overiding_assets_tbl.DELETE;
13347 -- Loop through all the Assets !
13348 FOR assets_rec IN assets_csr(p_qte_id)
13349 LOOP
13350 If assets_rec.fee_type <> 'FREE_FORM1'
13351 THEN
13352 l_overridden := TRUE;
13353 ELSE
13354 l_overridden := is_asset_overriding(
13355 p_qte_id => p_qte_id,
13356 p_ast_id => assets_rec.ast_id,
13357 p_lq_line_level_pricing => quote_rec.line_level_pricing,
13358 p_lq_srt_id => quote_rec.rate_template_id,
13359 p_ast_srt_id => assets_rec.rate_template_id,
13360 p_lq_struct_pricing => quote_rec.structured_pricing,
13361 p_ast_struct_pricing => assets_rec.structured_pricing,
13362 p_lq_arrears_yn => quote_rec.target_arrears,
13363 p_ast_arrears_yn => assets_rec.target_arrears,
13364 x_return_status => l_return_status);
13365 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13366 'PM = SS/SD/ST | After is_asset_overriding | l_return_status = ' ||
13367 l_return_status || ' | Asset ID = ' || assets_rec.ast_id );
13368 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13369 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13370 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13371 RAISE OKL_API.G_EXCEPTION_ERROR;
13372 END IF;
13373 END IF;
13374 IF l_overridden = FALSE
13375 THEN
13376 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13377 'This configuration line follows payment defined @ LQ level !!' );
13378 -- Storing the non overriding assets for future
13379 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
13380 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
13381 astid => assets_rec.ast_id)
13382 LOOP
13383 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE AND
13384 quote_rec.pricing_method <> 'SD'
13385 THEN
13386 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
13387 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE AND
13388 quote_rec.pricing_method <> 'SS'
13389 THEN
13390 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
13391 THEN
13392 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
13393 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
13394 CLOSE subsidy_adj_csr;
13395 -- Bug 7429169: Start
13396 -- l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
13397 IF l_noa_pp_tbl.EXISTS(lnoa_index)
13398 THEN
13399 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(subsidy_adj_rec.amount,0);
13400 ELSE
13401 l_noa_pp_tbl(lnoa_index).subsidy := NVL(subsidy_adj_rec.amount,0);
13402 END IF;
13403 -- Bug 7429169: End
13404 ELSE
13405 -- l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
13406 IF l_noa_pp_tbl.EXISTS(lnoa_index)
13407 THEN
13408 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(asset_cost_adj_rec.value,0);
13409 ELSE
13410 l_noa_pp_tbl(lnoa_index).subsidy := NVL(asset_cost_adj_rec.value,0);
13411 END IF;
13412 -- Bug 7429169: End
13413 END IF;
13414 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE AND
13415 quote_rec.pricing_method <> 'SI'
13416 THEN
13417 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0 );
13418 END IF;
13419 END LOOP;
13420 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
13421 LOOP
13422 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec,0);
13423 -- Calculate the Capitalized Fee for this Asset
13424 FOR ct_rec IN get_asset_cap_fee_amt(
13425 p_source_type => 'ASSET',
13426 p_source_id => assets_rec.ast_id,
13427 p_related_line_type => 'CAPITALIZED')
13428 LOOP
13429 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
13430 END LOOP;
13431 l_lq_residual_inflows(res_index).line_number := res_index;
13432 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
13433 THEN
13434 -- EOT = OEC * EOT %age /100;
13435 l_lq_residual_inflows(res_index).cf_amount :=
13436 nvl((asset_adj_rec.end_of_term_value/100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0);
13437 ELSE
13438 -- EOT is an amount so directly store it ..
13439 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
13440 END IF;
13441 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
13442 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
13443 l_lq_residual_inflows(res_index).is_stub := 'N';
13444 l_lq_residual_inflows(res_index).is_arrears := 'Y';
13445 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
13446 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
13447 -- Store the Asset Residuals in the corresponding NOA Assets table
13448 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
13449 -- Increment the res_index
13450 res_index := res_index + 1;
13451 END LOOP;
13452 -- Bug 6669429 : Start
13453 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
13454 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
13455 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
13456 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
13457 l_lq_pricing_parameter_rec.cap_fee_amount := l_lq_pricing_parameter_rec.cap_fee_amount + nvl(l_noa_pp_tbl(lnoa_index).cap_fee_amount,0);
13458 -- Bug 6669429 : End
13459 -- Increment the lnoa_index
13460 lnoa_index := lnoa_index + 1;
13461 ELSE -- IF l_overridden = FALSE
13462 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
13463 IF assets_rec.fee_type = 'FREE_FORM1'
13464 THEN
13465 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13466 'Asset with ID ' || assets_rec.ast_id || ' is overriding the payment structure defined @ LQ level !!' );
13467 price_standard_quote_asset(
13468 x_return_status => l_return_status,
13469 x_msg_count => x_msg_count,
13470 x_msg_data => x_msg_data,
13471 p_api_version => p_api_version,
13472 p_init_msg_list => p_init_msg_list,
13473 p_qte_id => p_qte_id,
13474 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
13475 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
13476 p_target_rate => NULL,
13477 p_line_type => assets_rec.fee_type,
13478 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
13479 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13480 'Pricing method = ' || quote_rec.pricing_method || ' | After price_standard_quote_asset l_return_status = ' || l_return_status ||
13481 ' | assets_rec.ast_id = ' || assets_rec.ast_id );
13482 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13483 RAISE okl_api.g_exception_unexpected_error;
13484 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13485 RAISE okl_api.g_exception_error;
13486 END IF;
13487 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
13488 -- Increment the pp_index
13489 pp_index := pp_index + 1;
13490 END IF;
13491 END IF;
13492 END LOOP; -- Loop on the Assets csr
13493 -- Now Solve for Subsidy/Trade in/Down Payment at the Lease Quote Level
13494 -- using amortization logic for assets which doesnot override the payment structure
13495 -- at lease quote level !
13496 IF l_non_overiding_assets_tbl.COUNT > 0
13497 THEN
13498 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
13499 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
13500 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
13501 -- Step 1: Solve for DownPayment/Subsidy/Trade-in @ Lease Quote Level
13502 -- Using payment structures defined @ LQ !
13503 compute_iir(
13504 p_api_version => p_api_version,
13505 p_init_msg_list => p_init_msg_list,
13506 x_return_status => l_return_status,
13507 x_msg_count => x_msg_count,
13508 x_msg_data => x_msg_data,
13509 p_start_date => quote_rec.expected_start_date,
13510 p_day_count_method => l_day_count_method,
13511 p_pricing_method => quote_rec.pricing_method,
13512 p_initial_guess => l_initial_guess,
13513 px_pricing_parameter_rec => l_lq_pricing_parameter_rec,
13514 px_iir => x_iir,
13515 x_payment => x_payment);
13516 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13517 'Pricing Method =' || quote_rec.pricing_method || ' | 1/ After compute_iir at LQ level l_return_status = ' || l_return_status );
13518 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13519 'Financed Amount | Down Payment | Subsidy Amount | Trade In Amount | CAP Fee Amt ' );
13520 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13521 round(l_lq_pricing_parameter_rec.financed_amount, 4 ) || ' | ' || round(l_lq_pricing_parameter_rec.down_payment, 4)
13522 || ' | ' || round(l_lq_pricing_parameter_rec.subsidy, 4) || ' | ' || round(l_lq_pricing_parameter_rec.trade_in, 4)
13523 || ' | ' || round(l_lq_pricing_parameter_rec.cap_fee_amount, 4));
13524 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13525 RAISE okl_api.g_exception_unexpected_error;
13526 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13527 RAISE okl_api.g_exception_error;
13528 END IF;
13529 l_an_ass_follow_lq := TRUE; -- Store the flag
13530 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
13531 -- By now, we have solved for the Down Payment/Subsidy/Tradein @ LQ Level !
13532 -- Now calculate the IIR at the LQ Level. Here, we have to just consider those
13533 -- assets only which follow the payment structured defined at LQ level !
13534 -- l_lq_pricing_parameter_rec will be now updated with the solved
13535 -- DownPayment/Subsidy/Trade In
13536 -- Calculating the IIR at LQ level ( including only assets which follows the payment structure
13537 -- defined at the asset, 'coz there can be multiple paymnet levels in the payment structure !!
13538 l_lq_pp_noa_dts := l_lq_pricing_parameter_rec;
13539 -- Proportionate the Solved Down Payment/Subsidy/TradeIn Amount now
13540 -- based on the Asset OEC ! -- TBD
13541 l_tot_noa_oec := 0;
13542 FOR t_index IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
13543 LOOP
13544 l_tot_noa_oec := l_tot_noa_oec + nvl( l_noa_pp_tbl(t_index).financed_amount, 0 );
13545 END LOOP;
13546 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13547 'SUM( OEC ) of non-overriding Assets ' || round( l_tot_noa_oec , 4 ));
13548 FOR t_index IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
13549 LOOP
13550 ----------------------------------------------------------------------------------
13551 -- Create an Asset Cost Adjustment for the Solved Down Payment/Trade-in/Subsidy !!
13552 ----------------------------------------------------------------------------------
13553 l_ass_adj_tbl.DELETE;
13554 l_ass_adj_tbl(1).parent_object_code := 'ASSET';
13555 l_ass_adj_tbl(1).parent_object_id := l_non_overiding_assets_tbl(t_index); -- Asset ID
13556 l_ass_adj_tbl(1).basis := 'FIXED';
13557 IF quote_rec.pricing_method = 'SI'
13558 THEN
13559 l_ass_adj_tbl(1).adjustment_source_type := 'TRADEIN';
13560 l_ass_adj_tbl(1).VALUE := l_lq_pp_noa_dts.trade_in *
13561 l_noa_pp_tbl(t_index).financed_amount/ l_tot_noa_oec;
13562 l_noa_pp_tbl(t_index).trade_in := l_ass_adj_tbl(1).VALUE;
13563 l_adj_type := 'Trade-in';
13564 ELSIF quote_rec.pricing_method = 'SD'
13565 THEN
13566 l_ass_adj_tbl(1).adjustment_source_type := 'DOWN_PAYMENT';
13567 l_ass_adj_tbl(1).VALUE := l_lq_pp_noa_dts.down_payment *
13568 l_noa_pp_tbl(t_index).financed_amount/ l_tot_noa_oec;
13569 l_noa_pp_tbl(t_index).down_payment := l_ass_adj_tbl(1).VALUE;
13570 l_adj_type := 'Down Payment';
13571 ELSIF quote_rec.pricing_method = 'SS'
13572 THEN
13573 l_ass_adj_tbl(1).adjustment_source_type := 'SUBSIDY';
13574 l_ass_adj_tbl(1).VALUE := l_lq_pp_noa_dts.subsidy *
13575 l_noa_pp_tbl(t_index).financed_amount/ l_tot_noa_oec;
13576 l_noa_pp_tbl(t_index).subsidy := l_ass_adj_tbl(1).VALUE;
13577 l_adj_type := 'Subsidy';
13578 END IF;
13579 IF l_ass_adj_tbl(1).VALUE < 0
13580 THEN
13581 OKL_API.SET_MESSAGE (
13582 p_app_name => G_APP_NAME,
13583 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
13584 p_token1 => 'TYPE',
13585 p_token1_value => l_adj_type,
13586 p_token2 => 'AMOUNT',
13587 p_token2_value => round(l_ass_adj_tbl(1).VALUE,2));
13588 RAISE okl_api.g_exception_error;
13589 END IF;
13590 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13591 'Asset ID | Cost | Down Payment | Subsidy | Trade In ' );
13592 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13593 l_ass_adj_tbl(1).parent_object_id || ' | ' ||
13594 round( l_noa_pp_tbl(t_index).financed_amount , 4 ) || ' | ' ||
13595 round( l_noa_pp_tbl(t_index).down_payment , 4 ) || ' | ' ||
13596 round( l_noa_pp_tbl(t_index).subsidy , 4 ) || ' | ' ||
13597 round( l_noa_pp_tbl(t_index).trade_in , 4 ) );
13598 -- Create/Update the Solved Financial Adjustment
13599 okl_lease_quote_asset_pvt.create_adjustment(
13600 p_api_version => p_api_version,
13601 p_init_msg_list => p_init_msg_list,
13602 p_transaction_control => FND_API.G_TRUE,
13603 p_asset_adj_tbl => l_ass_adj_tbl,
13604 x_return_status => l_return_status,
13605 x_msg_count => x_msg_count,
13606 x_msg_data => x_msg_data );
13607 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13608 'After okl_lease_quote.asset.create_adjustment ' || l_return_status);
13609 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13610 RAISE okl_api.g_exception_unexpected_error;
13611 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13612 RAISE okl_api.g_exception_error;
13613 END IF;
13614 END LOOP; -- Loop on the Non-overriding Assets
13615 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
13616 /* Commented. Bug 7440199: Quote Streams ER: RGOOTY: Start
13617 -- pp_index is an post-assigned incremented index!
13618 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
13619 pp_index := pp_index + 1;*/
13620 -- Pricing has to create the Cash Flow levels when the Pricing option is SRT @ LQ level.
13621 -- So, check whether the Cash flows have been already created by the Pricing or not
13622 -- If already created, then delete and create new else, create new cash flow levels.
13623 IF quote_rec.rate_template_id IS NOT NULL
13624 THEN
13625 IF l_cfo_exists_at_lq = 'YES'
13626 THEN
13627 -- Delete the Cash Flow Levels which may be already created by Pricing ..
13628 okl_lease_quote_cashflow_pvt.delete_cashflows (
13629 p_api_version => p_api_version,
13630 p_init_msg_list => p_init_msg_list,
13631 p_transaction_control => NULL,
13632 p_source_object_code => 'LEASE_QUOTE',
13633 p_source_object_id => p_qte_id,
13634 x_return_status => l_return_status,
13635 x_msg_count => x_msg_count,
13636 x_msg_data => x_msg_data);
13637 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13638 ' ----- "SD/SS/ST" ---- After deleting the Cash flows @ LQ Level ' || l_return_status );
13639 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13640 RAISE okl_api.g_exception_unexpected_error;
13641 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13642 RAISE okl_api.g_exception_error;
13643 END IF;
13644 END IF;
13645 FOR cfl_index IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
13646 LOOP
13647 l_lq_payment_level_tbl(cfl_index).record_mode := 'CREATE';
13648 END LOOP;
13649 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13650 'Before creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
13651 || 'Status_code ' || l_lq_payment_header_rec.status_code );
13652 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
13653 p_api_version => p_api_version,
13654 p_init_msg_list => p_init_msg_list,
13655 p_transaction_control => NULL,
13656 p_cashflow_header_rec => l_lq_payment_header_rec,
13657 p_cashflow_level_tbl => l_lq_payment_level_tbl,
13658 x_return_status => l_return_status,
13659 x_msg_count => x_msg_count,
13660 x_msg_data => x_msg_data);
13661 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13662 'After update_cashflow call ' || l_Return_Status );
13663 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13664 'After creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
13665 || 'Status_code ' || l_lq_payment_header_rec.status_code );
13666 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13667 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13668 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13669 RAISE OKL_API.G_EXCEPTION_ERROR;
13670 END IF;
13671 END IF; -- Check if Pricing Option = SRT
13672 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
13673 -- pp_index is an post-assigned incremented index!
13674 l_lq_pricing_parameter_rec.cfo_id := l_lq_payment_header_rec.cashflow_object_id;
13675 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
13676 pp_index := pp_index + 1;
13677 -- Bug 7440199: Quote Streams ER: RGOOTY: End
13678 END IF; -- IF noa count > 0
13679 -- Fetch the ROLLOVER and Financed Fees Information
13680 FOR assets_rec IN assets_csr(p_qte_id)
13681 LOOP
13682 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED' )
13683 THEN
13684 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13685 ' Pricing for fee type ' || assets_rec.fee_type );
13686 price_standard_quote_asset(
13687 x_return_status => l_return_status,
13688 x_msg_count => x_msg_count,
13689 x_msg_data => x_msg_data,
13690 p_api_version => p_api_version,
13691 p_init_msg_list => p_init_msg_list,
13692 p_qte_id => p_qte_id,
13693 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
13694 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
13695 p_target_rate => NULL,
13696 p_line_type => assets_rec.fee_type,
13697 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
13698 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13699 'Pricing method = ' || quote_rec.pricing_method ||
13700 ' | After price_standard_quote_asset l_return_status = ' || l_return_status ||
13701 ' | assets_rec.ast_id = ' || assets_rec.ast_id );
13702 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13703 RAISE okl_api.g_exception_unexpected_error;
13704 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13705 RAISE okl_api.g_exception_error;
13706 END IF;
13707 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
13708 -- Increment the pp_index
13709 pp_index := pp_index + 1;
13710 END IF;
13711 END LOOP; -- FOR assets_rec IN assets_csr(p_qte_id)
13712 -- Store the Pricing Params for later use
13713 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
13714 ----------------------------------------------------------------------
13715 -- Compute the IIR @ Lease quote level, considering all the Assets !
13716 ----------------------------------------------------------------------
13717 compute_irr(
13718 p_api_version => p_api_version,
13719 p_init_msg_list => p_init_msg_list,
13720 x_return_status => l_return_status,
13721 x_msg_count => x_msg_count,
13722 x_msg_data => x_msg_data,
13723 p_start_date => quote_rec.expected_start_date,
13724 p_day_count_method => l_day_count_method,
13725 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13726 p_pricing_method => 'SY',
13727 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
13728 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
13729 px_irr => x_iir,
13730 x_payment => x_payment);
13731 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13732 'After Calculating the Subsidized IIR ' || round(x_iir, 4) );
13733 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13734 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13735 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13736 RAISE OKL_API.G_EXCEPTION_ERROR;
13737 END IF;
13738 l_subsidized_yields_rec.iir := x_iir;
13739 l_subsidized_yields_rec.bk_yield := x_iir;
13740 -- Fetching the Fees and Service Information for the calculation of the
13741 -- Pre-tax Internal Rate of Return
13742 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
13743 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
13744 LOOP
13745 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
13746 THEN
13747 -- Delete the previous fees cash flows
13748 l_fee_outflow_cfl_tbl.DELETE;
13749 l_fee_inflow_cfl_tbl.DELETE;
13750 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13751 '!!!!!! Handling fee ' || assets_rec.fee_type );
13752 get_lq_fee_cash_flows(
13753 p_api_version => p_api_version,
13754 p_init_msg_list => p_init_msg_list,
13755 x_return_status => l_return_status,
13756 x_msg_count => x_msg_count,
13757 x_msg_data => x_msg_data,
13758 p_fee_type => assets_rec.fee_type,
13759 p_lq_id => p_qte_id,
13760 p_fee_id => assets_rec.fee_id,
13761 x_outflow_caf_rec => l_fee_outflow_caf_rec,
13762 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
13763 x_inflow_caf_rec => l_fee_inflow_caf_rec,
13764 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
13765 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13766 'After get_lq_fee_cash_flows ' || l_return_status );
13767 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13768 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13769 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13770 RAISE OKL_API.G_EXCEPTION_ERROR;
13771 END IF;
13772 -- Based on the outflows/Inflows obtained generate the streams
13773 IF l_fee_outflow_cfl_tbl.COUNT > 0
13774 THEN
13775 l_cash_inflows.DELETE;
13776 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13777 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
13778 gen_so_cf_strms(
13779 p_api_version => p_api_version,
13780 p_init_msg_list => p_init_msg_list,
13781 x_return_status => l_return_status,
13782 x_msg_count => x_msg_count,
13783 x_msg_data => x_msg_data,
13784 p_cash_flow_rec => l_fee_outflow_caf_rec,
13785 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
13786 x_cash_inflow_strms_tbl => l_cash_inflows);
13787 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13788 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13789 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13790 RAISE OKL_API.G_EXCEPTION_ERROR;
13791 END IF;
13792 -- Place the information in the pricing params
13793 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
13794 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
13795 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
13796 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
13797 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
13798 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
13799 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_outflow_caf_rec.cfo_id;
13800 -- Bug 7440199: Quote Streams ER: RGOOTY: End
13801 pp_index := pp_index + 1;
13802 END IF;
13803 -- Based on the outflows/Inflows obtained generate the streams
13804 IF l_fee_inflow_cfl_tbl.COUNT > 0
13805 THEN
13806 l_cash_inflows.DELETE;
13807 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13808 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
13809 gen_so_cf_strms(
13810 p_api_version => p_api_version,
13811 p_init_msg_list => p_init_msg_list,
13812 x_return_status => l_return_status,
13813 x_msg_count => x_msg_count,
13814 x_msg_data => x_msg_data,
13815 p_cash_flow_rec => l_fee_inflow_caf_rec,
13816 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
13817 x_cash_inflow_strms_tbl => l_cash_inflows);
13818 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13819 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13820 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13821 RAISE OKL_API.G_EXCEPTION_ERROR;
13822 END IF;
13823 -- Place the information in the pricing params
13824 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
13825 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
13826 THEN
13827 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
13828 ELSE
13829 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
13830 END IF;
13831 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
13832 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
13833 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
13834 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
13835 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_inflow_caf_rec.cfo_id;
13836 -- Bug 7440199: Quote Streams ER: RGOOTY: End
13837 pp_index := pp_index + 1;
13838 END IF;
13839 END IF; -- IF on Fee_type not in ...
13840 IF assets_rec.fee_type = 'ABSORBED'
13841 THEN
13842 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13843 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
13844 -- Increment the pp_index and store the pricng params
13845 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
13846 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
13847 pp_index := pp_index + 1;
13848 END IF;
13849 END LOOP;
13850 -- Store the Pricing Params for calculation of Non-subsidized IRR
13851 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
13852 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
13853 l_iir_temp := NULL;
13854 l_iir_temp := l_subsidized_yields_rec.pre_tax_irr;
13855 compute_irr(
13856 p_api_version => p_api_version,
13857 p_init_msg_list => p_init_msg_list,
13858 x_return_status => l_return_status,
13859 x_msg_count => x_msg_count,
13860 x_msg_data => x_msg_data,
13861 p_start_date => quote_rec.expected_start_date,
13862 p_day_count_method => l_day_count_method,
13863 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13864 p_pricing_method => 'SY',
13865 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13866 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
13867 -- px_irr => l_subsidized_yields_rec.pre_tax_irr,
13868 px_irr => l_iir_temp,
13869 x_payment => x_payment);
13870 l_subsidized_yields_rec.pre_tax_irr := l_iir_temp;
13871 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13872 'After Calculating the Subsidized IRR ' || round(l_subsidized_yields_rec.pre_tax_irr, 4) );
13873 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13874 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13875 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13876 RAISE OKL_API.G_EXCEPTION_ERROR;
13877 END IF;
13878 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13879 '!!!!!!!!!!! NON-SUBSIDIZIED YIELDS CALCULATION !!!!!!!!!!!' );
13880 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13881 'Removing subsidy from the l_pp_non_sub_iir_tbl ' );
13882 FOR t IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
13883 LOOP
13884 IF l_pp_non_sub_iir_tbl(t).line_type = 'FREE_FORM1'
13885 THEN
13886 l_pp_non_sub_iir_tbl(t).subsidy := 0;
13887 END IF;
13888 END LOOP;
13889 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13890 'Before calculating the IIR ( NON-SUBSIDY ) ' );
13891 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
13892 l_iir_temp := NULL;
13893 l_iir_temp := l_yields_rec.iir;
13894 compute_irr(
13895 p_api_version => p_api_version,
13896 p_init_msg_list => p_init_msg_list,
13897 x_return_status => l_return_status,
13898 x_msg_count => x_msg_count,
13899 x_msg_data => x_msg_data,
13900 p_start_date => quote_rec.expected_start_date,
13901 p_day_count_method => l_day_count_method,
13902 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13903 p_pricing_method => 'SY',
13904 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13905 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
13906 -- px_irr => l_yields_rec.iir,
13907 px_irr => l_iir_temp,
13908 x_payment => x_payment);
13909 l_yields_rec.iir := l_iir_temp;
13910 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13911 'After Calculating the NON-Subsidized IIR ' || round(l_yields_rec.pre_tax_irr, 4) );
13912 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13913 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13914 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13915 RAISE OKL_API.G_EXCEPTION_ERROR;
13916 END IF;
13917 l_yields_rec.bk_yield := l_yields_rec.iir;
13918 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13919 'Removing subsidy from the l_pp_non_sub_irr_tbl ' );
13920 FOR t IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
13921 LOOP
13922 IF l_pp_non_sub_irr_tbl(t).line_type = 'FREE_FORM1'
13923 THEN
13924 l_pp_non_sub_irr_tbl(t).subsidy := 0;
13925 END IF;
13926 END LOOP;
13927 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13928 'Before calculating the IIR ( NON-SUBSIDY ) ' );
13929 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
13930 l_iir_temp := NULL;
13931 l_iir_temp := l_yields_rec.pre_tax_irr;
13932 compute_irr(
13933 p_api_version => p_api_version,
13934 p_init_msg_list => p_init_msg_list,
13935 x_return_status => l_return_status,
13936 x_msg_count => x_msg_count,
13937 x_msg_data => x_msg_data,
13938 p_start_date => quote_rec.expected_start_date,
13939 p_day_count_method => l_day_count_method,
13940 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13941 p_pricing_method => 'SY',
13942 p_initial_guess => l_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13943 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
13944 -- px_irr => l_yields_rec.pre_tax_irr,
13945 px_irr => l_iir_temp,
13946 x_payment => x_payment);
13947 l_yields_rec.pre_tax_irr := l_iir_temp;
13948 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13949 'After Calculating the NON-Subsidized IRR ' || round(l_yields_rec.pre_tax_irr, 4) );
13950 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13951 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13952 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13953 RAISE OKL_API.G_EXCEPTION_ERROR;
13954 END IF;
13955 ELSIF quote_rec.pricing_method = 'TR'
13956 THEN
13957 -- Target for rate, which is IIR !
13958 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
13959 l_lq_pricing_parameter_rec.financed_amount := 0;
13960 l_lq_pricing_parameter_rec.down_payment := 0;
13961 l_lq_pricing_parameter_rec.trade_in := 0;
13962 l_lq_pricing_parameter_rec.subsidy := 0;
13963 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
13964 pp_index := 1;
13965 lnoa_index := 1;
13966 res_index := 1;
13967 l_non_overiding_assets_tbl.DELETE;
13968 -- Loop through the Assets and check price the asset seperately
13969 -- which has overriddent the payment option picked at the Quote Level
13970 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
13971 LOOP
13972 -- Check whether this Asset has overridden the Payment option defined
13973 -- at the quote level !
13974 IF ( assets_rec.fee_type <> 'FREE_FORM1' )
13975 THEN
13976 -- For financed fee/Rollover fee its not yet clear ..but
13977 -- pricing needs to solve the payments for them for sure !
13978 l_overridden := TRUE;
13979 ELSE
13980 -- All assets in TR pricing method follow the pricing option picked at lease quote
13981 l_overridden := FALSE;
13982 END IF;
13983 IF l_overridden = FALSE
13984 THEN
13985 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13986 ' Asset Follows the Payment Structure @ Lease Quote Level ' || assets_rec.asset_number );
13987 -- If asset is not overriding the Payment option defined at the Quote Level ...
13988 -- Store the Asset Id for later use ..
13989 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
13990 -- Fetch the Asset Cost Adjustment Details for each Asset and accumulate them
13991 -- in the lx_pricing_parameter_rec
13992 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
13993 astid => assets_rec.ast_id)
13994 LOOP
13995 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
13996 THEN
13997 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
13998 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
13999 THEN
14000 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
14001 THEN
14002 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
14003 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
14004 CLOSE subsidy_adj_csr;
14005 -- Bug 7429169 : Start
14006 -- l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
14007 IF l_noa_pp_tbl.EXISTS(lnoa_index)
14008 THEN
14009 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(subsidy_adj_rec.amount,0);
14010 ELSE
14011 l_noa_pp_tbl(lnoa_index).subsidy := NVL(subsidy_adj_rec.amount,0);
14012 END IF;
14013 -- Bug 7429169 : End
14014 ELSE
14015 -- Bug 7429169 : Start
14016 -- l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
14017 IF l_noa_pp_tbl.EXISTS(lnoa_index)
14018 THEN
14019 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(asset_cost_adj_rec.value,0);
14020 ELSE
14021 l_noa_pp_tbl(lnoa_index).subsidy := NVL(asset_cost_adj_rec.value,0);
14022 END IF;
14023 -- Bug 7429169 : End
14024 END IF;
14025 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
14026 THEN
14027 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
14028 END IF;
14029 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14030 'After Retrieving the Asset Cost Adjustments ');
14031 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14032 'Down Payment| Trade In | Subsidy ' );
14033 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14034 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' || l_noa_pp_tbl(lnoa_index).trade_in || ' | ' ||
14035 l_noa_pp_tbl(lnoa_index).subsidy );
14036 END LOOP;
14037 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
14038 LOOP
14039 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec,0);
14040 -- Calculate the Capitalized Fee for this Asset
14041 FOR ct_rec IN get_asset_cap_fee_amt(
14042 p_source_type => 'ASSET',
14043 p_source_id => assets_rec.ast_id,
14044 p_related_line_type => 'CAPITALIZED')
14045 LOOP
14046 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
14047 END LOOP;
14048 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14049 'Unit Cost=' || asset_adj_rec.unit_cost || ' No. of Units ' || asset_adj_rec.number_of_units);
14050 l_lq_residual_inflows(res_index).line_number := res_index;
14051 l_lq_residual_inflows(res_index).line_number := res_index;
14052 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
14053 THEN
14054 -- EOT = OEC * EOT %age /100;
14055 l_lq_residual_inflows(res_index).cf_amount :=
14056 nvl((asset_adj_rec.end_of_term_value/100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0);
14057 ELSE
14058 -- EOT is an amount so directly store it ..
14059 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
14060 END IF;
14061 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
14062 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
14063 l_lq_residual_inflows(res_index).is_stub := 'N';
14064 l_lq_residual_inflows(res_index).is_arrears := 'Y';
14065 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
14066 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
14067 -- Store the Asset Residuals in the corresponding NOA Assets table
14068 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
14069 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14070 'Financed Amount = ' || l_noa_pp_tbl(lnoa_index).financed_amount);
14071 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14072 'Storing residual amt ' || l_lq_residual_inflows(res_index).cf_amount );
14073 -- Increment the res_index
14074 res_index := res_index + 1;
14075 END LOOP;
14076 -- Bug 6669429 : Start
14077 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
14078 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
14079 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
14080 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
14081 l_lq_pricing_parameter_rec.cap_fee_amount := l_lq_pricing_parameter_rec.cap_fee_amount + nvl(l_noa_pp_tbl(lnoa_index).cap_fee_amount,0);
14082 -- Bug 6669429 : End
14083 lnoa_index := lnoa_index + 1;
14084 END IF;
14085 END LOOP; -- Loop on the Assets csr
14086 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
14087 -- at the Lease Quote Header Level
14088 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
14089 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
14090 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
14091 l_lq_pricing_parameter_rec.cfo_id := l_lq_cash_flow_rec.cfo_id;
14092 -- Bug 7440199: Quote Streams ER: RGOOTY: End
14093 l_an_ass_follow_lq := TRUE; -- Store the flag
14094 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
14095 -- Extract and preserve the Fees and Other Information and
14096 -- store it in l_pp_lq_fee_srv_tbl
14097 l_pp_non_sub_iir_tbl.DELETE;
14098 l_pp_non_sub_iir_tbl(1) := l_lq_pricing_parameter_rec;
14099 ppfs_index := 1; -- Only one pricing parameter rec would have been built
14100 -- Need to derieve the Payment for the FINANCED/ROLLOVER Fees.
14101 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
14102 LOOP
14103 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
14104 THEN
14105 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14106 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
14107 -- Price the fees ROLLOVER OR FINANCED
14108 price_standard_quote_asset(
14109 x_return_status => l_return_status,
14110 x_msg_count => x_msg_count,
14111 x_msg_data => x_msg_data,
14112 p_api_version => p_api_version,
14113 p_init_msg_list => p_init_msg_list,
14114 p_qte_id => p_qte_id,
14115 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
14116 p_price_at_lq_level => TRUE, -- Use Asset Level Cash flows only !
14117 p_target_rate => quote_rec.target_rate / 100,
14118 p_line_type => assets_rec.fee_type,
14119 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
14120 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14121 'After price_standard_quote_asset ' || l_return_status );
14122 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
14123 RAISE okl_api.g_exception_unexpected_error;
14124 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
14125 RAISE okl_api.g_exception_error;
14126 END IF;
14127 FOR t_in IN l_tmp_pricing_parameter_rec.cash_inflows.FIRST ..
14128 l_tmp_pricing_parameter_rec.cash_inflows.LAST
14129 LOOP
14130 l_tmp_pricing_parameter_rec.cash_inflows(t_in).locked_amt := 'Y';
14131 END LOOP;
14132 -- Store the ROLLOVER/FINANCED Fee PP Rec in the l_pp_non_sub_iir_tbl
14133 ppfs_index := ppfs_index + 1;
14134 l_pp_non_sub_iir_tbl(ppfs_index) := l_tmp_pricing_parameter_rec;
14135 END IF;
14136 END LOOP;
14137 l_pp_non_sub_irr_tbl.DELETE;
14138 l_pp_non_sub_irr_tbl := l_pp_non_sub_iir_tbl;
14139 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
14140 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
14141 LOOP
14142 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
14143 THEN
14144 -- Delete the previous fees cash flows
14145 l_fee_outflow_cfl_tbl.DELETE;
14146 l_fee_inflow_cfl_tbl.DELETE;
14147 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14148 '!!!!!! Handling fee ' || assets_rec.fee_type );
14149 get_lq_fee_cash_flows(
14150 p_api_version => p_api_version,
14151 p_init_msg_list => p_init_msg_list,
14152 x_return_status => l_return_status,
14153 x_msg_count => x_msg_count,
14154 x_msg_data => x_msg_data,
14155 p_fee_type => assets_rec.fee_type,
14156 p_lq_id => p_qte_id,
14157 p_fee_id => assets_rec.fee_id,
14158 x_outflow_caf_rec => l_fee_outflow_caf_rec,
14159 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
14160 x_inflow_caf_rec => l_fee_inflow_caf_rec,
14161 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
14162 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14163 'After get_lq_fee_cash_flows ' || l_return_status );
14164 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14165 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14166 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14167 RAISE OKL_API.G_EXCEPTION_ERROR;
14168 END IF;
14169 -- Based on the outflows/Inflows obtained generate the streams
14170 IF l_fee_outflow_cfl_tbl.COUNT > 0
14171 THEN
14172 l_cash_inflows.DELETE;
14173 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14174 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
14175 IF quote_rec.target_rate_type = 'PIRR'
14176 THEN
14177 FOR t_in IN l_fee_outflow_cfl_tbl.FIRST ..l_fee_outflow_cfl_tbl.LAST
14178 LOOP
14179 l_fee_outflow_cfl_tbl(t_in).rate := quote_rec.target_rate;
14180 END LOOP;
14181 END IF;
14182 gen_so_cf_strms(
14183 p_api_version => p_api_version,
14184 p_init_msg_list => p_init_msg_list,
14185 x_return_status => l_return_status,
14186 x_msg_count => x_msg_count,
14187 x_msg_data => x_msg_data,
14188 p_cash_flow_rec => l_fee_outflow_caf_rec,
14189 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
14190 x_cash_inflow_strms_tbl => l_cash_inflows);
14191 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14192 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14193 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14194 RAISE OKL_API.G_EXCEPTION_ERROR;
14195 END IF;
14196 -- Place the information in the pricing params
14197 ppfs_index := ppfs_index + 1;
14198 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
14199 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
14200 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
14201 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
14202 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
14203 --- Bug 7440199: Quote Streams ER: RGOOTY: Start
14204 l_pp_non_sub_irr_tbl(ppfs_index).cfo_id := l_fee_outflow_caf_rec.cfo_id;
14205 -- Bug 7440199: Quote Streams ER: RGOOTY: End
14206 END IF;
14207 -- Based on the outflows/Inflows obtained generate the streams
14208 IF l_fee_inflow_cfl_tbl.COUNT > 0
14209 THEN
14210 l_cash_inflows.DELETE;
14211 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14212 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
14213 IF quote_rec.target_rate_type = 'PIRR'
14214 THEN
14215 FOR t_in IN l_fee_inflow_cfl_tbl.FIRST ..l_fee_inflow_cfl_tbl.LAST
14216 LOOP
14217 l_fee_inflow_cfl_tbl(t_in).rate := quote_rec.target_rate;
14218 END LOOP;
14219 END IF;
14220 gen_so_cf_strms(
14221 p_api_version => p_api_version,
14222 p_init_msg_list => p_init_msg_list,
14223 x_return_status => l_return_status,
14224 x_msg_count => x_msg_count,
14225 x_msg_data => x_msg_data,
14226 p_cash_flow_rec => l_fee_inflow_caf_rec,
14227 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
14228 x_cash_inflow_strms_tbl => l_cash_inflows);
14229 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14230 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14231 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14232 RAISE OKL_API.G_EXCEPTION_ERROR;
14233 END IF;
14234 -- Place the information in the pricing params
14235 ppfs_index := ppfs_index + 1;
14236 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
14237 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
14238 THEN
14239 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'INCOME';
14240 ELSE
14241 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'SECDEPOSIT';
14242 END IF;
14243 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
14244 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
14245 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
14246 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
14247 l_pp_non_sub_irr_tbl(ppfs_index).cfo_id := l_fee_inflow_caf_rec.cfo_id;
14248 -- Bug 7440199: Quote Streams ER: RGOOTY: End
14249 END IF;
14250 END IF; -- IF on Fee_type not in ...
14251 IF assets_rec.fee_type = 'ABSORBED'
14252 THEN
14253 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14254 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
14255 -- Increment the pp_index and store the pricng params
14256 ppfs_index := ppfs_index + 1;
14257 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
14258 l_pp_non_sub_irr_tbl(ppfs_index).financed_amount := assets_rec.fee_amount;
14259 END IF;
14260 END LOOP;-- FOR LOOP ON Assets_csr
14261 -- Solve for the Payment
14262 IF quote_rec.target_rate_type = 'IIR'
14263 THEN
14264 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14265 'Calling the IIR api to solve the payment amount ' );
14266 -- Now solve the Payment amount calling the compute_irr
14267 compute_irr(
14268 p_api_version => p_api_version,
14269 p_init_msg_list => p_init_msg_list,
14270 x_return_status => l_return_status,
14271 x_msg_count => x_msg_count,
14272 x_msg_data => x_msg_data,
14273 p_start_date => quote_rec.expected_start_date,
14274 p_day_count_method => l_day_count_method,
14275 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14276 p_pricing_method => quote_rec.pricing_method,
14277 p_initial_guess => l_initial_guess, -- Use the IIR derieved prev. as initial guess
14278 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
14279 px_irr => x_iir,
14280 x_payment => x_payment);
14281 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
14282 RAISE okl_api.g_exception_unexpected_error;
14283 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
14284 RAISE okl_api.g_exception_error;
14285 END IF;
14286 -- IIR @ LQ level has already been given by the user itself ..
14287 -- So, we wont be calling the compute_irr api just passing the assets information.
14288 l_subsidized_yields_rec.iir := quote_rec.target_rate / 100;
14289 l_subsidized_yields_rec.bk_yield := l_subsidized_yields_rec.iir;
14290 ELSE
14291 l_iir_temp := NULL;
14292 l_iir_temp := l_subsidized_yields_rec.pre_tax_irr;
14293 compute_irr(
14294 p_api_version => p_api_version,
14295 p_init_msg_list => p_init_msg_list,
14296 x_return_status => l_return_status,
14297 x_msg_count => x_msg_count,
14298 x_msg_data => x_msg_data,
14299 p_start_date => quote_rec.expected_start_date,
14300 p_day_count_method => l_day_count_method,
14301 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14302 p_pricing_method => quote_rec.pricing_method,
14303 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
14304 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
14305 -- px_irr => l_subsidized_yields_rec.pre_tax_irr,
14306 px_irr => l_iir_temp,
14307 x_payment => x_payment);
14308
14309 l_subsidized_yields_rec.pre_tax_irr := l_iir_temp;
14310 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14311 quote_rec.pricing_method || ': FINAL: After compute_irr ' || l_return_status );
14312 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14313 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14314 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14315 RAISE OKL_API.G_EXCEPTION_ERROR;
14316 END IF;
14317 l_subsidized_yields_rec.pre_tax_irr := quote_rec.target_rate / 100;
14318 END IF;
14319 IF x_payment < 0
14320 THEN
14321 OKL_API.SET_MESSAGE (
14322 p_app_name => G_APP_NAME,
14323 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
14324 p_token1 => 'TYPE',
14325 p_token1_value => 'Payment',
14326 p_token2 => 'AMOUNT',
14327 p_token2_value => round(x_payment,2) );
14328 RAISE okl_api.g_exception_error;
14329 END IF;
14330 -- Store the Calculated Payment amount back in the quote Header
14331 l_lease_qte_rec.target_amount := x_payment;
14332 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14333 'SOLVED TARGET AMOUNT ' || round(l_lease_qte_rec.target_amount,4) );
14334 -- Pricing need to create CFO, CFH, CFL @ Lease Quote level storing this
14335 -- targetted Amount
14336 -- When the pricing method is Target Rate, pricing will create cash flows with
14337 -- only one cash flow level always, which is a regular payment. Hence, updating the CFL
14338 -- with the solved amount.
14339 FOR t_in IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
14340 LOOP
14341 l_lq_payment_level_tbl(t_in).periodic_amount := x_payment;
14342 END LOOP;
14343 IF l_cfo_exists_at_lq = 'YES'
14344 THEN
14345 -- Update the CFL Table
14346 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14347 'Before OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow l_lq_payment_header_rec '
14348 || l_lq_payment_header_rec.stream_type_id
14349 || ' status_code ' || l_lq_payment_header_rec.status_code );
14350 OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow (
14351 p_api_version => G_API_VERSION,
14352 p_init_msg_list => p_init_msg_list,
14353 p_transaction_control => G_FALSE,
14354 p_cashflow_header_rec => l_lq_payment_header_rec,
14355 p_cashflow_level_tbl => l_lq_payment_level_tbl,
14356 x_return_status => l_return_status,
14357 x_msg_count => x_msg_count,
14358 x_msg_data => x_msg_data);
14359 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14360 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow ' || l_return_status );
14361 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14362 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow l_lq_payment_header_rec '
14363 || l_lq_payment_header_rec.stream_type_id
14364 || ' status_code ' || l_lq_payment_header_rec.status_code );
14365 IF l_return_status = G_RET_STS_UNEXP_ERROR THEN
14366 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14367 ELSIF l_return_status = G_RET_STS_ERROR THEN
14368 RAISE OKL_API.G_EXCEPTION_ERROR;
14369 END IF;
14370 ELSE
14371 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14372 'Before OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow l_lq_payment_header_rec '
14373 || l_lq_payment_header_rec.stream_type_id
14374 || ' status_code ' || l_lq_payment_header_rec.status_code );
14375 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow (
14376 p_api_version => p_api_version,
14377 p_init_msg_list => p_init_msg_list,
14378 p_transaction_control => G_FALSE,
14379 p_cashflow_header_rec => l_lq_payment_header_rec,
14380 p_cashflow_level_tbl => l_lq_payment_level_tbl,
14381 x_return_status => l_return_status,
14382 x_msg_count => x_msg_count,
14383 x_msg_data => x_msg_data);
14384 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14385 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow ' || l_return_status );
14386 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14387 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow l_lq_payment_header_rec '
14388 || l_lq_payment_header_rec.stream_type_id
14389 || ' status_code ' || l_lq_payment_header_rec.status_code );
14390 IF l_return_status = G_RET_STS_UNEXP_ERROR THEN
14391 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14392 ELSIF l_return_status = G_RET_STS_ERROR THEN
14393 RAISE OKL_API.G_EXCEPTION_ERROR;
14394 END IF;
14395 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
14396 l_pp_non_sub_irr_tbl(1).cfo_id := l_lq_payment_header_rec.cashflow_object_id;
14397 -- Bug 7440199: Quote Streams ER: RGOOTY: End
14398 END IF;
14399 -- Update pmnt. amount in l_pp_non_sub_iir_tbl(1).cash_inflows and l_pp_non_sub_irr_tbl(1).cash_inflows
14400 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14401 '***** Updating the stream elements with the solved amount *****');
14402 FOR t IN l_pp_non_sub_iir_tbl(1).cash_inflows.FIRST ..
14403 l_pp_non_sub_iir_tbl(1).cash_inflows.LAST
14404 LOOP
14405 -- Update the Cash Inflow Streams for the FREE_FORM1 line !
14406 l_pp_non_sub_iir_tbl(1).cash_inflows(t).cf_amount := x_payment;
14407 l_pp_non_sub_irr_tbl(1).cash_inflows(t).cf_amount := x_payment;
14408 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14409 l_pp_non_sub_iir_tbl(1).cash_inflows(t).cf_date || ' | ' ||
14410 l_pp_non_sub_iir_tbl(1).cash_inflows(t).cf_amount );
14411 END LOOP;
14412 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14413 'Updated the Payment amount back in the Cash Inflows ');
14414 -- Need to solve for the IIR if Target_Rate is PIRR else Solve for IRR if
14415 -- target rate type is IIR
14416 IF quote_rec.target_rate_type = 'IIR'
14417 THEN
14418 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14419 '******** Solving for the Subsidized IRR ********** ' );
14420 l_iir_temp := NULL;
14421 l_iir_temp := l_subsidized_yields_rec.pre_tax_irr;
14422 compute_irr(
14423 p_api_version => p_api_version,
14424 p_init_msg_list => p_init_msg_list,
14425 x_return_status => l_return_status,
14426 x_msg_count => x_msg_count,
14427 x_msg_data => x_msg_data,
14428 p_start_date => quote_rec.expected_start_date,
14429 p_day_count_method => l_day_count_method,
14430 p_currency_code => l_currency,
14431 p_pricing_method => 'SY',
14432 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
14433 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
14434 -- px_irr => l_subsidized_yields_rec.pre_tax_irr,
14435 px_irr => l_iir_temp,
14436 x_payment => x_payment);
14437 l_subsidized_yields_rec.pre_tax_irr := l_iir_temp;
14438 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14439 quote_rec.pricing_method || ': FINAL: After compute_irr ' || l_return_status );
14440 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14441 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14442 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14443 RAISE OKL_API.G_EXCEPTION_ERROR;
14444 END IF;
14445 ELSE
14446 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14447 '******** Solving for the Subsidized IIR ********** ' );
14448 -- Now solve the Payment amount calling the compute_iir
14449 compute_irr(
14450 p_api_version => p_api_version,
14451 p_init_msg_list => p_init_msg_list,
14452 x_return_status => l_return_status,
14453 x_msg_count => x_msg_count,
14454 x_msg_data => x_msg_data,
14455 p_start_date => quote_rec.expected_start_date,
14456 p_day_count_method => l_day_count_method,
14457 p_currency_code => l_currency,
14458 p_pricing_method => 'SY',
14459 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
14460 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
14461 px_irr => x_iir,
14462 x_payment => x_payment);
14463 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
14464 RAISE okl_api.g_exception_unexpected_error;
14465 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
14466 RAISE okl_api.g_exception_error;
14467 END IF;
14468 -- IIR @ LQ level has already been given by the user itself ..
14469 -- So, we wont be calling the compute_irr api just passing the assets information.
14470 l_subsidized_yields_rec.iir := x_iir;
14471 l_subsidized_yields_rec.bk_yield := x_iir;
14472 END IF;
14473 -- Solve for the Non-Subsidized Yields now
14474 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14475 '!!!!!!!!!!!!! SOLVING FOR NON-SUBSIDIZED YIELDS NOW !!!!!!!!!!!!!!!!! ' );
14476 -- Loop through the l_pp_non_sub_iir_tbl table and make the Subsidy Amount to zero !
14477 FOR ny IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
14478 LOOP
14479 -- line_type, subsidy
14480 l_pp_non_sub_iir_tbl(ny).subsidy := 0;
14481 END LOOP;
14482 l_iir_temp := NULL;
14483 l_iir_temp := l_yields_rec.iir;
14484 compute_irr(
14485 p_api_version => p_api_version,
14486 p_init_msg_list => p_init_msg_list,
14487 x_return_status => l_return_status,
14488 x_msg_count => x_msg_count,
14489 x_msg_data => x_msg_data,
14490 p_start_date => quote_rec.expected_start_date,
14491 p_day_count_method => l_day_count_method,
14492 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14493 p_pricing_method => 'SY',
14494 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
14495 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
14496 -- px_irr => l_yields_rec.iir,
14497 px_irr => l_iir_temp,
14498 x_payment => x_payment);
14499 l_yields_rec.iir := l_iir_temp;
14500 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14501 '1/ After Computation of IIR (NON-SUBSIDIZED) ' || l_return_status );
14502 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14503 'SOLVED FOR IIR (NON-SUBSIDY)' || l_yields_rec.iir );
14504 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14505 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14506 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14507 RAISE OKL_API.G_EXCEPTION_ERROR;
14508 END IF;
14509 -- Store the IIR as the Booking Yield
14510 l_yields_rec.bk_yield := l_yields_rec.iir;
14511 -- Loop through the l_pp_non_sub_iir_tbl table and make the Subsidy Amount to zero !
14512 FOR ny IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
14513 LOOP
14514 -- line_type, subsidy
14515 l_pp_non_sub_irr_tbl(ny).subsidy := 0;
14516 END LOOP;
14517 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
14518 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14519 '1/ Before Computation of IRR @ LQ Level ' );
14520 l_iir_temp := NULL;
14521 l_iir_temp := l_yields_rec.pre_tax_irr;
14522 compute_irr(
14523 p_api_version => p_api_version,
14524 p_init_msg_list => p_init_msg_list,
14525 x_return_status => l_return_status,
14526 x_msg_count => x_msg_count,
14527 x_msg_data => x_msg_data,
14528 p_start_date => quote_rec.expected_start_date,
14529 p_day_count_method => l_day_count_method,
14530 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14531 p_pricing_method => 'SY',
14532 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
14533 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
14534 -- px_irr => l_yields_rec.pre_tax_irr,
14535 px_irr => l_iir_temp,
14536 x_payment => x_payment);
14537 l_yields_rec.pre_tax_irr := l_iir_temp;
14538 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14539 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
14540 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14541 'SOLVED FOR IRR (NON-SUBSIDY)' || l_yields_rec.pre_tax_irr );
14542 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14543 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14544 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14545 RAISE OKL_API.G_EXCEPTION_ERROR;
14546 END IF;
14547 ELSIF quote_rec.pricing_method = 'RC'
14548 THEN
14549 -- Fetch the SGT Day convention to be used
14550 get_lq_sgt_day_convention(
14551 p_api_version => p_api_version,
14552 p_init_msg_list => p_init_msg_list,
14553 x_return_status => l_return_status,
14554 x_msg_count => x_msg_count,
14555 x_msg_data => x_msg_data,
14556 p_lq_id => p_qte_id,
14557 x_days_in_month => l_days_in_month,
14558 x_days_in_year => l_days_in_year);
14559 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14560 ': After Fetching the Day convention from the SGT - RC ' );
14561 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14562 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14563 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14564 RAISE OKL_API.G_EXCEPTION_ERROR;
14565 END IF;
14566 -- Get the Day count method for passing into the compute_irr api version.
14567 get_day_count_method(
14568 p_days_in_month => l_days_in_month,
14569 p_days_in_year => l_days_in_year,
14570 x_day_count_method => l_day_count_method,
14571 x_return_status => l_return_status );
14572 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14573 'Return Status | l_days_in_month | l_days_in_year | l_day_count_method ' );
14574 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14575 l_return_status || ' | ' || l_days_in_month || ' | ' ||
14576 l_days_in_year || ' | ' || l_day_count_method );
14577 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14578 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14579 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14580 --Bug 5884825 PAGARG start
14581 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
14582 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
14583 p_token1 => 'PRODUCT_NAME',
14584 p_token1_value => l_product_name);
14585 --Bug 5884825 PAGARG end
14586 RAISE OKL_API.G_EXCEPTION_ERROR;
14587 END IF;
14588 pp_index := 1;
14589 -- Loop through each configuration line and price it seperately ...
14590 FOR assets_rec IN assets_csr(p_qte_id)
14591 LOOP
14592 IF assets_rec.fee_type = 'FREE_FORM1'
14593 THEN
14594 -- For Rate Card Pricing the price_standard_quote_asset api will
14595 -- a/ Create Cash flows for each configuration line
14596 -- Checks whether to pick the RC from Header of configuration level itself.
14597 -- b/ builds and return the pricing parameter record
14598 price_standard_quote_asset(
14599 x_return_status => l_return_status,
14600 x_msg_count => x_msg_count,
14601 x_msg_data => x_msg_data,
14602 p_api_version => p_api_version,
14603 p_init_msg_list => p_init_msg_list,
14604 p_qte_id => p_qte_id,
14605 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
14606 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
14607 p_target_rate => NULL,
14608 p_line_type => assets_rec.fee_type,
14609 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
14610 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14611 'After price_standard_quote_asset ' || l_return_status );
14612 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
14613 RAISE okl_api.g_exception_unexpected_error;
14614 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
14615 RAISE okl_api.g_exception_error;
14616 END IF;
14617 -- Store the Pricing Parameter for solving yields at the entire quote level
14618 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
14619 -- Increment the pp_index
14620 pp_index := pp_index + 1;
14621 END IF;
14622 END LOOP; -- Loop on the Assets csr
14623 -- Loop through ROLLOVER and Financed Fees, and fetch the pricng parameter rec. structure
14624 FOR assets_rec IN assets_csr(p_qte_id)
14625 LOOP
14626 IF assets_rec.fee_type in ('ROLLOVER', 'FINANCED')
14627 THEN
14628 -- For Rate Card Pricing the price_standard_quote_asset api will
14629 -- a/ Create Cash flows for each configuration line
14630 -- Checks whether to pick the RC from Header of configuration level itself.
14631 -- b/ builds and return the pricing parameter record
14632 price_standard_quote_asset(
14633 x_return_status => l_return_status,
14634 x_msg_count => x_msg_count,
14635 x_msg_data => x_msg_data,
14636 p_api_version => p_api_version,
14637 p_init_msg_list => p_init_msg_list,
14638 p_qte_id => p_qte_id,
14639 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
14640 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
14641 p_target_rate => NULL,
14642 p_line_type => assets_rec.fee_type,
14643 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
14644 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14645 'After price_standard_quote_asset ' || l_return_status );
14646 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
14647 RAISE okl_api.g_exception_unexpected_error;
14648 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
14649 RAISE okl_api.g_exception_error;
14650 END IF;
14651 -- Store the Pricing Parameter for solving yields at the entire quote level
14652 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
14653 -- Increment the pp_index
14654 pp_index := pp_index + 1;
14655 END IF;
14656 END LOOP; -- Loop on the Assets csr
14657 -- Store the Pricing Param Table for calculation of the Non-Subsidized Yields
14658 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
14659 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14660 'Before calling irr for iir at quote level ' || l_return_status );
14661 -- Compute IIR @ Lease Quote Level.
14662 compute_irr(
14663 p_api_version => p_api_version,
14664 p_init_msg_list => p_init_msg_list,
14665 x_return_status => l_return_status,
14666 x_msg_count => x_msg_count,
14667 x_msg_data => x_msg_data,
14668 p_start_date => quote_rec.expected_start_date,
14669 p_day_count_method => l_day_count_method,
14670 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14671 p_pricing_method => 'SY',
14672 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
14673 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
14674 px_irr => x_iir,
14675 x_payment => x_payment);
14676 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14677 '1/ After Computation of IIR @ LQ Level ( SUBSIDY )' || l_return_status );
14678 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14679 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14680 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14681 RAISE OKL_API.G_EXCEPTION_ERROR;
14682 END IF;
14683 l_subsidized_yields_rec.iir := x_iir;
14684 l_subsidized_yields_rec.bk_yield := x_iir;
14685 -- Extract the other fees and other lines information for computation of the IRR
14686 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
14687 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
14688 LOOP
14689 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
14690 THEN
14691 -- Delete the previous fees cash flows
14692 l_fee_outflow_cfl_tbl.DELETE;
14693 l_fee_inflow_cfl_tbl.DELETE;
14694 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14695 '!!!!!! Handling fee ' || assets_rec.fee_type );
14696 get_lq_fee_cash_flows(
14697 p_api_version => p_api_version,
14698 p_init_msg_list => p_init_msg_list,
14699 x_return_status => l_return_status,
14700 x_msg_count => x_msg_count,
14701 x_msg_data => x_msg_data,
14702 p_fee_type => assets_rec.fee_type,
14703 p_lq_id => p_qte_id,
14704 p_fee_id => assets_rec.fee_id,
14705 x_outflow_caf_rec => l_fee_outflow_caf_rec,
14706 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
14707 x_inflow_caf_rec => l_fee_inflow_caf_rec,
14708 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
14709 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14710 'After get_lq_fee_cash_flows ' || l_return_status );
14711 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14712 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14713 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14714 RAISE OKL_API.G_EXCEPTION_ERROR;
14715 END IF;
14716 -- Based on the outflows/Inflows obtained generate the streams
14717 IF l_fee_outflow_cfl_tbl.COUNT > 0
14718 THEN
14719 l_cash_inflows.DELETE;
14720 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14721 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
14722 gen_so_cf_strms(
14723 p_api_version => p_api_version,
14724 p_init_msg_list => p_init_msg_list,
14725 x_return_status => l_return_status,
14726 x_msg_count => x_msg_count,
14727 x_msg_data => x_msg_data,
14728 p_cash_flow_rec => l_fee_outflow_caf_rec,
14729 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
14730 x_cash_inflow_strms_tbl => l_cash_inflows);
14731 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14732 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14733 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14734 RAISE OKL_API.G_EXCEPTION_ERROR;
14735 END IF;
14736 -- Place the information in the pricing params
14737 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
14738 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
14739 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
14740 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
14741 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
14742 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
14743 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_outflow_caf_rec.cfo_id;
14744 -- Bug 7440199: Quote Streams ER: RGOOTY: End
14745 pp_index := pp_index + 1;
14746 END IF;
14747 -- Based on the outflows/Inflows obtained generate the streams
14748 IF l_fee_inflow_cfl_tbl.COUNT > 0
14749 THEN
14750 l_cash_inflows.DELETE;
14751 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14752 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
14753 gen_so_cf_strms(
14754 p_api_version => p_api_version,
14755 p_init_msg_list => p_init_msg_list,
14756 x_return_status => l_return_status,
14757 x_msg_count => x_msg_count,
14758 x_msg_data => x_msg_data,
14759 p_cash_flow_rec => l_fee_inflow_caf_rec,
14760 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
14761 x_cash_inflow_strms_tbl => l_cash_inflows);
14762 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14763 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14764 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14765 RAISE OKL_API.G_EXCEPTION_ERROR;
14766 END IF;
14767 -- Place the information in the pricing params
14768 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
14769 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
14770 THEN
14771 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
14772 ELSE
14773 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
14774 END IF;
14775 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
14776 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
14777 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
14778 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
14779 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_inflow_caf_rec.cfo_id;
14780 -- Bug 7440199: Quote Streams ER: RGOOTY: End
14781 pp_index := pp_index + 1;
14782 END IF;
14783 END IF; -- IF on Fee_type not in ...
14784 IF assets_rec.fee_type = 'ABSORBED'
14785 THEN
14786 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14787 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
14788 -- Increment the pp_index and store the pricng params
14789 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
14790 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
14791 pp_index := pp_index + 1;
14792 END IF;
14793 END LOOP;
14794 -- Store the Pricing Param Table for calculation of the
14795 -- Non-Subsidized Yields
14796 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
14797 l_iir_temp := NULL;
14798 l_iir_temp := l_subsidized_yields_rec.pre_tax_irr;
14799
14800 compute_irr(
14801 p_api_version => p_api_version,
14802 p_init_msg_list => p_init_msg_list,
14803 x_return_status => l_return_status,
14804 x_msg_count => x_msg_count,
14805 x_msg_data => x_msg_data,
14806 p_start_date => quote_rec.expected_start_date,
14807 p_day_count_method => l_day_count_method,
14808 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14809 p_pricing_method => 'SY',
14810 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
14811 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
14812 -- px_irr => l_subsidized_yields_rec.pre_tax_irr,
14813 px_irr => l_iir_temp,
14814 x_payment => x_payment);
14815 l_subsidized_yields_rec.pre_tax_irr := l_iir_temp;
14816 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14817 '1/ After Computation of IRR @ LQ Level ( SUBSIDY )' || l_return_status );
14818 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14819 'SOLVED FOR IRR ' || l_subsidized_yields_rec.pre_tax_irr );
14820 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14821 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14822 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14823 RAISE OKL_API.G_EXCEPTION_ERROR;
14824 END IF;
14825 -- Calculate the Yields without involving the Subsidy Amount
14826 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14827 '1/ CALCULATING THE YEILDS WIHTOUT THE SUBSIDY AMOUNT INVOLVED !! ' );
14828 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
14829 FOR ny IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
14830 LOOP
14831 -- line_type, subsidy
14832 l_pp_non_sub_iir_tbl(ny).subsidy := 0;
14833 END LOOP;
14834 l_iir_temp := NULL;
14835 l_iir_temp := l_yields_rec.iir;
14836 compute_irr(
14837 p_api_version => p_api_version,
14838 p_init_msg_list => p_init_msg_list,
14839 x_return_status => l_return_status,
14840 x_msg_count => x_msg_count,
14841 x_msg_data => x_msg_data,
14842 p_start_date => quote_rec.expected_start_date,
14843 p_day_count_method => l_day_count_method,
14844 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14845 p_pricing_method => 'SY',
14846 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
14847 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
14848 -- px_irr => l_yields_rec.iir,
14849 px_irr => l_iir_temp,
14850 x_payment => x_payment);
14851 l_yields_rec.iir := l_iir_temp;
14852 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14853 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
14854 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14855 'SOLVED FOR IIR (NON-SUBSIDY)' || l_yields_rec.iir );
14856 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14857 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14858 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14859 RAISE OKL_API.G_EXCEPTION_ERROR;
14860 END IF;
14861 -- Store the IIR as the Booking Yield
14862 l_yields_rec.bk_yield := l_yields_rec.iir;
14863
14864 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
14865 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14866 '1/ Before Computation of IRR @ LQ Level ' );
14867 FOR ny IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
14868 LOOP
14869 -- For Asset lines, change the Subsidy Amount to Zero ..
14870 IF l_pp_non_sub_irr_tbl(ny).line_type = 'FREE_FORM1'
14871 THEN
14872 l_pp_non_sub_irr_tbl(ny).subsidy := 0;
14873 END IF;
14874 END LOOP;
14875 l_iir_temp := NULL;
14876 l_iir_temp := l_yields_rec.pre_tax_irr;
14877 compute_irr(
14878 p_api_version => p_api_version,
14879 p_init_msg_list => p_init_msg_list,
14880 x_return_status => l_return_status,
14881 x_msg_count => x_msg_count,
14882 x_msg_data => x_msg_data,
14883 p_start_date => quote_rec.expected_start_date,
14884 p_day_count_method => l_day_count_method,
14885 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14886 p_pricing_method => 'SY',
14887 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
14888 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
14889 -- px_irr => l_yields_rec.pre_tax_irr,
14890 px_irr => l_iir_temp,
14891 x_payment => x_payment);
14892 l_yields_rec.pre_tax_irr := l_iir_temp;
14893 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14894 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
14895 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14896 'SOLVED FOR IRR (NON-SUBSIDY)' || l_yields_rec.pre_tax_irr );
14897 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14898 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14899 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14900 RAISE OKL_API.G_EXCEPTION_ERROR;
14901 END IF;
14902 -- End of Rate Card Pricing
14903 ELSIF quote_rec.pricing_method = 'SY'
14904 THEN
14905 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14906 'SOlving for Yields ' || l_return_status );
14907 l_lq_pricing_parameter_rec.financed_amount := 0;
14908 l_lq_pricing_parameter_rec.down_payment := 0;
14909 l_lq_pricing_parameter_rec.trade_in := 0;
14910 l_lq_pricing_parameter_rec.subsidy := 0;
14911 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
14912 pp_index := 1;
14913 lnoa_index := 1;
14914 res_index := 1;
14915 l_non_overiding_assets_tbl.DELETE;
14916 -- Loop through the Assets and check price the asset seperately
14917 -- which has overriddent the payment option picked at the Quote Level
14918 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
14919 LOOP
14920 -- Check whether this Asset has overridden the Payment option defined
14921 -- at the quote level !
14922 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14923 'loop thru assets ' || assets_rec.asset_number || ' ' || l_return_status );
14924 IF nvl(assets_rec.fee_type, 'XXXX') <> 'FREE_FORM1'
14925 THEN
14926 l_overridden := TRUE;
14927 ELSE
14928 l_overridden := is_asset_overriding(
14929 p_qte_id => p_qte_id,
14930 p_ast_id => assets_rec.ast_id,
14931 p_lq_line_level_pricing => quote_rec.line_level_pricing,
14932 p_lq_srt_id => quote_rec.rate_template_id,
14933 p_ast_srt_id => assets_rec.rate_template_id,
14934 p_lq_struct_pricing => quote_rec.structured_pricing,
14935 p_ast_struct_pricing => assets_rec.structured_pricing,
14936 p_lq_arrears_yn => quote_rec.target_arrears,
14937 p_ast_arrears_yn => assets_rec.target_arrears,
14938 x_return_status => l_return_status);
14939 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14940 'After is_asset_overriding assets_rec.id =' || assets_rec.ast_id || ' | ' ||
14941 ' l_return_status =' || l_return_status );
14942 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14943 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14944 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14945 RAISE OKL_API.G_EXCEPTION_ERROR;
14946 END IF;
14947 END IF;
14948 IF l_overridden = FALSE
14949 THEN
14950 -- If asset is not overriding the Payment option defined at the Quote Level ...
14951 -- Store the Asset Id for later use ..
14952 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
14953 -- Fetch the Asset Cost Adjustment Details for each Asset and accumulate them
14954 -- in the lx_pricing_parameter_rec
14955 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
14956 astid => assets_rec.ast_id)
14957 LOOP
14958 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
14959 THEN
14960 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
14961 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
14962 THEN
14963 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
14964 THEN
14965 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
14966 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
14967 CLOSE subsidy_adj_csr;
14968 -- Bug 7429169 : Start
14969 -- l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
14970 IF l_noa_pp_tbl.EXISTS(lnoa_index)
14971 THEN
14972 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(subsidy_adj_rec.amount,0);
14973 ELSE
14974 l_noa_pp_tbl(lnoa_index).subsidy := NVL(subsidy_adj_rec.amount,0);
14975 END IF; -- djanaswa bug7295753 end
14976 -- Bug 7429169 : End
14977 ELSE
14978 -- Bug 7429169 : Start
14979 -- l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
14980 IF l_noa_pp_tbl.EXISTS(lnoa_index)
14981 THEN
14982 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(asset_cost_adj_rec.value,0);
14983 ELSE
14984 l_noa_pp_tbl(lnoa_index).subsidy := NVL(asset_cost_adj_rec.value,0);
14985 END IF; -- djanaswa bug7295753 end
14986 -- Bug 7429169 : End
14987 END IF;
14988 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
14989 THEN
14990 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
14991 END IF;
14992 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14993 'Down Payment| Trade In | Subsidy ' );
14994 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14995 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' ||
14996 l_noa_pp_tbl(lnoa_index).trade_in || ' | ' ||
14997 l_noa_pp_tbl(lnoa_index).subsidy );
14998 END LOOP;
14999 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15000 'After Retrieving the Asset Cost Adjustments ');
15001 --res_index := 1;
15002 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
15003 LOOP
15004 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec, 0);
15005 -- Calculate the Capitalized Fee for this Asset
15006 FOR ct_rec IN get_asset_cap_fee_amt(
15007 p_source_type => 'ASSET',
15008 p_source_id => assets_rec.ast_id,
15009 p_related_line_type => 'CAPITALIZED')
15010 LOOP
15011 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
15012 END LOOP;
15013 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15014 asset_adj_rec.unit_cost|| ' No. of Units ' || asset_adj_rec.number_of_units);
15015 l_lq_residual_inflows(res_index).line_number := res_index;
15016 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
15017 THEN
15018 -- EOT = OEC * EOT %age /100;
15019 l_lq_residual_inflows(res_index).cf_amount :=
15020 nvl((asset_adj_rec.end_of_term_value/100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0 );
15021 ELSE
15022 -- EOT is an amount so directly store it ..
15023 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
15024 END IF;
15025 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
15026 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
15027 l_lq_residual_inflows(res_index).is_stub := 'N';
15028 l_lq_residual_inflows(res_index).is_arrears := 'Y';
15029 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
15030 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
15031 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15032 'Financed Amount = ' || l_noa_pp_tbl(lnoa_index).financed_amount);
15033 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15034 'Storing residual amt ' || l_lq_residual_inflows(res_index).cf_amount );
15035 -- Store the Asset Residuals in the corresponding NOA Assets table
15036 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
15037 -- Increment the res_index
15038 res_index := res_index + 1;
15039 END LOOP;
15040 -- Bug 6669429 : Start
15041 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
15042 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
15043 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
15044 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
15045 l_lq_pricing_parameter_rec.cap_fee_amount := l_lq_pricing_parameter_rec.cap_fee_amount + nvl(l_noa_pp_tbl(lnoa_index).cap_fee_amount,0);
15046 -- Bug 6669429 : End
15047 lnoa_index := lnoa_index + 1;
15048 ELSE -- IF l_overridden = TRUE
15049 IF assets_rec.fee_type = 'FREE_FORM1'
15050 THEN
15051 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
15052 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15053 ' Calling price_standard_quote_asset ' || 'p_qte_id ' || p_qte_id
15054 || ' | assets_rec.ast_id ' || nvl(assets_rec.ast_id, assets_rec.fee_id) ||
15055 ' | p_price_at_lq_level = FALSE | p_target_rate = NULL' );
15056 price_standard_quote_asset(
15057 x_return_status => l_return_status,
15058 x_msg_count => x_msg_count,
15059 x_msg_data => x_msg_data,
15060 p_api_version => p_api_version,
15061 p_init_msg_list => p_init_msg_list,
15062 p_qte_id => p_qte_id,
15063 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
15064 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
15065 p_target_rate => NULL,
15066 p_line_type => assets_rec.fee_type,
15067 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
15068 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15069 'After price_standard_quote_asset ' || l_return_status );
15070 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
15071 RAISE okl_api.g_exception_unexpected_error;
15072 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
15073 RAISE okl_api.g_exception_error;
15074 END IF;
15075 -- Increment the pp_index
15076 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
15077 pp_index := pp_index + 1;
15078 END IF;
15079 END IF;
15080 END LOOP; -- Loop on the Assets csr
15081 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15082 ' Number of Overriding Lines = ' || l_pricing_parameter_tbl.COUNT || ' | ' ||
15083 ' Number of Non-Overriding Lines = ' || l_non_overiding_assets_tbl.COUNT );
15084 IF l_non_overiding_assets_tbl.COUNT > 0
15085 THEN
15086 -- If there is atleast one asset which follows the Payment Structure
15087 -- defined at Lease Quote Level, then pass the Pricing param table
15088 -- withe the Cash flows information at lease quote level else DON'T !!
15089 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
15090 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
15091 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
15092 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
15093 l_lq_pricing_parameter_rec.cfo_id := l_lq_cash_flow_rec.cfo_id;
15094 -- Bug 7440199: Quote Streams ER: RGOOTY: End
15095 -- pp_index is an post-assigned incremented index!
15096 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
15097 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
15098 pp_index := pp_index + 1;
15099 l_an_ass_follow_lq := TRUE; -- Store the flag
15100 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
15101 END IF;
15102 -- Handling the ROLLOVER AND FINANCED FEES
15103 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
15104 LOOP
15105 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
15106 THEN
15107 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15108 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
15109 -- Price the fees ROLLOVER OR FINANCED
15110 price_standard_quote_asset(
15111 x_return_status => l_return_status,
15112 x_msg_count => x_msg_count,
15113 x_msg_data => x_msg_data,
15114 p_api_version => p_api_version,
15115 p_init_msg_list => p_init_msg_list,
15116 p_qte_id => p_qte_id,
15117 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
15118 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
15119 p_target_rate => NULL,
15120 p_line_type => assets_rec.fee_type,
15121 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
15122 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15123 'After price_standard_quote_asset ' || l_return_status );
15124 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
15125 RAISE okl_api.g_exception_unexpected_error;
15126 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
15127 RAISE okl_api.g_exception_error;
15128 END IF;
15129 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
15130 -- Increment the pp_index
15131 pp_index := pp_index + 1;
15132 END IF;
15133 END LOOP;
15134 -- Store the Pricing Param Table for calculation of the Non-Subsidized Yields
15135 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
15136 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15137 'Before calling irr for iir at quote level ' || l_return_status );
15138 -- Compute IIR @ Lease Quote Level.
15139 compute_irr(
15140 p_api_version => p_api_version,
15141 p_init_msg_list => p_init_msg_list,
15142 x_return_status => l_return_status,
15143 x_msg_count => x_msg_count,
15144 x_msg_data => x_msg_data,
15145 p_start_date => quote_rec.expected_start_date,
15146 p_day_count_method => l_day_count_method,
15147 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
15148 p_pricing_method => 'SY',
15149 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
15150 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
15151 px_irr => x_iir,
15152 x_payment => x_payment);
15153 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15154 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
15155 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15156 'SOLVED FOR IIR ' || x_iir );
15157 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15158 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15159 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15160 RAISE OKL_API.G_EXCEPTION_ERROR;
15161 END IF;
15162 l_subsidized_yields_rec.iir := x_iir;
15163 l_subsidized_yields_rec.bk_yield := x_iir;
15164 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
15165 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
15166 LOOP
15167 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
15168 THEN
15169 -- Delete the previous fees cash flows
15170 l_fee_outflow_cfl_tbl.DELETE;
15171 l_fee_inflow_cfl_tbl.DELETE;
15172 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15173 '!!!!!! Handling fee ' || assets_rec.fee_type );
15174 get_lq_fee_cash_flows(
15175 p_api_version => p_api_version,
15176 p_init_msg_list => p_init_msg_list,
15177 x_return_status => l_return_status,
15178 x_msg_count => x_msg_count,
15179 x_msg_data => x_msg_data,
15180 p_fee_type => assets_rec.fee_type,
15181 p_lq_id => p_qte_id,
15182 p_fee_id => assets_rec.fee_id,
15183 x_outflow_caf_rec => l_fee_outflow_caf_rec,
15184 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
15185 x_inflow_caf_rec => l_fee_inflow_caf_rec,
15186 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
15187 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15188 'After get_lq_fee_cash_flows ' || l_return_status );
15189 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15190 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15191 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15192 RAISE OKL_API.G_EXCEPTION_ERROR;
15193 END IF;
15194 -- Based on the outflows/Inflows obtained generate the streams
15195 IF l_fee_outflow_cfl_tbl.COUNT > 0
15196 THEN
15197 l_cash_inflows.DELETE;
15198 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15199 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
15200 gen_so_cf_strms(
15201 p_api_version => p_api_version,
15202 p_init_msg_list => p_init_msg_list,
15203 x_return_status => l_return_status,
15204 x_msg_count => x_msg_count,
15205 x_msg_data => x_msg_data,
15206 p_cash_flow_rec => l_fee_outflow_caf_rec,
15207 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
15208 x_cash_inflow_strms_tbl => l_cash_inflows);
15209 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15210 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15211 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15212 RAISE OKL_API.G_EXCEPTION_ERROR;
15213 END IF;
15214 -- Place the information in the pricing params
15215 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
15216 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
15217 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
15218 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
15219 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
15220 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
15221 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_outflow_caf_rec.cfo_id;
15222 -- Bug 7440199: Quote Streams ER: RGOOTY: End
15223 pp_index := pp_index + 1;
15224 END IF;
15225 -- Based on the outflows/Inflows obtained generate the streams
15226 IF l_fee_inflow_cfl_tbl.COUNT > 0
15227 THEN
15228 l_cash_inflows.DELETE;
15229 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15230 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
15231 gen_so_cf_strms(
15232 p_api_version => p_api_version,
15233 p_init_msg_list => p_init_msg_list,
15234 x_return_status => l_return_status,
15235 x_msg_count => x_msg_count,
15236 x_msg_data => x_msg_data,
15237 p_cash_flow_rec => l_fee_inflow_caf_rec,
15238 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
15239 x_cash_inflow_strms_tbl => l_cash_inflows);
15240 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15241 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15242 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15243 RAISE OKL_API.G_EXCEPTION_ERROR;
15244 END IF;
15245 -- Place the information in the pricing params
15246 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
15247 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
15248 THEN
15249 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
15250 ELSE
15251 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
15252 END IF;
15253 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
15254 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
15255 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
15256 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
15257 l_pricing_parameter_tbl(pp_index).cfo_id := l_fee_inflow_caf_rec.cfo_id;
15258 -- Bug 7440199: Quote Streams ER: RGOOTY: End
15259 pp_index := pp_index + 1;
15260 END IF;
15261 END IF; -- IF on Fee_type not in ...
15262 IF assets_rec.fee_type = 'ABSORBED'
15263 THEN
15264 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15265 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
15266 -- Increment the pp_index and store the pricng params
15267 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
15268 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
15269 pp_index := pp_index + 1;
15270 END IF;
15271 END LOOP;
15272 -- Store the Pricing Param Table for calculation of the
15273 -- Non-Subsidized Yields
15274 l_pp_non_sub_irr_tbl.DELETE;
15275 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
15276 -- Now call the compute_irr api to solve for the Yield at the Lease quote Level !
15277 compute_irr(
15278 p_api_version => p_api_version,
15279 p_init_msg_list => p_init_msg_list,
15280 x_return_status => l_return_status,
15281 x_msg_count => x_msg_count,
15282 x_msg_data => x_msg_data,
15283 p_start_date => quote_rec.expected_start_date,
15284 p_day_count_method => l_day_count_method,
15285 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
15286 p_pricing_method => 'SY',
15287 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
15288 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
15289 px_irr => x_iir,
15290 x_payment => x_payment);
15291 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15292 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
15293 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15294 'SOLVED FOR IRR ' || x_iir );
15295 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15296 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15297 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15298 RAISE OKL_API.G_EXCEPTION_ERROR;
15299 END IF;
15300 l_subsidized_yields_rec.pre_tax_irr := x_iir;
15301 -- Calculate the Yields without involving the Subsidy Amount
15302 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15303 '1/ CALCULATING THE YEILDS WIHTOUT THE SUBSIDY AMOUNT INVOLVED !! ' );
15304 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15305 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
15306 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
15307 FOR ny IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
15308 LOOP
15309 -- line_type, subsidy
15310 l_pp_non_sub_iir_tbl(ny).subsidy := 0;
15311 END LOOP;
15312 l_iir_temp := NULL;
15313 l_iir_temp := l_yields_rec.iir;
15314 compute_irr(
15315 p_api_version => p_api_version,
15316 p_init_msg_list => p_init_msg_list,
15317 x_return_status => l_return_status,
15318 x_msg_count => x_msg_count,
15319 x_msg_data => x_msg_data,
15320 p_start_date => quote_rec.expected_start_date,
15321 p_day_count_method => l_day_count_method,
15322 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
15323 p_pricing_method => 'SY',
15324 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
15325 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
15326 -- px_irr => l_yields_rec.iir,
15327 px_irr => l_iir_temp,
15328 x_payment => x_payment);
15329 l_yields_rec.iir := l_iir_temp;
15330 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15331 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
15332 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15333 'SOLVED FOR IIR (NON-SUBSIDY)' || l_yields_rec.iir );
15334 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15335 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15336 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15337 RAISE OKL_API.G_EXCEPTION_ERROR;
15338 END IF;
15339 -- Store the IIR as the Booking Yield
15340 l_yields_rec.bk_yield := l_yields_rec.iir;
15341 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
15342 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15343 '1/ Before Computation of IRR @ LQ Level loop subsidy ' || to_char(l_pp_non_sub_irr_tbl.COUNT));
15344 FOR ny IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
15345 LOOP
15346 -- For Asset lines, change the Subsidy Amount to Zero ..
15347 IF nvl(l_pp_non_sub_irr_tbl(ny).line_type, 'XXXX') = 'FREE_FORM1'
15348 THEN
15349 l_pp_non_sub_irr_tbl(ny).subsidy := 0;
15350 END IF;
15351 END LOOP;
15352 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15353 '1/ Before Computation of IRR @ LQ Level ' );
15354 l_iir_temp := NULL;
15355 l_iir_temp := l_yields_rec.pre_tax_irr;
15356 compute_irr(
15357 p_api_version => p_api_version,
15358 p_init_msg_list => p_init_msg_list,
15359 x_return_status => l_return_status,
15360 x_msg_count => x_msg_count,
15361 x_msg_data => x_msg_data,
15362 p_start_date => quote_rec.expected_start_date,
15363 p_day_count_method => l_day_count_method,
15364 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
15365 p_pricing_method => 'SY',
15366 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
15367 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
15368 -- px_irr => l_yields_rec.pre_tax_irr,
15369 px_irr => l_iir_temp,
15370 x_payment => x_payment);
15371 l_yields_rec.pre_tax_irr := l_iir_temp;
15372 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15373 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
15374 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15375 'SOLVED FOR IRR (NON-SUBSIDY)' || l_yields_rec.pre_tax_irr );
15376 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15377 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15378 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15379 RAISE OKL_API.G_EXCEPTION_ERROR;
15380 END IF;
15381 END IF;
15382 -- Populate the l_lease_qte_rec appropriately for the Updation
15383 l_lease_qte_rec.id := p_qte_id;
15384 l_lease_qte_rec.SUB_IIR := round(l_subsidized_yields_rec.iir * 100, 4);
15385 l_lease_qte_rec.SUB_PIRR := round(l_subsidized_yields_rec.pre_tax_irr * 100, 4);
15386 l_lease_qte_rec.SUB_BOOKING_YIELD := round(l_subsidized_yields_rec.bk_yield * 100, 4);
15387 l_lease_qte_rec.IIR := round(l_yields_rec.iir * 100, 4);
15388 l_lease_qte_rec.PIRR := round(l_yields_rec.pre_tax_irr * 100, 4);
15389 l_lease_qte_rec.BOOKING_YIELD := round(l_yields_rec.bk_yield * 100, 4);
15390 l_lease_qte_rec.status := 'PR-COMPLETE';
15391 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15392 'Update the Yields on the Lease Quote' );
15393 okl_lease_quote_pvt.update_lease_qte(
15394 p_api_version => p_api_version,
15395 p_init_msg_list => p_init_msg_list,
15396 p_transaction_control => NULL,
15397 p_lease_qte_rec => l_lease_qte_rec,
15398 x_lease_qte_rec => x_lease_qte_rec,
15399 x_return_status => l_return_status,
15400 x_msg_count => x_msg_count,
15401 x_msg_data => x_msg_data);
15402 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15403 'After updation of Yields on Lease Quote. Status: ' || l_return_status );
15404 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15405 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15406 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15407 RAISE OKL_API.G_EXCEPTION_ERROR;
15408 END IF;
15409 -- Now after the Yields has been calculated, we need to calculate the payments
15410 -- for all Non-Overridden assets !
15411 IF quote_rec.pricing_method <> 'RC'
15412 AND l_an_ass_follow_lq
15413 THEN
15414 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15415 ' !!!!!!!! CALCULATION OF THE ASSET LEVEL PAYMENTS !!!!!! ' );
15416 -- Calculate the Quote leve C-S-D-T
15417 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15418 'LQ Level: Asset Cost (C) | Down Payment (D) | Trade-in (T) | Subsidy (s)' );
15419 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15420 round( l_lq_details_prc_rec.financed_amount, 4) || ' | ' || round( l_lq_details_prc_rec.down_payment, 4) || ' | ' ||
15421 round( l_lq_details_prc_rec.trade_in, 4) || ' | ' || round( l_lq_details_prc_rec.subsidy, 4));
15422 IF quote_rec.pricing_method <> 'TR'
15423 THEN
15424 -- Now compute the IIR for the group of assets which follow the payment
15425 -- entered at the Quote Level.
15426 compute_iir(
15427 p_api_version => p_api_version,
15428 p_init_msg_list => p_init_msg_list,
15429 x_return_status => l_return_status,
15430 x_msg_count => x_msg_count,
15431 x_msg_data => x_msg_data,
15432 p_start_date => quote_rec.expected_start_date,
15433 p_day_count_method => l_day_count_method,
15434 p_pricing_method => 'SY',
15435 p_initial_guess => (l_lease_qte_rec.iir/ 100 ),
15436 px_pricing_parameter_rec => l_lq_details_prc_rec,
15437 px_iir => l_iir,
15438 x_payment => l_miss_payment);
15439 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15440 'After SY @ LQ level ' || x_return_status || ' | l_iir=' || round(l_iir,4) );
15441 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15442 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15443 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15444 RAISE OKL_API.G_EXCEPTION_ERROR;
15445 END IF;
15446 ELSE
15447 l_iir := (l_lease_qte_rec.iir / 100 );
15448 END IF;
15449 -- Loop the Streams at the Quote level and put the l_iir as rate, and cf_ratio also
15450 -- needs to be populated appropriately.
15451 l_lq_con_cash_inflows := l_lq_details_prc_rec.cash_inflows;
15452 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15453 '!! Assigning the Quote level rate and cf_ratio !!' );
15454 FOR t_in IN l_lq_con_cash_inflows.FIRST .. l_lq_con_cash_inflows.LAST
15455 LOOP
15456 IF l_lq_con_cash_inflows(t_in).cf_amount > 0
15457 THEN
15458 l_tmp_amount := l_lq_con_cash_inflows(t_in).cf_amount;
15459 EXIT;
15460 END IF;
15461 END LOOP;
15462 FOR t_in IN l_lq_con_cash_inflows.FIRST .. l_lq_con_cash_inflows.LAST
15463 LOOP
15464 l_lq_con_cash_inflows(t_in).cf_rate := l_iir;
15465 l_lq_con_cash_inflows(t_in).cf_ratio:= l_lq_con_cash_inflows(t_in).cf_amount/l_tmp_amount;
15466 END LOOP;
15467 -- Store the amount from the first cash flow level which can be a Stub/Periodic Amount and is non-zero
15468 FOR t_in IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
15469 LOOP
15470 IF l_lq_payment_level_tbl(t_in).stub_days IS NOT NULL AND
15471 l_lq_payment_level_tbl(t_in).stub_amount > 0
15472 THEN
15473 -- Found a first stub CFL with some amount, using this as a base for the proportion.
15474 l_tmp_amount := l_lq_payment_level_tbl(t_in).stub_amount;
15475 EXIT;
15476 ELSIF l_lq_payment_level_tbl(t_in).periods IS NOT NULL AND
15477 l_lq_payment_level_tbl(t_in).periodic_amount > 0
15478 THEN
15479 -- Found a regular CFL with some amount, using this as a base for the proportion.
15480 l_tmp_amount := l_lq_payment_level_tbl(t_in).periodic_amount;
15481 EXIT;
15482 END IF;
15483 END LOOP;
15484 l_rnd_lq_payment_level_tbl := l_lq_payment_level_tbl;
15485 l_rnd_sum_assets_pmnts_tbl := l_lq_payment_level_tbl;
15486 FOR t_in IN l_rnd_lq_payment_level_tbl.FIRST .. l_rnd_lq_payment_level_tbl.LAST
15487 LOOP
15488 IF l_rnd_lq_payment_level_tbl(t_in).stub_days IS NOT NULL AND
15489 l_rnd_lq_payment_level_tbl(t_in).stub_amount > 0
15490 THEN
15491 l_rnd_lq_payment_level_tbl(t_in).stub_amount :=
15492 okl_accounting_util.round_amount(
15493 p_amount => l_rnd_lq_payment_level_tbl(t_in).stub_amount,
15494 p_currency_code => l_currency );
15495 l_rnd_sum_assets_pmnts_tbl(t_in).stub_amount := 0;
15496 ELSE
15497 l_rnd_lq_payment_level_tbl(t_in).periodic_amount :=
15498 okl_accounting_util.round_amount(
15499 p_amount => l_rnd_lq_payment_level_tbl(t_in).periodic_amount,
15500 p_currency_code => l_currency );
15501 l_rnd_sum_assets_pmnts_tbl(t_in).periodic_amount := 0;
15502 END IF;
15503 END LOOP;
15504 -- Loop through the assets which follow the LQ payment structure
15505 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15506 '!!!!!!!! **** DERIEVING PAYMENTS FOR ALL ASSETS ***** !!!!!!!!!' );
15507 FOR t IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
15508 LOOP
15509 IF quote_rec.pricing_method IN ( 'SF' )
15510 THEN
15511 -- Asset Cost is not stored in the l_noa_pp_tbl while solving it .. Hence, fetch it
15512 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15513 ' Asset ID = ' || l_non_overiding_assets_tbl(t) );
15514 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, l_non_overiding_assets_tbl(t))
15515 LOOP
15516 l_noa_pp_tbl(t).financed_amount := nvl(asset_adj_rec.oec,0);
15517 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15518 'Asset cost was fetched from the DB ' || l_noa_pp_tbl(t).financed_amount );
15519 END LOOP;
15520 END IF;
15521 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15522 'Asset Cost (C) | Down Payment (D) | Trade-in (T) | Subsidy (s)' );
15523 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15524 round( l_noa_pp_tbl(t).financed_amount, 4) || ' | ' || round( l_noa_pp_tbl(t).down_payment, 4) || ' | ' ||
15525 round( l_noa_pp_tbl(t).trade_in, 4) || ' | ' || round( l_noa_pp_tbl(t).subsidy, 4));
15526 -- The streams for this asset should resemble the Quote level ones. Hence, copying them to the Asset PP Rec.
15527 l_noa_pp_tbl(t).cash_inflows := l_lq_con_cash_inflows;
15528 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15529 'Calculating the Asset level Payment for ID ' || l_non_overiding_assets_tbl(t) );
15530 compute_iir(
15531 p_api_version => p_api_version,
15532 p_init_msg_list => p_init_msg_list,
15533 x_return_status => l_return_status,
15534 x_msg_count => x_msg_count,
15535 x_msg_data => x_msg_data,
15536 p_start_date => quote_rec.expected_start_date,
15537 p_day_count_method => l_day_count_method,
15538 p_pricing_method => 'SPP', -- Use the Algorithm which proportionates the Payment Amt
15539 p_initial_guess => l_lease_qte_rec.iir,
15540 px_pricing_parameter_rec => l_noa_pp_tbl(t),
15541 px_iir => l_iir,
15542 x_payment => l_miss_payment);
15543 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15544 'SPP: For Asset Status=' || x_return_status || ' | l_iir=' || round(l_iir,4) || ' | l_miss_payment = ' || round(l_miss_payment, 2));
15545 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15546 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15547 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15548 RAISE OKL_API.G_EXCEPTION_ERROR;
15549 END IF;
15550 -- Need to delete the cash flow (if any exists) for this Asset with WORK Status.
15551 l_cfo_exists_at_noa := 'YES';
15552 FOR t_rec IN check_cfo_exists_csr(
15553 p_oty_code => 'QUOTED_ASSET',
15554 p_source_table => 'OKL_ASSETS_B',
15555 p_source_id => l_non_overiding_assets_tbl(t),
15556 p_sts_code => 'WORK')
15557 LOOP
15558 l_cfo_exists_at_noa := t_rec.cfo_exists;
15559 END LOOP;
15560 -- Delete the Cash flows if they are already present
15561 IF l_cfo_exists_at_noa = 'YES'
15562 THEN
15563 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15564 ' Deleting already existing CFO ' );
15565 -- Delete the Cash Flow Levels which may be already created by Pricing ..
15566 okl_lease_quote_cashflow_pvt.delete_cashflows (
15567 p_api_version => p_api_version,
15568 p_init_msg_list => p_init_msg_list,
15569 p_transaction_control => NULL,
15570 p_source_object_code => 'QUOTED_ASSET',
15571 p_source_object_id => l_non_overiding_assets_tbl(t),
15572 x_return_status => l_return_status,
15573 x_msg_count => x_msg_count,
15574 x_msg_data => x_msg_data);
15575 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15576 ' ----- After deleting the Cash flows for the asset ' || l_return_status );
15577 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
15578 RAISE okl_api.g_exception_unexpected_error;
15579 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
15580 RAISE okl_api.g_exception_error;
15581 END IF;
15582 END IF;
15583 -- Create the Cash flows with the structure similiar to the LQ
15584 l_asset_caf_rec.parent_object_code := 'QUOTED_ASSET';
15585 l_asset_caf_rec.parent_object_id := l_non_overiding_assets_tbl(t);
15586 l_asset_caf_rec.status_code := 'WORK';
15587 l_asset_caf_rec.type_code := 'INFLOW';
15588 l_asset_caf_rec.arrears_flag := l_lq_payment_header_rec.arrears_flag;
15589 l_asset_caf_rec.stream_type_id := l_rent_sty_id;
15590 l_asset_caf_rec.frequency_code := l_lq_payment_header_rec.frequency_code;
15591 l_asset_caf_rec.quote_type_code := l_quote_type_code;
15592 l_asset_caf_rec.quote_id := p_qte_id;
15593 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15594 ' Frequency | Adv/ Arrears | Rate | Stub Days | Stub Amount | Periods | Amount | Start Date ' );
15595 FOR i in l_lq_payment_level_tbl.FIRST..l_lq_payment_level_tbl.LAST
15596 LOOP
15597 l_asset_cfl_tbl(i).record_mode := 'CREATE';
15598 l_asset_cfl_tbl(i).start_date := l_lq_payment_level_tbl(i).start_date;
15599 l_asset_cfl_tbl(i).rate := l_iir;
15600 l_asset_cfl_tbl(i).stub_amount := l_lq_payment_level_tbl(i).stub_amount;
15601 l_asset_cfl_tbl(i).stub_days := l_lq_payment_level_tbl(i).stub_days;
15602 l_asset_cfl_tbl(i).periods := l_lq_payment_level_tbl(i).periods;
15603 l_asset_cfl_tbl(i).periodic_amount := l_lq_payment_level_tbl(i).periodic_amount;
15604 -- Using the l_miss_amount and the ratio of the cash flows we need to determine the Amount @ every CFL
15605 IF l_lq_cash_flow_det_tbl(i).stub_days > 0
15606 THEN
15607 IF t = l_noa_pp_tbl.LAST
15608 THEN
15609 -- The Last Payment, hence use the Round LQ Amount - Sum of Prev. Assets Amount, instead of the proportion.
15610 l_asset_cfl_tbl(i).stub_amount := l_rnd_lq_payment_level_tbl(i).stub_amount - l_rnd_sum_assets_pmnts_tbl(i).stub_amount;
15611 ELSE
15612 l_asset_cfl_tbl(i).stub_amount :=
15613 l_miss_payment * (l_lq_payment_level_tbl(i).stub_amount / l_tmp_amount);
15614 l_rnd_sum_assets_pmnts_tbl(i).stub_amount := l_rnd_sum_assets_pmnts_tbl(i).stub_amount +
15615 okl_accounting_util.round_amount(
15616 p_amount => l_asset_cfl_tbl(i).stub_amount,
15617 p_currency_code => l_currency );
15618 END IF;
15619 ELSIF l_lq_cash_flow_det_tbl(i).number_of_periods > 0
15620 THEN
15621 IF t = l_noa_pp_tbl.LAST
15622 THEN
15623 -- The Last Payment, hence use the Round LQ Amount - Sum of Prev. Assets Amount, instead of the proportion.
15624 l_asset_cfl_tbl(i).periodic_amount := l_rnd_lq_payment_level_tbl(i).periodic_amount - l_rnd_sum_assets_pmnts_tbl(i).periodic_amount;
15625 ELSE
15626 l_asset_cfl_tbl(i).periodic_amount :=
15627 l_miss_payment * (l_lq_payment_level_tbl(i).periodic_amount / l_tmp_amount );
15628 l_rnd_sum_assets_pmnts_tbl(i).periodic_amount := l_rnd_sum_assets_pmnts_tbl(i).periodic_amount +
15629 okl_accounting_util.round_amount(
15630 p_amount => l_asset_cfl_tbl(i).periodic_amount,
15631 p_currency_code => l_currency );
15632 END IF;
15633 END IF;
15634 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15635 l_asset_caf_rec.frequency_code || ' | ' || l_asset_caf_rec.arrears_flag || ' | ' || l_asset_cfl_tbl(i).rate|| ' | ' ||
15636 l_asset_cfl_tbl(i).stub_days || ' | ' || l_asset_cfl_tbl(i).stub_amount|| ' | ' || l_asset_cfl_tbl(i).periods|| ' | ' ||
15637 l_asset_cfl_tbl(i).periodic_amount || ' | ' || l_asset_cfl_tbl(i).start_Date );
15638 END LOOP;
15639 -- Create the Cash flows for the Asset
15640 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
15641 p_api_version => p_api_version,
15642 p_init_msg_list => p_init_msg_list,
15643 p_transaction_control => NULL,
15644 p_cashflow_header_rec => l_asset_caf_rec,
15645 p_cashflow_level_tbl => l_asset_cfl_tbl,
15646 x_return_status => l_return_status,
15647 x_msg_count => x_msg_count,
15648 x_msg_data => x_msg_data);
15649 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15650 'After calling create_cash_flow ' || l_return_status);
15651 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15652 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15653 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15654 RAISE OKL_API.G_EXCEPTION_ERROR;
15655 END IF;
15656 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
15657 -- Based on the Derieved Cash flows for the Non-overriding Assets
15658 -- Generate the Streams for the Non-Overriding Assets
15659 IF l_asset_cfl_tbl.COUNT > 0
15660 THEN
15661 -- Delete the Temporary Streams Table
15662 l_cash_inflows.DELETE;
15663 l_noa_cash_flow_det_tbl.DELETE;
15664 -- Populate the Cash Flow Header Equivalent Record Structure to generate Streams
15665 l_noa_cash_flow_rec.caf_id := l_asset_caf_rec.cashflow_header_id;
15666 l_noa_cash_flow_rec.qte_id := p_qte_id;
15667 l_noa_cash_flow_rec.cfo_id := l_asset_caf_rec.cashflow_object_id;
15668 l_noa_cash_flow_rec.sts_code := 'WORK';
15669 l_noa_cash_flow_rec.sty_id := l_asset_caf_rec.stream_type_id;
15670 l_noa_cash_flow_rec.cft_code := 'PAYMENT_SCHEDULE';
15671 l_noa_cash_flow_rec.due_arrears_yn := l_asset_caf_rec.arrears_flag;
15672 l_noa_cash_flow_rec.start_date := NULL;
15673 l_noa_cash_flow_rec.number_of_advance_periods := NULL;
15674 -- Populate the Cash Flow Level equivalent Record Structure to generate streams
15675 FOR i in l_asset_cfl_tbl.FIRST .. l_asset_cfl_tbl.LAST
15676 LOOP
15677 l_noa_cash_flow_det_tbl(i).start_date := l_asset_cfl_tbl(i).start_date;
15678 l_noa_cash_flow_det_tbl(i).rate := l_asset_cfl_tbl(i).rate;
15679 l_noa_cash_flow_det_tbl(i).fqy_code := l_asset_caf_rec.frequency_code;
15680 l_noa_cash_flow_det_tbl(i).number_of_periods := l_asset_cfl_tbl(i).periods;
15681 l_noa_cash_flow_det_tbl(i).amount := l_asset_cfl_tbl(i).periodic_amount;
15682 l_noa_cash_flow_det_tbl(i).stub_days := l_asset_cfl_tbl(i).stub_days;
15683 l_noa_cash_flow_det_tbl(i).stub_amount := l_asset_cfl_tbl(i).stub_amount;
15684 END LOOP;
15685 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15686 'Generating the Stream Elements for the Asset!' );
15687 gen_so_cf_strms(
15688 p_api_version => p_api_version,
15689 p_init_msg_list => p_init_msg_list,
15690 x_return_status => l_return_status,
15691 x_msg_count => x_msg_count,
15692 x_msg_data => x_msg_data,
15693 p_cash_flow_rec => l_noa_cash_flow_rec,
15694 p_cf_details_tbl => l_noa_cash_flow_det_tbl,
15695 x_cash_inflow_strms_tbl => l_cash_inflows);
15696 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15697 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15698 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15699 RAISE OKL_API.G_EXCEPTION_ERROR;
15700 END IF;
15701 -- Place the information in the Consolidated Pricing Params Table
15702 -- so that the insert_quote_api inserts the Streams Captured here !
15703 pp_index := l_pp_non_sub_irr_tbl.COUNT + 1;
15704 l_pp_non_sub_irr_tbl(pp_index).line_type := 'FREE_FORM1';
15705 l_pp_non_sub_irr_tbl(pp_index).payment_type := 'QUOTED_ASSET';
15706 --l_pricing_parameter_tbl(pp_index).line_end_date := srvc_rec.line_end_date;
15707 l_pp_non_sub_irr_tbl(pp_index).cash_inflows := l_cash_inflows;
15708 l_pp_non_sub_irr_tbl(pp_index).cfo_id := l_asset_caf_rec.cashflow_object_id;
15709 -- Push the Residual Values also
15710 l_pp_non_sub_irr_tbl(pp_index).residual_inflows := l_noa_pp_tbl(t).residual_inflows;
15711 END IF;
15712 -- Bug 7440199: Quote Streams ER: RGOOTY: End
15713 END LOOP; -- Loop on the l_noa_det_prc_tbl
15714 END IF;
15715 -- Delete (if exists any..) LEASE_QUOTE_CONSOLIDATED cash flows existing
15716 -- at the Lease Quote level.
15717 l_cfo_exists_at_lq := 'NO';
15718 FOR t_rec IN check_cfo_exists_csr(
15719 p_oty_code => 'LEASE_QUOTE_CONSOLIDATED',
15720 p_source_table => 'OKL_LEASE_QUOTES_B',
15721 p_source_id => p_qte_id,
15722 p_sts_code => 'WORK')
15723 LOOP
15724 l_cfo_exists_at_lq := t_rec.cfo_exists;
15725 END LOOP;
15726 IF l_cfo_exists_at_lq = 'YES'
15727 THEN
15728 -- Delete the Payment structure already derieved by pricing
15729 okl_lease_quote_cashflow_pvt.delete_cashflows (
15730 p_api_version => p_api_version,
15731 p_init_msg_list => p_init_msg_list,
15732 p_transaction_control => NULL,
15733 p_source_object_code => 'LEASE_QUOTE_CONSOLIDATED',
15734 p_source_object_id => p_qte_id,
15735 x_return_status => l_return_status,
15736 x_msg_count => x_msg_count,
15737 x_msg_data => x_msg_data);
15738 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15739 'Deleted the Consolidated Cash flow levels @ LQ levels. Status: ' || l_return_status );
15740 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
15741 RAISE okl_api.g_exception_unexpected_error;
15742 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
15743 RAISE okl_api.g_exception_error;
15744 END IF;
15745 END IF; -- IF l_cfo_exists_at_lq
15746 -- Code for solving the payment amount @ LQ level follows ..
15747 -- If for all the assets, frequency, adv/arrears, the payment structure matches
15748 -- then the solve_pmnts_at_lq API returns the solved payment structure @ LQ level
15749 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15750 '!!! *** DERIEVING THE CONSOLIDATED PAYMENT AMOUNT AT LEASE QUOTE LEVEL *** !!! ');
15751 solve_pmnts_at_lq(
15752 p_api_version => p_api_version,
15753 p_init_msg_list => p_init_msg_list,
15754 x_return_status => l_return_status,
15755 x_msg_count => x_msg_count,
15756 x_msg_data => x_msg_data,
15757 p_id => p_qte_id,
15758 x_caf_rec => l_lq_payment_header_rec,
15759 x_cfl_tbl => l_lq_payment_level_tbl,
15760 x_solved => l_solved);
15761 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15762 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15763 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15764 RAISE OKL_API.G_EXCEPTION_ERROR;
15765 END IF;
15766 IF l_solved = 'YES' AND l_lq_payment_level_tbl IS NOT NULL AND l_lq_payment_level_tbl.COUNT > 0
15767 THEN
15768 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15769 '!!! *** Payments can be derieved at Lease Quote level *** !!! ' || l_lq_payment_level_tbl.COUNT );
15770 l_lq_payment_header_rec.type_code := 'INFLOW';
15771 l_lq_payment_header_rec.parent_object_code := 'LEASE_QUOTE_CONSOLIDATED';
15772 l_lq_payment_header_rec.parent_object_id := p_qte_id;
15773 l_lq_payment_header_rec.status_code := 'WORK';
15774 IF quote_rec.pricing_method = 'RC'
15775 THEN
15776 OPEN c_strm_type ( quote_rec.id, quote_rec.expected_start_date );
15777 FETCH c_strm_type INTO r_strm_type;
15778 CLOSE c_strm_type;
15779 l_rent_sty_id := r_strm_type.payment_type_id;
15780 END IF;
15781 l_lq_payment_header_rec.stream_type_id := l_rent_sty_id;
15782 l_lq_payment_header_rec.quote_type_code := l_quote_type_code;
15783 l_lq_payment_header_rec.quote_id := p_qte_id;
15784 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15785 ' Frequency | Adv/ Arrears | Rate | Stub Days | Stub Amount | Periods | Amount | Start Date ' );
15786 FOR i IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
15787 LOOP
15788 l_lq_payment_level_tbl(i).record_mode := 'CREATE';
15789 IF l_lq_payment_level_tbl(i).rate IS NULL
15790 THEN
15791 l_lq_payment_level_tbl(i).rate := l_lease_qte_rec.sub_iir;
15792 END IF;
15793 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15794 l_lq_payment_header_rec.frequency_code || ' | ' || l_lq_payment_header_rec.arrears_flag || ' | ' || l_lq_payment_level_tbl(i).rate|| ' | ' ||
15795 l_lq_payment_level_tbl(i).stub_days || ' | ' || l_lq_payment_level_tbl(i).stub_amount|| ' | ' || l_lq_payment_level_tbl(i).periods|| ' | ' ||
15796 l_lq_payment_level_tbl(i).periodic_amount || ' | ' || l_lq_payment_level_tbl(i).start_Date );
15797 END LOOP;
15798 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
15799 p_api_version => p_api_version,
15800 p_init_msg_list => p_init_msg_list,
15801 p_transaction_control => NULL,
15802 p_cashflow_header_rec => l_lq_payment_header_rec,
15803 p_cashflow_level_tbl => l_lq_payment_level_tbl,
15804 x_return_status => l_return_status,
15805 x_msg_count => x_msg_count,
15806 x_msg_data => x_msg_data);
15807 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15808 'Creation of LQ level cash flow levels stauts: ' || l_Return_Status );
15809 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15810 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15811 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15812 RAISE OKL_API.G_EXCEPTION_ERROR;
15813 END IF;
15814 ELSE
15815 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15816 '!!!!! PRICING ENGINE IS UNABLE TO DERIEVE PAYMENTS AT LQ LEVEL !!!!!' );
15817 END IF; -- IF l_solved = 'YES'
15818 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
15819 --Get the service cash inflows and generate the streams
15820 FOR srvc_rec IN services_csr(p_qte_id)
15821 LOOP
15822 -- Delete the previous services cash inflows
15823 l_srvc_inflow_cfl_tbl.DELETE;
15824 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15825 '!!!!!! Handling service ');
15826 get_lq_srvc_cash_flows(
15827 p_api_version => p_api_version,
15828 p_init_msg_list => p_init_msg_list,
15829 x_return_status => l_return_status,
15830 x_msg_count => x_msg_count,
15831 x_msg_data => x_msg_data,
15832 p_srvc_type => 'SERVICE',
15833 p_lq_id => p_qte_id,
15834 p_srvc_id => srvc_rec.srvc_id,
15835 x_inflow_caf_rec => l_srvc_inflow_caf_rec,
15836 x_inflow_cfl_tbl => l_srvc_inflow_cfl_tbl);
15837 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15838 'After get_lq_srvc_cash_flows ' || l_return_status );
15839 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15840 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15841 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15842 RAISE OKL_API.G_EXCEPTION_ERROR;
15843 END IF;
15844
15845 -- Based on the Inflows obtained generate the streams
15846 IF l_srvc_inflow_cfl_tbl.COUNT > 0
15847 THEN
15848 l_cash_inflows.DELETE;
15849 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
15850 '!!!!!!! Obtained Service Cash flow levels !!!!!!!!' );
15851 gen_so_cf_strms(
15852 p_api_version => p_api_version,
15853 p_init_msg_list => p_init_msg_list,
15854 x_return_status => l_return_status,
15855 x_msg_count => x_msg_count,
15856 x_msg_data => x_msg_data,
15857 p_cash_flow_rec => l_srvc_inflow_caf_rec,
15858 p_cf_details_tbl => l_srvc_inflow_cfl_tbl,
15859 x_cash_inflow_strms_tbl => l_cash_inflows);
15860 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15861 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
15862 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
15863 RAISE OKL_API.G_EXCEPTION_ERROR;
15864 END IF;
15865 -- Place the information in the pricing params
15866 pp_index := l_pp_non_sub_irr_tbl.COUNT + 1;
15867 l_pp_non_sub_irr_tbl(pp_index).line_type := 'SERVICE';
15868 l_pp_non_sub_irr_tbl(pp_index).payment_type := 'SERVICE';
15869 l_pp_non_sub_irr_tbl(pp_index).line_start_date := srvc_rec.line_start_date;
15870 --l_pricing_parameter_tbl(pp_index).line_end_date := srvc_rec.line_end_date;
15871 l_pp_non_sub_irr_tbl(pp_index).cash_inflows := l_cash_inflows;
15872 l_pp_non_sub_irr_tbl(pp_index).cfo_id := l_srvc_inflow_caf_rec.cfo_id;
15873
15874 --Added by bkatraga for bug 7410991
15875 l_sum_assoc_assets_amt := 0;
15876 l_assoc_assets_count := 0;
15877 OPEN CHECK_ASSOC_ASSETS('SERVICE', srvc_rec.srvc_id);
15878 FETCH CHECK_ASSOC_ASSETS INTO l_sum_assoc_assets_amt, l_assoc_assets_count;
15879 CLOSE CHECK_ASSOC_ASSETS;
15880
15881 IF(l_assoc_assets_count > 0) THEN
15882 l_assets_indx := 0;
15883 l_amount_tbl.DELETE;
15884
15885 FOR i in l_cash_inflows.FIRST .. l_cash_inflows.LAST
15886 LOOP
15887 l_cash_inflows(i).cf_amount := okl_accounting_util.round_amount(p_amount => l_cash_inflows(i).cf_amount,
15888 p_currency_code => l_currency);
15889 l_amount_tbl(i) := 0;
15890 END LOOP;
15891
15892 FOR assoc_asset_rec IN GET_ASSOC_ASSETS('SERVICE', srvc_rec.srvc_id)
15893 LOOP
15894 l_assets_indx := l_assets_indx + 1;
15895
15896 pp_index := l_pp_non_sub_irr_tbl.COUNT + 1;
15897 l_pp_non_sub_irr_tbl(pp_index).line_type := 'ASSOC_ASSET_SRVC';
15898 l_pp_non_sub_irr_tbl(pp_index).payment_type := 'ASSOC_ASSET_SRVC';
15899 l_pp_non_sub_irr_tbl(pp_index).line_start_date := srvc_rec.line_start_date;
15900 l_pp_non_sub_irr_tbl(pp_index).cash_inflows := l_cash_inflows;
15901 l_pp_non_sub_irr_tbl(pp_index).cfo_id := l_srvc_inflow_caf_rec.cfo_id;
15902 l_pp_non_sub_irr_tbl(pp_index).link_asset_id := assoc_asset_rec.source_line_id;
15903
15904 FOR i in l_cash_inflows.FIRST .. l_cash_inflows.LAST
15905 LOOP
15906 IF(l_assets_indx = l_assoc_assets_count) THEN --LAST ASSET
15907 l_pp_non_sub_irr_tbl(pp_index).cash_inflows(i).cf_amount := l_cash_inflows(i).cf_amount - l_amount_tbl(i);
15908 ELSE
15909 IF(l_sum_assoc_assets_amt = 0) THEN
15910 l_amount := 0;
15911 ELSE
15912 l_amount := (assoc_asset_rec.amount/l_sum_assoc_assets_amt) * l_cash_inflows(i).cf_amount;
15913 l_amount := okl_accounting_util.round_amount(p_amount => l_amount,
15914 p_currency_code => l_currency);
15915 END IF;
15916 l_pp_non_sub_irr_tbl(pp_index).cash_inflows(i).cf_amount := l_amount;
15917 l_amount_tbl(i) := l_amount_tbl(i) + l_amount;
15918 END IF;
15919 END LOOP;
15920 END LOOP;
15921 END IF;
15922 -- Bug 7440199: Quote Streams ER: RGOOTY: End
15923
15924 END IF;
15925 END LOOP;
15926 -- Bug 7440199: Quote Streams ER: RGOOTY: Start
15927 --Logic to generate Associated Asset Level streams for Financed and Rollover Fees
15928 FOR k in l_pp_non_sub_irr_tbl.first .. l_pp_non_sub_irr_tbl.last
15929 LOOP
15930 IF(l_pp_non_sub_irr_tbl(k).line_type IN('FINANCED','ROLLOVER')) THEN
15931 OPEN GET_FEE_ID(l_pp_non_sub_irr_tbl(k).cfo_id);
15932 FETCH GET_FEE_ID into l_fee_id;
15933 CLOSE GET_FEE_ID;
15934
15935 l_sum_assoc_assets_amt := 0;
15936 l_assoc_assets_count := 0;
15937 OPEN CHECK_ASSOC_ASSETS(l_pp_non_sub_irr_tbl(k).line_type, l_fee_id);
15938 FETCH CHECK_ASSOC_ASSETS INTO l_sum_assoc_assets_amt, l_assoc_assets_count;
15939 CLOSE CHECK_ASSOC_ASSETS;
15940
15941 IF(l_assoc_assets_count > 0) THEN
15942 l_assets_indx := 0;
15943 l_amount_tbl.DELETE;
15944 l_cash_inflows := l_pp_non_sub_irr_tbl(k).cash_inflows;
15945
15946 FOR i in l_cash_inflows.FIRST .. l_cash_inflows.LAST
15947 LOOP
15948 l_cash_inflows(i).cf_amount := okl_accounting_util.round_amount(p_amount => l_cash_inflows(i).cf_amount,
15949 p_currency_code => l_currency);
15950 l_amount_tbl(i) := 0;
15951 END LOOP;
15952
15953 FOR assoc_asset_rec IN GET_ASSOC_ASSETS(l_pp_non_sub_irr_tbl(k).line_type, l_fee_id)
15954 LOOP
15955 l_assets_indx := l_assets_indx + 1;
15956
15957 pp_index := l_pp_non_sub_irr_tbl.COUNT + 1;
15958 l_pp_non_sub_irr_tbl(pp_index).line_type := 'ASSOC_ASSET_FEE';
15959 l_pp_non_sub_irr_tbl(pp_index).payment_type := 'ASSOC_ASSET_FEE';
15960 l_pp_non_sub_irr_tbl(pp_index).line_start_date := l_pp_non_sub_irr_tbl(k).line_start_date;
15961 l_pp_non_sub_irr_tbl(pp_index).cash_inflows := l_cash_inflows;
15962 l_pp_non_sub_irr_tbl(pp_index).cfo_id := l_pp_non_sub_irr_tbl(k).cfo_id;
15963 l_pp_non_sub_irr_tbl(pp_index).link_asset_id := assoc_asset_rec.source_line_id;
15964
15965 FOR i in l_cash_inflows.FIRST .. l_cash_inflows.LAST
15966 LOOP
15967 IF(l_assets_indx = l_assoc_assets_count) THEN --LAST ASSET
15968 l_pp_non_sub_irr_tbl(pp_index).cash_inflows(i).cf_amount := l_cash_inflows(i).cf_amount - l_amount_tbl(i);
15969 ELSE
15970 IF(l_sum_assoc_assets_amt = 0) THEN
15971 l_amount := 0;
15972 ELSE
15973 l_amount := (assoc_asset_rec.amount/l_sum_assoc_assets_amt) * l_cash_inflows(i).cf_amount;
15974 l_amount := okl_accounting_util.round_amount(p_amount => l_amount,
15975 p_currency_code => l_currency);
15976 END IF;
15977 l_pp_non_sub_irr_tbl(pp_index).cash_inflows(i).cf_amount := l_amount;
15978 l_amount_tbl(i) := l_amount_tbl(i) + l_amount;
15979 END IF;
15980 END LOOP;
15981 END LOOP;
15982 END IF;
15983 END IF;
15984 END LOOP;
15985 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
15986 'Before Calling the API insert_quote_streams ');
15987 insert_quote_streams(p_api_version => p_api_version,
15988 p_init_msg_list => p_init_msg_list,
15989 x_return_status => l_return_status,
15990 x_msg_count => x_msg_count,
15991 x_msg_data => x_msg_data,
15992 p_quote_id => p_qte_id,
15993 p_quote_type => 'LEASE_QUOTE',
15994 p_currency => l_currency,
15995 p_pricing_param_tbl => l_pp_non_sub_irr_tbl);
15996 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
15997 'After Calling the API insert_quote_streams x_return_status= ' || x_return_status);
15998 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
15999 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
16000 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
16001 RAISE OKL_API.G_EXCEPTION_ERROR;
16002 END IF;
16003 -- Bug 7440199: Quote Streams ER: RGOOTY: End
16004 -- Pass the results back
16005 x_return_status := l_return_status;
16006 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
16007 x_msg_data => x_msg_data);
16008 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
16009 'end debug OKLRPIUB.pls call ' || LOWER(l_api_name) );
16010 EXCEPTION
16011 WHEN OKL_API.G_EXCEPTION_ERROR THEN
16012 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
16013 p_api_name => l_api_name,
16014 p_pkg_name => G_PKG_NAME,
16015 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
16016 x_msg_count => x_msg_count,
16017 x_msg_data => x_msg_data,
16018 p_api_type => g_api_type);
16019 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
16020 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
16021 p_api_name => l_api_name,
16022 p_pkg_name => G_PKG_NAME,
16023 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
16024 x_msg_count => x_msg_count,
16025 x_msg_data => x_msg_data,
16026 p_api_type => g_api_type);
16027 WHEN OTHERS THEN
16028 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
16029 p_api_name => l_api_name,
16030 p_pkg_name => G_PKG_NAME,
16031 p_exc_name => 'OTHERS',
16032 x_msg_count => x_msg_count,
16033 x_msg_data => x_msg_data,
16034 p_api_type => g_api_type);
16035 END price_standard_quote;
16036 END OKL_PRICING_UTILS_PVT;