[Home] [Help]
PACKAGE BODY: APPS.OKL_PRICING_UTILS_PVT
Source
1 PACKAGE BODY OKL_PRICING_UTILS_PVT AS
2 /* $Header: OKLRPIUB.pls 120.75 2008/05/16 11:26:32 rgooty noship $ */
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 RETURN NUMBER
2172 AS
2173 n_months NUMBER := 0;
2174 n_days NUMBER := 0;
2175 n_Years NUMBER := 0;
2176 l_start_year NUMBER;
2177 l_end_year NUMBER;
2178 l_start_month NUMBER;
2179 l_end_month NUMBER;
2180 l_start_day NUMBER;
2181 l_orig_start_day NUMBER;
2182 l_end_day NUMBER;
2183 l_start_date DATE;
2184 l_end_date DATE;
2185 l_temp_date DATE;
2186 n_leap_years NUMBER;
2187 l_day_convention VARCHAR2(10); -- Flag for 365 Year/360 Year based calculation
2188 l_mod_days NUMBER; -- Added by ssohal for Bug#6706568
2189 BEGIN
2190 x_return_status := OKL_API.G_RET_STS_SUCCESS;
2191 -- Validation: If Start Date cant be greater than End Date then return zero.
2192 l_start_date := trunc( p_start_date );
2193 l_end_date := trunc( p_end_date );
2194 IF( l_start_date > l_end_date )
2195 THEN
2196 RETURN 0;
2197 END IF;
2198 -- Based on p_day_convention calculate the days between Start and End dates
2199 IF p_days_in_month = 'ACTUAL' AND
2200 p_days_in_year = 'ACTUAL'
2201 THEN
2202 -- Calculations are based on the 365/366 Days/Year assumption
2203 n_days := floor( l_end_date - l_start_date );
2204
2205 ELSIF p_days_in_month = 'ACTUAL' AND
2206 p_days_in_year = '365'
2207 THEN
2208 -- Calculations are based on 365 days per year, even in a leap year
2209 -- Parse years ..
2210 l_start_year := to_char( p_start_date, 'YYYY' );
2211 --print( l_api_name || ': ' || 'l_start_year ' || l_start_year );
2212 IF MOD(l_start_year, 4) <> 0
2213 THEN
2214 -- Go to the next probable leap year
2215 l_start_year := l_start_year + ( 4 - MOD( l_start_year, 4 ) );
2216 END IF;
2217
2218 -- Check whether l_start_year is a leap year
2219 IF is_leap_year( l_start_year)
2220 THEN
2221 -- leap year, so leave it as it is
2222 NULL;
2223 ELSE
2224 l_start_year := l_start_year + 4;
2225 END IF;
2226 --print( l_api_name || ': ' || 'Starting with Leap Year ' || l_start_year );
2227 n_leap_years := 0;
2228 -- Form a date with 29-Feb-<l_start_year>
2229 l_temp_date := to_date( '29-02-' || to_char(l_start_year), 'DD-MM-YYYY' );
2230 --print( l_api_name || ': ' || 'l_temp_date ' || l_temp_date );
2231 WHILE l_temp_date >= l_start_date AND
2232 l_temp_date <= l_end_date
2233 LOOP
2234 -- Increment the Leap Year count
2235 n_leap_years := n_leap_years + 1;
2236 l_start_year := l_start_year + 4;
2237 -- Check whether l_start_year is a leap year
2238 IF is_leap_year( l_start_year )
2239 THEN
2240 -- leap year, so leave it as it is
2241 NULL;
2242 ELSE
2243 l_start_year := l_start_year + 4;
2244 END IF;
2245 -- Form a date with 29-Feb-<l_start_year>
2246 l_temp_date := to_date( '29-02-' || to_char(l_start_year), 'DD-MM-YYYY' );
2247 --print( l_api_name || ': ' || 'l_temp_date ' || l_temp_date );
2248 END LOOP;
2249 -- First, count the actual number of dates between l_start_date and l_end_date
2250 n_days := floor( l_end_date - l_start_date );
2251 -- Remove the number of leap years falling between
2252 n_days := n_days - n_leap_years;
2253 ELSIF p_days_in_month = '30' AND
2254 p_days_in_year = '360'
2255 THEN
2256 -- Parse years ..
2257 l_start_year := to_char( p_Start_date, 'YYYY' );
2258 l_end_year := to_char( p_end_date, 'YYYY' );
2259 -- Parse months ..
2260 l_start_month := to_char( p_start_date, 'MM' );
2261 l_end_month := to_char( p_end_date, 'MM' );
2262 -- Parse days ..
2263 l_start_day := to_char( p_start_date, 'DD' );
2264 l_orig_start_day := l_start_day;
2265 l_end_day := to_char( p_end_date, 'DD' );
2266 -- Calculation is based on the assumption of 30 days per month.
2267 n_Years := l_end_year - l_start_year;
2268 n_Months := n_Years * 12 - l_start_month + l_end_month;
2269
2270 -- IF D1 is last day of February,
2271 -- and D2 day > D1 day ( D2 day in ( 29, 30, 31) )
2272 -- then move D1 to 30
2273 -- If D2 is last day of February,
2274 -- If D1 day = D2 day and D1 month <> 2, then make D1 to 30
2275 -- If D1 is not the last day of february month in earlier years or D1 = D2
2276 -- Make D2 to 30
2277 -- IF d1 is last day of the non-February month move d1 to 30
2278 -- IF d2 is last day of the non-February month move d2 to 30
2279
2280 IF l_start_month = 2 AND l_start_date = LAST_DAY( l_start_date )
2281 AND l_end_day > l_start_day
2282 THEN
2283 -- Move D1 to 30
2284 l_start_day := 30;
2285 END IF;
2286 IF l_end_month = 2 AND l_end_date = LAST_DAY( l_end_date )
2287 THEN
2288 IF l_start_day = l_end_day AND l_start_month <> 2
2289 THEN
2290 l_start_day := 30;
2291 END IF;
2292 IF MOD(n_months, 12) <> 0 OR n_months = 0
2293 THEN
2294 l_end_day := 30;
2295 END IF;
2296 END IF;
2297
2298 IF l_start_month <> 2 AND l_start_date = LAST_DAY( l_start_date)
2299 THEN
2300 l_start_day := 30;
2301 END IF;
2302
2303 IF l_end_month <> 2 AND l_end_date = LAST_DAY( l_end_date)
2304 THEN
2305 l_end_day := 30;
2306 END IF;
2307 -- Calculate the number of days ...
2308 n_days := n_Months * 30 - l_start_day + l_end_day;
2309 ELSE
2310 x_return_Status := OKL_API.G_RET_STS_ERROR;
2311 RETURN 0;
2312 END IF;
2313
2314 -- Consider the last day incase of arrears Payments
2315 -- Start : Added by ssohal for Bug#6706568
2316 IF p_arrears = 'Y'
2317 THEN
2318 IF p_days_in_month = '30' AND
2319 p_days_in_year = '360'
2320 THEN
2321 l_mod_days := MOD(n_days,30);
2322 IF ( l_mod_days <> 0 OR n_days = 0 ) AND ( l_orig_start_day <> 31 )
2323 THEN
2324 n_days := n_days + 1;
2325 END IF;
2326 ELSE
2327 n_days := n_days + 1;
2328 END IF;
2329 END IF;
2330 -- End : Added by ssohal for Bug#6706568
2331
2332 -- Set the OUT parameters and return
2333 x_return_status := 'S';
2334 RETURN n_days;
2335 EXCEPTION
2336 WHEN OKL_API.G_EXCEPTION_ERROR THEN
2337 x_return_status := G_RET_STS_ERROR;
2338 RETURN -1; -- get_day_count returns negative in case of error/failure
2339 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
2340 x_return_status := G_RET_STS_UNEXP_ERROR;
2341 RETURN -1; -- get_day_count returns negative in case of error/failure
2342 WHEN OTHERS THEN
2343 OKL_API.SET_MESSAGE (
2344 p_app_name => G_APP_NAME,
2345 p_msg_name => G_DB_ERROR,
2346 p_token1 => G_PROG_NAME_TOKEN,
2347 p_token1_value => 'GET_DAY_COUNT',
2348 p_token2 => G_SQLCODE_TOKEN,
2349 p_token2_value => sqlcode,
2350 p_token3 => G_SQLERRM_TOKEN,
2351 p_token3_value => sqlerrm);
2352 x_return_status := G_RET_STS_UNEXP_ERROR;
2353 RETURN -1; -- get_day_count returns negative in case of error/failure
2354 END get_day_count;
2355
2356 PROCEDURE compute_irr(
2357 p_api_version IN NUMBER,
2358 p_init_msg_list IN VARCHAR2,
2359 x_return_status OUT NOCOPY VARCHAR2,
2360 x_msg_count OUT NOCOPY NUMBER,
2361 x_msg_data OUT NOCOPY VARCHAR2,
2362 p_start_date IN DATE,
2363 p_day_count_method IN VARCHAR2,
2364 p_currency_code IN VARCHAR2,
2365 p_pricing_method IN VARCHAR2,
2366 p_initial_guess IN NUMBER,
2367 px_pricing_parameter_tbl IN OUT NOCOPY pricing_parameter_tbl_type,
2368 px_irr IN OUT NOCOPY NUMBER,
2369 x_payment OUT NOCOPY NUMBER)
2370 AS
2371 -- Local Variables
2372 l_api_version CONSTANT NUMBER DEFAULT 1.0;
2373 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_irr';
2374 l_return_status VARCHAR2(1);
2375 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
2376 || G_PKG_NAME || '.' || UPPER(l_api_name);
2377 l_debug_enabled VARCHAR2(10);
2378 is_debug_procedure_on BOOLEAN;
2379 is_debug_statement_on BOOLEAN;
2380 -- Cursor Definitions
2381 CURSOR get_precision_csr(p_currency_code VARCHAR2)
2382 IS
2383 SELECT NVL(cur.precision,0) precision
2384 FROM fnd_currencies cur
2385 WHERE cur.currency_code = p_currency_code;
2386 -- Local Variables/Constants Declaration
2387 l_cash_inflow_strms_tbl cash_inflows_tbl_type;
2388 l_cash_outflow_strms_tbl cash_inflows_tbl_type;
2389 l_residuals_tbl cash_inflows_tbl_type;
2390 l_days_in_month VARCHAR2(30);
2391 l_days_in_year VARCHAR2(30);
2392 cin_index NUMBER; -- Index for Cash Inflows
2393 cout_index NUMBER; -- Index for Cash Outflows
2394 res_index NUMBER; -- Index for Residuals Table
2395 l_time_zero_cost NUMBER;
2396 l_adv_inf_payment NUMBER;
2397 l_precision NUMBER;
2398 l_irr_limit NUMBER;
2399 l_irr NUMBER;
2400 l_npv NUMBER;
2401 l_npv_sign NUMBER;
2402 l_increment_rate NUMBER;
2403 l_abs_incr_rate NUMBER;
2404 n_iterations NUMBER;
2405 l_cf_dpp NUMBER;
2406 l_cf_ppy NUMBER;
2407 l_cf_amount NUMBER;
2408 l_cf_date DATE;
2409 l_days_in_future NUMBER;
2410 l_periods NUMBER;
2411 l_rate NUMBER;
2412 l_prev_irr NUMBER;
2413 l_prev_npv NUMBER;
2414 l_prev_npv_sign NUMBER;
2415 l_prev_incr_sign NUMBER;
2416 l_positive_npv_irr NUMBER;
2417 l_negative_npv_irr NUMBER;
2418 l_positive_npv NUMBER;
2419 l_negative_npv NUMBER;
2420 l_crossed_zero VARCHAR2(1);
2421 l_irr_decided VARCHAR2(1);
2422 l_temp_amount NUMBER; -- Debug Purpose
2423 l_disc_rate NUMBER; -- Debug Purpose
2424 l_term_interest NUMBER;
2425 l_acc_term_interest NUMBER;
2426 i NUMBER; -- Used as Index
2427 l_period_start_date DATE;
2428 l_period_end_date DATE;
2429 BEGIN
2430 l_return_status := OKL_API.G_RET_STS_SUCCESS;
2431 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
2432 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
2433
2434 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
2435 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
2436 -- check for logging on STATEMENT level
2437 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
2438 -- Call START_ACTIVITY to create savepoint, check compatibility and initialize message list
2439 l_return_status := OKL_API.START_ACTIVITY(
2440 p_api_name => l_api_name,
2441 p_pkg_name => G_PKG_NAME,
2442 p_init_msg_list => p_init_msg_list,
2443 l_api_version => l_api_version,
2444 p_api_version => p_api_version,
2445 p_api_type => g_api_type,
2446 x_return_status => x_return_status);
2447 --Check if activity started successfully
2448 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2449 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2450 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2451 RAISE OKL_API.G_EXCEPTION_ERROR;
2452 END IF;
2453 -- Validations here ..
2454 get_days_in_year_and_month(
2455 p_day_count_method => p_day_count_method,
2456 x_days_in_month => l_days_in_month,
2457 x_days_in_year => l_days_in_year,
2458 x_return_status => l_return_status);
2459 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2460 'After get_days_in_year_and_month ' || l_return_status);
2461 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2462 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2463 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2464 RAISE OKL_API.G_EXCEPTION_ERROR;
2465 END IF;
2466 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2467 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
2468
2469 -- 1/ Fetch the Start Date
2470 IF p_start_date IS NULL
2471 THEN
2472 -- Show the error message
2473 RAISE OKL_API.G_EXCEPTION_ERROR;
2474 END IF; -- IF p_start_date
2475 IF px_pricing_parameter_tbl.COUNT > 0
2476 THEN
2477 -- Do Nothing
2478 NULL;
2479 ELSE
2480 -- Cant proceed.
2481 RAISE OKL_API.G_EXCEPTION_ERROR;
2482 END IF; -- IF px_pricing_parameter_tbl.COUNT > 0
2483
2484 IF p_pricing_method = 'SY' OR
2485 p_pricing_method = 'TR'
2486 THEN
2487 -- Do Nothing
2488 NULL;
2489 ELSE
2490 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2491 'Compute_irr currently supports only Solve for Yields and Target Rate Pricing Scenarios only ' );
2492 RAISE OKL_API.G_EXCEPTION_ERROR;
2493 END IF;
2494 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2495 'Start Date =' || p_start_date );
2496 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2497 'Pricing Method =' || p_pricing_method );
2498 -- Starting to Initialize things .....
2499 l_time_zero_cost := 0; -- Time Zero Outflows
2500 l_adv_inf_payment := 0; -- Cash Inflow Amounts
2501 cin_index := 1;
2502 cout_index := 1;
2503 res_index := 1;
2504 -- Consolidate all the Cash and Residual Inflows per each
2505 -- pricing parameter record with line_type as FREE_FORM1 ..
2506 i := px_pricing_parameter_tbl.FIRST;
2507 WHILE i <= px_pricing_parameter_tbl.LAST
2508 LOOP
2509 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2510 'Time Zero Cost[SUM] | Financed Amount| Subsidy | Down Payment | Tradein | Capitalized Fee Amt' );
2511 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2512 round( l_time_zero_cost, 4) || '|' || round( px_pricing_parameter_tbl(i).financed_amount, 4 )
2513 || '|' || round( px_pricing_parameter_tbl(i).subsidy, 4 ) || '|' || round( px_pricing_parameter_tbl(i).down_payment, 4 )
2514 || '|' || round( px_pricing_parameter_tbl(i).trade_in, 4) || '|' || round( px_pricing_parameter_tbl(i).cap_fee_amount, 4) );
2515 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2516 'compute_irr: line_type ' || px_pricing_parameter_tbl(i).line_type );
2517 IF px_pricing_parameter_tbl(i).line_type = 'FREE_FORM1'
2518 THEN
2519 -- Handling the Cash inflows Details
2520 IF px_pricing_parameter_tbl(i).cash_inflows IS NOT NULL AND
2521 px_pricing_parameter_tbl(i).cash_inflows.COUNT > 0
2522 THEN
2523 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2524 'Cash Inflows: -------------------------------------------------------------' );
2525 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2526 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date | LOCKED');
2527 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2528 px_pricing_parameter_tbl(i).cash_inflows.LAST
2529 LOOP
2530 l_cash_inflow_strms_tbl( cin_index ) :=
2531 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2532 -- Need to calculate just the cf_days
2533 l_cash_inflow_strms_tbl(cin_index).cf_days :=
2534 get_day_count(
2535 p_days_in_month => l_days_in_month,
2536 p_days_in_year => l_days_in_year,
2537 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2538 p_end_date => l_cash_inflow_strms_tbl(cin_index).cf_date,
2539 p_arrears => l_cash_inflow_strms_tbl(cin_index).is_arrears,
2540 x_return_status => l_return_status);
2541 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2542 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2543 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2544 RAISE OKL_API.G_EXCEPTION_ERROR;
2545 END IF;
2546 -- cf_dpp, cf_ppy, cf_periods are being populated
2547 IF p_day_count_method <> 'THIRTY'
2548 THEN
2549 -- Pricing Day convention is not THIRTY day based !!
2550 -- So, override the existing the cf_dpp here !
2551 IF l_cash_inflow_strms_tbl(cin_index).is_arrears = 'Y'
2552 THEN
2553 -- cf_date represents end of the period
2554 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2555 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2556 ELSE
2557 -- cf_date represents start of the period
2558 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2559 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2560 END IF;
2561 l_cash_inflow_strms_tbl(cin_index).cf_dpp :=
2562 get_day_count(
2563 p_days_in_month => l_days_in_month,
2564 p_days_in_year => l_days_in_year,
2565 p_start_date => l_period_start_date, -- Start date mentioned in the Header rec
2566 p_end_date => l_period_end_date,
2567 p_arrears => 'Y',
2568 x_return_status => l_return_status);
2569 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2570 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2571 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2572 RAISE OKL_API.G_EXCEPTION_ERROR;
2573 END IF;
2574 END IF; -- If p_day_convention <> 'THIRTY'
2575 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2576 ROUND(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_date
2577 || '|' || round(l_cash_inflow_strms_tbl(cin_index).cf_amount,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_days
2578 || '|' || l_cash_inflow_strms_tbl(cin_index).is_Arrears || '|' || l_cash_inflow_strms_tbl(cin_index).is_stub
2579 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_dpp || '|' || l_cash_inflow_strms_tbl(cin_index).cf_ppy
2580 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date || ' | ' ||
2581 l_cash_inflow_strms_tbl(cin_index).locked_amt);
2582 -- Validations regarding either of the Payment amount or rate should be present
2583 -- can be placed here ... Think about it ..
2584 cin_index := cin_index + 1;
2585 END LOOP;
2586 END IF;
2587 -- Handling the Residual Inflows
2588 IF px_pricing_parameter_tbl(i).residual_inflows IS NOT NULL AND
2589 px_pricing_parameter_tbl(i).residual_inflows.COUNT > 0
2590 THEN
2591 -- Calculation of the Residual Value Inflow Amounts
2592 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2593 'Residuals: -----------------------------------' || px_pricing_parameter_tbl(i).residual_inflows.COUNT );
2594 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2595 'Rate | Date | Residual Amount | Days | Arrears | cf_dpp | cf_ppy | cf_period_start_end_date| LOCKED');
2596 FOR t_index IN px_pricing_parameter_tbl(i).residual_inflows.FIRST ..
2597 px_pricing_parameter_tbl(i).residual_inflows.LAST
2598 LOOP
2599 l_residuals_tbl( res_index ) :=
2600 px_pricing_parameter_tbl(i).residual_inflows(t_index);
2601 -- The wrapper API has to take the responsibility of passing the
2602 -- cf_date, cf_dpp, cf_ppy, cf_amount per each residual record
2603 get_rate(
2604 p_date => l_residuals_tbl(res_index).cf_date,
2605 p_cf_strms_tbl => px_pricing_parameter_tbl(i).cash_inflows,
2606 x_rate => l_residuals_tbl(res_index).cf_rate,
2607 x_return_status => l_return_status);
2608 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2609 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2610 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2611 RAISE OKL_API.G_EXCEPTION_ERROR;
2612 END IF;
2613 l_residuals_tbl(res_index).cf_days :=
2614 get_day_count(
2615 p_days_in_month => l_days_in_month,
2616 p_days_in_year => l_days_in_year,
2617 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2618 p_end_date => l_residuals_tbl(res_index).cf_date,
2619 p_arrears => 'Y', -- Residuals are always obtained at the end of the term
2620 x_return_status => l_return_status);
2621 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2622 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2623 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2624 RAISE OKL_API.G_EXCEPTION_ERROR;
2625 END IF;
2626
2627 IF p_day_count_method <> 'THIRTY'
2628 THEN
2629 -- Calculating the cf_dpp for the residual values
2630 l_period_end_date := l_residuals_tbl(res_index).cf_date;
2631 okl_stream_generator_pvt.add_months_new(
2632 p_start_date => l_period_end_date,
2633 p_months_after => -12 / l_residuals_tbl(res_index).cf_ppy, -- Will get the frequency for us
2634 x_date => l_period_start_date,
2635 x_return_status => l_return_status);
2636 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2637 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2638 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2639 RAISE OKL_API.G_EXCEPTION_ERROR;
2640 END IF;
2641
2642 l_period_start_date := l_period_start_date + 1;
2643 l_residuals_tbl(res_index).cf_period_start_end_date := l_period_start_date;
2644 -- Residual value will be calculated based on the
2645 -- number of days between the l_period_start_date and l_period_end_date !!
2646 l_residuals_tbl(res_index).cf_dpp :=
2647 get_day_count(
2648 p_days_in_month => l_days_in_month,
2649 p_days_in_year => l_days_in_year,
2650 p_start_date => l_period_start_date, -- Start date mentioned in the Header rec
2651 p_end_date => l_period_end_date,
2652 p_arrears => 'Y',
2653 x_return_status => l_return_status);
2654 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2655 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2656 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2657 RAISE OKL_API.G_EXCEPTION_ERROR;
2658 END IF;
2659 END IF; -- IF p_day_count_method = 'THIRTY'
2660 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2661 round(l_residuals_tbl(res_index).cf_rate,4) || '|' || l_residuals_tbl(res_index).cf_date
2662 || '|' || round(l_residuals_tbl(res_index).cf_amount,4) || '|' || l_residuals_tbl(res_index).cf_days
2663 || '|' || l_residuals_tbl(res_index).cf_purpose || '|' || l_residuals_tbl(res_index).is_Arrears
2664 || '|' || l_residuals_tbl(res_index).cf_dpp || '|' || l_residuals_tbl(res_index).cf_ppy
2665 || '|' || l_residuals_tbl(res_index).cf_period_start_end_date || '|' || l_residuals_tbl(res_index).locked_amt);
2666 -- Increment the res_index
2667 res_index := res_index + 1;
2668 END LOOP;
2669 END IF;
2670 l_time_zero_cost := l_time_zero_cost +
2671 nvl( px_pricing_parameter_tbl(i).financed_amount, 0 ) -
2672 nvl( px_pricing_parameter_tbl(i).subsidy, 0 ) -
2673 nvl( px_pricing_parameter_tbl(i).trade_in, 0 ) -
2674 nvl( px_pricing_parameter_tbl(i).down_payment, 0 ) +
2675 nvl( px_pricing_parameter_tbl(i).cap_fee_amount, 0 );
2676 -- Code to handle various possible fees/service other than the FREE_FORM1
2677 ELSIF px_pricing_parameter_tbl(i).payment_type = 'INCOME'
2678 THEN
2679 -- Assumption is that the outflow amount is placed in the
2680 -- financed_amount. And the inflows are being passed in the l_cash_inflow_strms_tbl
2681 l_time_zero_cost := l_time_zero_cost + nvl(px_pricing_parameter_tbl(i).financed_amount,0);
2682
2683 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',px_pricing_parameter_tbl(i).payment_type ||
2684 ' Inflows: -------------------------------------------------------------' );
2685 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2686 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date | LOCKED');
2687 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2688 px_pricing_parameter_tbl(i).cash_inflows.LAST
2689 LOOP
2690 l_cash_inflow_strms_tbl( cin_index ) :=
2691 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2692 -- Need to calculate just the cf_days
2693 l_cash_inflow_strms_tbl(cin_index).cf_days :=
2694 get_day_count(
2695 p_days_in_month => l_days_in_month,
2696 p_days_in_year => l_days_in_year,
2697 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2698 p_end_date => l_cash_inflow_strms_tbl(cin_index).cf_date,
2699 p_arrears => l_cash_inflow_strms_tbl(cin_index).is_arrears,
2700 x_return_status => l_return_status);
2701 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2702 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2703 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2704 RAISE OKL_API.G_EXCEPTION_ERROR;
2705 END IF;
2706 -- cf_dpp, cf_ppy, cf_periods are being populated
2707 IF p_day_count_method <> 'THIRTY'
2708 THEN
2709 -- Pricing Day convention is not THIRTY day based !!
2710 -- So, override the existing the cf_dpp here !
2711 IF l_cash_inflow_strms_tbl(cin_index).is_arrears = 'Y'
2712 THEN
2713 -- cf_date represents end of the period
2714 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2715 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2716 ELSE
2717 -- cf_date represents start of the period
2718 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2719 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2720 END IF;
2721 l_cash_inflow_strms_tbl(cin_index).cf_dpp :=
2722 get_day_count(
2723 p_days_in_month => l_days_in_month,
2724 p_days_in_year => l_days_in_year,
2725 p_start_date => l_period_start_date, -- Start date mentioned in the Header rec
2726 p_end_date => l_period_end_date,
2727 p_arrears => 'Y',
2728 x_return_status => l_return_status);
2729 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2730 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2731 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2732 RAISE OKL_API.G_EXCEPTION_ERROR;
2733 END IF;
2734 END IF; -- If p_day_convention <> 'THIRTY'
2735 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2736 round(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_date
2737 || '|' || round(l_cash_inflow_strms_tbl(cin_index).cf_amount,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_days
2738 || '|' || l_cash_inflow_strms_tbl(cin_index).is_Arrears || '|' || l_cash_inflow_strms_tbl(cin_index).is_stub
2739 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_dpp || '|' || l_cash_inflow_strms_tbl(cin_index).cf_ppy
2740 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date
2741 || '|' || l_cash_inflow_strms_tbl(cin_index).locked_amt);
2742 -- Validations regarding either of the Payment amount or rate should be present
2743 -- can be placed here ... Think about it ..
2744 cin_index := cin_index + 1;
2745 END LOOP; -- Loop on the px_pricing_parameter_tbl(i).cash_inflows
2746 -- Handling the Outflows
2747 ELSIF px_pricing_parameter_tbl(i).payment_type = 'EXPENSE'
2748 THEN
2749 -- One time expense amount is being passed in the financed_amount
2750 -- Recurring expenses are being passed as cash inflows. (Reverse the sign here)
2751 l_time_zero_cost := l_time_zero_cost + nvl(px_pricing_parameter_tbl(i).financed_amount,0);
2752 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', px_pricing_parameter_tbl(i).payment_type ||
2753 'Handling Outflows: -------------------------------------------------------------' );
2754 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2755 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date|LOCKED');
2756 IF px_pricing_parameter_tbl(i).cash_inflows.COUNT > 0
2757 THEN
2758 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2759 px_pricing_parameter_tbl(i).cash_inflows.LAST
2760 LOOP
2761 l_cash_outflow_strms_tbl( cout_index ) :=
2762 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2763 -- Checking that the amount should be negative, as they are expenses
2764 -- and expenses are always considered negative from Lessor perspective !!
2765 IF l_cash_outflow_strms_tbl(cout_index).cf_amount > 0
2766 THEN
2767 l_cash_outflow_strms_tbl(cout_index).cf_amount := -1 * l_cash_outflow_strms_tbl(cout_index).cf_amount;
2768 END IF;
2769 -- calculate the cf_days
2770 l_cash_outflow_strms_tbl(cout_index).cf_days :=
2771 get_day_count(
2772 p_days_in_month => l_days_in_month,
2773 p_days_in_year => l_days_in_year,
2774 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2775 p_end_date => l_cash_outflow_strms_tbl(cout_index).cf_date,
2776 p_arrears => l_cash_outflow_strms_tbl(cout_index).is_arrears,
2777 x_return_status => l_return_status);
2778 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2779 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2780 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2781 RAISE OKL_API.G_EXCEPTION_ERROR;
2782 END IF;
2783 -- cf_dpp, cf_ppy, cf_periods are being populated
2784 IF p_day_count_method <> 'THIRTY'
2785 THEN
2786 -- Pricing Day convention is not THIRTY day based !!
2787 -- So, override the existing the cf_dpp here !
2788 IF l_cash_outflow_strms_tbl(cout_index).is_arrears = 'Y'
2789 THEN
2790 -- cf_date represents end of the period
2791 l_period_start_date := l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date;
2792 l_period_end_date := l_cash_outflow_strms_tbl(cout_index).cf_date;
2793 ELSE
2794 -- cf_date represents start of the period
2795 l_period_start_date := l_cash_outflow_strms_tbl(cout_index).cf_date;
2796 l_period_end_date := l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date;
2797 END IF;
2798 l_cash_outflow_strms_tbl(cout_index).cf_dpp :=
2799 get_day_count(
2800 p_days_in_month => l_days_in_month,
2801 p_days_in_year => l_days_in_year,
2802 p_start_date => l_period_start_date,
2803 p_end_date => l_period_end_date,
2804 p_arrears => 'Y',
2805 x_return_status => l_return_status);
2806 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2807 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2808 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2809 RAISE OKL_API.G_EXCEPTION_ERROR;
2810 END IF;
2811 END IF; -- If p_day_convention <> 'THIRTY'
2812 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2813 ROUND(l_cash_outflow_strms_tbl(cout_index).cf_rate,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_date
2814 || '|' || round(l_cash_outflow_strms_tbl(cout_index).cf_amount,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_days
2815 || '|' || l_cash_outflow_strms_tbl(cout_index).is_Arrears || '|' || l_cash_outflow_strms_tbl(cout_index).is_stub
2816 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_dpp || '|' || l_cash_outflow_strms_tbl(cout_index).cf_ppy
2817 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date
2818 || '|' || l_cash_outflow_strms_tbl(cout_index).locked_amt);
2819 -- Validations regarding either of the Payment amount or rate should be present
2820 -- can be placed here ... Think about it ..
2821 cout_index := cout_index + 1;
2822 END LOOP; -- Loop on the px_pricing_parameter_tbl(i).cash_inflows
2823 END IF; -- If cash_inflows.count
2824 -- Handling the Outflows
2825 ELSIF px_pricing_parameter_tbl(i).line_type = 'SECDEPOSIT'
2826 THEN
2827 -- Security Deposit is a different kind of Fee. Need to handle that differently.
2828 -- Security Deposit is kind of payment, which is considered intially as inflow
2829 -- and at the end of the term, it is considered as outflow !!
2830 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2831 px_pricing_parameter_tbl(i).line_type ||
2832 'Handling Security Deposit Streams: -------------------------------------------------------------' );
2833 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2834 'Rate | Date | Amount | Days | Arrears | Stub | cf_dpp | cf_ppy | cf_period_start_end_date|LOCKED');
2835 FOR t_index IN px_pricing_parameter_tbl(i).cash_inflows.FIRST ..
2836 px_pricing_parameter_tbl(i).cash_inflows.LAST
2837 LOOP
2838
2839 l_cash_inflow_strms_tbl( cin_index ) :=
2840 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2841 -- calculate the cf_days
2842 l_cash_inflow_strms_tbl(cin_index).cf_days :=
2843 get_day_count(
2844 p_days_in_month => l_days_in_month,
2845 p_days_in_year => l_days_in_year,
2846 p_start_date => p_start_date, -- Start date mentioned in the Header rec
2847 p_end_date => l_cash_inflow_strms_tbl(cin_index).cf_date,
2848 p_arrears => 'N',
2849 x_return_status => l_return_status);
2850 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2851 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2852 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2853 RAISE OKL_API.G_EXCEPTION_ERROR;
2854 END IF;
2855
2856 -- cf_dpp, cf_ppy, cf_periods are being populated
2857 IF p_day_count_method <> 'THIRTY'
2858 THEN
2859 -- Pricing Day convention is not THIRTY day based !!
2860 -- So, override the existing the cf_dpp here !
2861 IF l_cash_inflow_strms_tbl(cin_index).is_arrears = 'Y'
2862 THEN
2863 -- cf_date represents end of the period
2864 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2865 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2866 ELSE
2867 -- cf_date represents start of the period
2868 l_period_start_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
2869 l_period_end_date := l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date;
2870 END IF;
2871 l_cash_inflow_strms_tbl(cin_index).cf_dpp :=
2872 get_day_count(
2873 p_days_in_month => l_days_in_month,
2874 p_days_in_year => l_days_in_year,
2875 p_start_date => l_period_start_date,
2876 p_end_date => l_period_end_date,
2877 p_arrears => 'Y',
2878 x_return_status => l_return_status);
2879 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2880 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2881 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2882 RAISE OKL_API.G_EXCEPTION_ERROR;
2883 END IF;
2884 END IF; -- If p_day_convention <> 'THIRTY'
2885 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2886 ROUND(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_date
2887 || '|' || round(l_cash_inflow_strms_tbl(cin_index).cf_amount,4) || '|' || l_cash_inflow_strms_tbl(cin_index).cf_days
2888 || '|' || l_cash_inflow_strms_tbl(cin_index).is_Arrears || '|' || l_cash_inflow_strms_tbl(cin_index).is_stub
2889 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_dpp || '|' || l_cash_inflow_strms_tbl(cin_index).cf_ppy
2890 || '|' || l_cash_inflow_strms_tbl(cin_index).cf_period_start_end_date
2891 || '|' || l_cash_inflow_strms_tbl(cin_index).locked_amt);
2892 l_cash_outflow_strms_tbl( cout_index ) :=
2893 px_pricing_parameter_tbl(i).cash_inflows(t_index);
2894 -- Checking that the amount should be negative, as they are expenses
2895 -- and expenses are always considered negative from Lessor perspective !!
2896 IF l_cash_outflow_strms_tbl(cout_index).cf_amount > 0
2897 THEN
2898 l_cash_outflow_strms_tbl(cout_index).cf_amount := -1 * l_cash_outflow_strms_tbl(cout_index).cf_amount;
2899 END IF;
2900 -- calculate the cf_days
2901 l_cash_outflow_strms_tbl(cout_index).cf_days :=
2902 get_day_count(
2903 p_days_in_month => l_days_in_month,
2904 p_days_in_year => l_days_in_year,
2905 p_start_date => p_start_date,
2906 p_end_date => px_pricing_parameter_tbl(i).line_end_date,
2907 p_arrears => 'N',
2908 x_return_status => l_return_status);
2909 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2910 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2911 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
2912 RAISE OKL_API.G_EXCEPTION_ERROR;
2913 END IF;
2914 -- Use the cash inflows cf_dpp as the cf_dpp for outflows too,
2915 -- instead of calculation of the cf_dpp for ACT365/ ACTUAL day count methods pricing
2916 l_cash_outflow_strms_tbl(cout_index).cf_dpp :=
2917 l_cash_inflow_strms_tbl(cin_index).cf_dpp;
2918 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2919 round(l_cash_outflow_strms_tbl(cout_index).cf_rate,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_date
2920 || '|' || round(l_cash_outflow_strms_tbl(cout_index).cf_amount,4) || '|' || l_cash_outflow_strms_tbl(cout_index).cf_days
2921 || '|' || l_cash_outflow_strms_tbl(cout_index).is_Arrears || '|' || l_cash_outflow_strms_tbl(cout_index).is_stub
2922 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_dpp || '|' || l_cash_outflow_strms_tbl(cout_index).cf_ppy
2923 || '|' || l_cash_outflow_strms_tbl(cout_index).cf_period_start_end_date
2924 || '|' || l_cash_outflow_strms_tbl(cout_index).locked_amt);
2925 -- Increment the cin_index and cout_indexes
2926 cin_index := cin_index + 1;
2927 cout_index := cout_index + 1;
2928 END LOOP; -- Loop on the px_pricing_parameter_tbl(i).cash_inflows
2929 END IF; -- If on the line_type
2930 -- Increment index i ..
2931 i := px_pricing_parameter_tbl.NEXT(i);
2932 END LOOP;
2933 -- Loop thru' the inflows and sum the amount
2934 IF l_cash_inflow_strms_tbl.COUNT > 0
2935 THEN
2936 FOR t_in in l_cash_inflow_strms_tbl.FIRST .. l_cash_inflow_strms_tbl.LAST
2937 LOOP
2938 IF l_cash_inflow_strms_tbl(t_in).cf_date <= p_start_date
2939 THEN
2940 -- Sum the amount
2941 l_adv_inf_payment := l_adv_inf_payment + nvl( l_cash_inflow_strms_tbl(t_in).cf_amount, 0 );
2942 END IF;
2943 END LOOP;
2944 END IF;
2945 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2946 'Rent Inflows on or before the Start Date ' || round(l_adv_inf_payment,4) );
2947
2948 -- 20/ Validation: Sum of all the inflows should not exceed the Total Time zero cost
2949 IF l_adv_inf_payment >= l_time_zero_cost
2950 THEN
2951 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2952 'Unable to calculate the IRR l_adv_inf_payment= ' || round(l_adv_inf_payment, 4)
2953 || 'l_time_zero_cost = ' || round( l_time_zero_cost, 4) );
2954 OKL_API.SET_MESSAGE (
2955 p_app_name => G_APP_NAME,
2956 p_msg_name => 'OKL_IRR_CALC_INF_LOOP',
2957 p_token1 => 'ADV_AMOUNT',
2958 p_token1_value => l_adv_inf_payment,
2959 p_token2 => 'CAPITAL_AMOUNT',
2960 p_token2_value => l_time_zero_cost);
2961 RAISE OKL_API.G_EXCEPTION_ERROR;
2962 END IF;
2963 -- 30/ Validate Currency code and Precision ...
2964 IF p_currency_code IS NOT NULL
2965 THEN
2966 OPEN get_precision_csr(p_currency_code);
2967 FETCH get_precision_csr INTO l_precision;
2968 CLOSE get_precision_csr;
2969 END IF;
2970 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2971 'Precision=' || nvl(l_precision, 1) );
2972 -- If Precision is null throw error and return
2973 IF l_precision IS NULL
2974 THEN
2975 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2976 ': ' || 'Precision is not mentioned !' );
2977 OKL_API.set_message(
2978 p_app_name => G_APP_NAME,
2979 p_msg_name => OKL_API.G_REQUIRED_VALUE,
2980 p_token1 => OKL_API.G_COL_NAME_TOKEN,
2981 p_token1_value => 'CURRENCY_CODE');
2982 RAISE OKL_API.G_EXCEPTION_ERROR;
2983 END IF;
2984 -- Setting up all for the MAIN Loop ....
2985 -- Setting the IRR limit
2986 l_irr_limit := ROUND(NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000), 0)/100;
2987 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
2988 ': ' || 'IRR Limit=' || l_irr_limit );
2989 -- n_iterations represent the number of Iteration we are in ..
2990 n_iterations := 0;
2991 l_acc_term_interest := 0;
2992 l_increment_rate := 0.1; -- 10% increment
2993 l_crossed_zero := 'N'; -- Y/N Flags
2994 l_irr_decided := 'N'; -- Y/N Flags
2995 l_irr := nvl(p_initial_guess,0.1);
2996 -- Forming the Equation (1)
2997 -- pvCF + pvR - ( C - S - D - T )= 0
2998 -- Until now l_time_zero_cost = C - S - D - T + Cap. Fee Amt, so negate l_time_zero_cost
2999 l_time_zero_cost := -1 * l_time_zero_cost;
3000 -- As we see in Equation (1) only pvR and pvCF are based on the rate we assume/calculate
3001 -- Hence we calculate them per loop with the current l_irr
3002 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3003 'Time Zero Cost ' || round(l_time_zero_cost,4) );
3004 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3005 'Advance Inflows Amount' || round(l_adv_inf_payment,4) );
3006 LOOP
3007 -- Increment the current iteration
3008 n_iterations := n_iterations + 1;
3009 -- Start with the Net Present value as the l_time_zero_cost
3010 l_npv := l_time_zero_cost;
3011 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','Iteration # ' || n_iterations);
3012 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','Net Present Value ' || round(l_npv,4) );
3013 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','l_irr ' || l_irr );
3014 -- Handling the Present Value of the Residuals
3015 IF l_residuals_tbl.COUNT > 0
3016 THEN
3017 res_index := l_residuals_tbl.FIRST;
3018 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3019 '--- Residual Values ------------------------------------------------------------' );
3020 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3021 'DPP | PPY | Days | Periods | Res. Amount | Rate | Discount Rate | Present Value' );
3022 WHILE res_index <= l_residuals_tbl.LAST
3023 LOOP
3024 l_cf_dpp := l_residuals_tbl(res_index).cf_dpp;
3025 l_cf_ppy := l_residuals_tbl(res_index).cf_ppy;
3026 l_cf_amount := l_residuals_tbl(res_index).cf_amount;
3027 l_cf_date := l_residuals_tbl(res_index).cf_date;
3028 l_days_in_future := l_residuals_tbl(res_index).cf_days;
3029 IF l_cf_dpp <> 0
3030 THEN
3031 l_periods := l_days_in_future / l_cf_dpp;
3032 ELSE
3033 l_periods := 0;
3034 END IF;
3035 -- This is the variable you will be change based on the Pricing Method ..
3036 -- Eg., For 'Target Payment' you will be using l_irr as l_rate
3037 -- For 'Target Rate' you will be using the l_residuals_tbl(res_index).cf_rate ..
3038 IF p_pricing_method = 'SY'
3039 THEN
3040 l_rate := l_irr;
3041 ELSE
3042 l_rate := l_residuals_tbl(res_index).cf_rate;
3043 END IF;
3044 -- Now, calculate the Present Value of the Residual Value Cash Inflow
3045 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3046 THEN
3047 OKL_API.SET_MESSAGE (
3048 p_app_name => G_APP_NAME,
3049 p_msg_name => 'OKL_IRR_ZERO_DIV');
3050 l_return_status := OKL_API.G_RET_STS_ERROR;
3051 RAISE OKL_API.G_EXCEPTION_ERROR;
3052 END IF;
3053 l_disc_rate := 1 / POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3054 l_temp_amount := l_cf_amount * l_disc_rate;
3055 l_npv := l_npv + nvl(l_temp_amount,0);
3056 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3057 round( l_cf_dpp,4) || ' | ' || l_cf_ppy || ' | ' || l_days_in_future
3058 || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3059 || ' | ' || round(l_rate,4) || ' | ' || round(l_disc_rate,4)
3060 || ' | ' || round(l_temp_amount, 4) );
3061 -- Increment the Index of the Residuals Table
3062 res_index := l_residuals_tbl.NEXT(res_index);
3063 END LOOP;
3064 END IF;
3065 -- Handling the Present Value of the Cash Inflows
3066 IF l_cash_inflow_strms_tbl.COUNT > 0
3067 THEN
3068 IF p_pricing_method = 'SY'
3069 THEN
3070 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3071 'Cash Inflows -------------------------------------------------------------' );
3072 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3073 'DPP | PPY | Periods | Inflow Amount | Rate | Discount Rate | Present Value' );
3074 ELSE
3075 -- Pricing Method is TR
3076 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3077 'Targetted Net Present Value: ' || round(l_npv,0) );
3078 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3079 'Cash Inflows ------------------------------------------' );
3080 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3081 '--- |---- |-------- |--------| Discount | Accumulated |' );
3082 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3083 'DPP | PPY | Days | Periods | Rate | Rate/Term | Interest |' );
3084 END IF;
3085 cin_index := l_cash_inflow_strms_tbl.FIRST;
3086 WHILE cin_index <= l_cash_inflow_strms_tbl.LAST
3087 LOOP
3088 l_cf_dpp := l_cash_inflow_strms_tbl(cin_index).cf_dpp;
3089 l_cf_ppy := l_cash_inflow_strms_tbl(cin_index).cf_ppy;
3090 l_cf_amount := l_cash_inflow_strms_tbl(cin_index).cf_amount;
3091 l_cf_date := l_cash_inflow_strms_tbl(cin_index).cf_date;
3092 l_days_in_future := l_cash_inflow_strms_tbl(cin_index).cf_days;
3093 IF l_cf_dpp <> 0
3094 THEN
3095 l_periods := l_days_in_future / l_cf_dpp;
3096 ELSE
3097 l_periods := 0;
3098 END IF;
3099 -- This is the variable you will be changing based on the
3100 -- Pricing Method ..
3101 -- Say like for Target Payment you will be using l_irr as l_rate
3102 -- when for Target Rate you will be using the l_cash_inflow_strms_tbl(cin_index).cf_rate ..
3103 IF p_pricing_method = 'SY'
3104 THEN
3105 l_rate := l_irr;
3106 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3107 THEN
3108 OKL_API.SET_MESSAGE (
3109 p_app_name => G_APP_NAME,
3110 p_msg_name => 'OKL_IRR_ZERO_DIV');
3111 l_return_status := OKL_API.G_RET_STS_ERROR;
3112 RAISE OKL_API.G_EXCEPTION_ERROR;
3113 END IF;
3114 -- Now, calculate the Present Value of the Cash Inflows
3115 l_disc_rate := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3116 l_temp_amount := l_cf_amount * l_disc_rate;
3117 l_npv := l_npv + l_temp_amount;
3118 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3119 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || l_days_in_future
3120 || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3121 || ' | ' || round(l_rate,4) || ' | ' || round(l_disc_rate, 4)
3122 || ' | ' || round(l_temp_amount,4) );
3123 ELSIF p_pricing_method = 'TR'
3124 THEN
3125 IF nvl(l_cash_inflow_strms_tbl(cin_index).locked_amt, 'N') = 'N'
3126 THEN
3127 -- Rate given, need to solve for Payment
3128 l_rate := l_cash_inflow_strms_tbl(cin_index).cf_rate;
3129 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3130 THEN
3131 OKL_API.SET_MESSAGE (
3132 p_app_name => G_APP_NAME,
3133 p_msg_name => 'OKL_IRR_ZERO_DIV');
3134 l_return_status := OKL_API.G_RET_STS_ERROR;
3135 RAISE OKL_API.G_EXCEPTION_ERROR;
3136 END IF;
3137 l_term_interest := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3138 l_acc_term_interest := l_acc_term_interest + l_term_interest;
3139 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3140 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || l_days_in_future || ' | ' || round(l_periods,4)
3141 || ' | ' || round(l_rate,4) || ' | ' || round(l_term_interest, 4)
3142 || ' | ' || round(l_acc_term_interest,4) );
3143 ELSE
3144 -- The possible case is that the Quote Pricing method is TR and User has entered Income/Misc Fee with proper Amount.
3145 -- In such a case, pricing should consider the amount using the Rate which is being stored at the Cash flow levels of the Fees
3146 -- NOTE: Be sure that the fee streams has the Rate populated, may be pricing only needs to populate them
3147 -- as front end may not take the responsibility of updating the CFL with the target_rate.
3148 l_disc_rate := 1 / POWER((1 + l_cash_inflow_strms_tbl(cin_index).cf_rate /(l_cf_ppy)), l_periods);
3149 l_temp_amount := l_cf_amount * l_disc_rate;
3150 l_npv := l_npv + nvl(l_temp_amount,0);
3151 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3152 round( l_cf_dpp,4) || ' | ' || l_cf_ppy || ' | ' || l_days_in_future || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3153 || ' | ' || round(l_cash_inflow_strms_tbl(cin_index).cf_rate,4) || ' | ' || round(l_disc_rate,4) || ' | ' || round(l_temp_amount, 4) );
3154 END IF;
3155 END IF; -- IF based on Pricing method
3156 -- Increment the Index of the Residuals Table
3157 cin_index := l_cash_inflow_strms_tbl.NEXT(cin_index);
3158 END LOOP;
3159 END IF;
3160 -- Handling the Present Value of the Cash Outflows
3161 IF l_cash_outflow_strms_tbl.COUNT > 0
3162 THEN
3163 IF p_pricing_method = 'SY'
3164 THEN
3165 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3166 'Cash Outflows: -------------------------------------------------------------' );
3167 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3168 'DPP | PPY | Periods | Inflow Amount | Rate | Discount Rate | Present Value' );
3169 ELSE
3170 -- Pricing Method is TR
3171 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3172 'Targetted Net Present Value: ' || round(l_npv,0) );
3173 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3174 'Cash Outflows ------------------------------------------' );
3175 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3176 '--- |---- |-------- |--------| Discount | Accumulated |' );
3177 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3178 'DPP | PPY | Days | Periods | Rate | Rate/Term | Interest |' );
3179 END IF;
3180 cout_index := l_cash_outflow_strms_tbl.FIRST;
3181 WHILE cout_index <= l_cash_outflow_strms_tbl.LAST
3182 LOOP
3183 l_cf_dpp := l_cash_outflow_strms_tbl(cout_index).cf_dpp;
3184 l_cf_ppy := l_cash_outflow_strms_tbl(cout_index).cf_ppy;
3185 l_cf_amount := l_cash_outflow_strms_tbl(cout_index).cf_amount;
3186 l_cf_date := l_cash_outflow_strms_tbl(cout_index).cf_date;
3187 l_days_in_future := l_cash_outflow_strms_tbl(cout_index).cf_days;
3188 IF l_cf_dpp <> 0
3189 THEN
3190 l_periods := l_days_in_future / l_cf_dpp;
3191 ELSE
3192 l_periods := 0;
3193 END IF;
3194 IF p_pricing_method = 'SY'
3195 THEN
3196 l_rate := l_irr;
3197 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3198 THEN
3199 OKL_API.SET_MESSAGE (
3200 p_app_name => G_APP_NAME,
3201 p_msg_name => 'OKL_IRR_ZERO_DIV');
3202 l_return_status := OKL_API.G_RET_STS_ERROR;
3203 RAISE OKL_API.G_EXCEPTION_ERROR;
3204 END IF;
3205 -- Now, calculate the Present Value of the Cash Inflows
3206 l_disc_rate := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3207 l_temp_amount := l_cf_amount * l_disc_rate;
3208 l_npv := l_npv + l_temp_amount;
3209 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3210 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || l_days_in_future
3211 || ' | ' || round(l_periods,4) || ' | ' || round(l_cf_amount,4)
3212 || ' | ' || round(l_rate,4) || ' | ' || round(l_disc_rate, 4)
3213 || ' | ' || round(l_temp_amount,4) );
3214 ELSIF p_pricing_method = 'TR'
3215 THEN
3216 IF nvl(l_cash_outflow_strms_tbl(cout_index).locked_amt, 'N') = 'N'
3217 THEN
3218 -- Rate given, need to solve for Payment
3219 l_rate := l_cash_outflow_strms_tbl(cout_index).cf_rate;
3220 IF (l_rate /l_cf_ppy = -1) or ((l_periods < 1) AND (l_rate /l_cf_ppy <= -1))
3221 THEN
3222 OKL_API.SET_MESSAGE (
3223 p_app_name => G_APP_NAME,
3224 p_msg_name => 'OKL_IRR_ZERO_DIV');
3225 l_return_status := OKL_API.G_RET_STS_ERROR;
3226 RAISE OKL_API.G_EXCEPTION_ERROR;
3227 END IF;
3228 l_term_interest := 1/ POWER((1 + l_rate /(l_cf_ppy)), l_periods);
3229 l_acc_term_interest := l_acc_term_interest + l_term_interest;
3230 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3231 l_cf_dpp || ' | ' || l_cf_ppy || ' | ' || round(l_periods,4) || ' | ' || round(l_rate,4) || ' | ' || round(l_term_interest, 4)
3232 || ' | ' || round(l_acc_term_interest,4) );
3233 ELSE
3234 l_disc_rate := 1 / POWER((1 + l_cash_outflow_strms_tbl(cout_index).cf_rate /(l_cf_ppy)), l_periods);
3235 l_temp_amount := l_cf_amount * l_disc_rate;
3236 l_npv := l_npv + nvl(l_temp_amount,0);
3237 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3238 round( l_cf_dpp,4) || ' | ' || l_cf_ppy || ' | ' ||
3239 l_days_in_future || ' | ' || round(l_periods,4) || ' | ' ||
3240 round(l_cf_amount,4) || ' | ' || round(l_cash_outflow_strms_tbl(cout_index).cf_rate,4)
3241 || ' | ' || round(l_disc_rate,4) || ' | ' || round(l_temp_amount, 4) );
3242 END IF;
3243 END IF; -- IF based on Pricing method
3244 -- Increment the Index of the Residuals Table
3245 cout_index := l_cash_outflow_strms_tbl.NEXT(cout_index);
3246 END LOOP;
3247 END IF;
3248 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'NPV : ' || round(l_npv,4) );
3249 -- If Pricing Method is Solve for Payments ..
3250 IF p_pricing_method = 'SY'
3251 THEN
3252 -- With the current l_irr rate if the NPV is nearly zero ..
3253 -- then return the current rate as the final irr ...
3254 IF ROUND( l_npv, l_precision + 4 ) = 0
3255 THEN
3256 -- If the net present value is ZERO
3257 -------------------------------------------------------
3258 -- Need to place the code to return the payment too ...
3259 -------------------------------------------------------
3260 px_irr := l_irr;
3261 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3262 'INTERNAL RATE OF RETURN = ' || px_irr );
3263 EXIT;
3264 END IF;
3265 ELSIF p_pricing_method = 'TR'
3266 THEN
3267 -- Calculate the Payment and exit .. ..( NO LOOPING ...)
3268 IF ROUND( l_acc_term_interest, l_precision + 4 ) = 0
3269 THEN
3270 OKL_API.SET_MESSAGE (
3271 p_app_name => G_APP_NAME,
3272 p_msg_name => 'OKL_IRR_ZERO_DIV');
3273 l_return_status := OKL_API.G_RET_STS_ERROR;
3274 EXIT WHEN (l_return_status = OKL_API.G_RET_STS_ERROR);
3275 END IF;
3276 x_payment := -l_npv/ l_acc_term_interest;
3277 px_irr := l_irr;
3278 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3279 'CALCULATED PAYMENT AMOUNT = ' || round( x_payment,4) );
3280 EXIT;
3281 END IF; -- p_pricing_method IF
3282
3283 IF p_pricing_method = 'SY' THEN
3284 -- Determine whether we are having NPVs with different signs ..
3285 IF SIGN(l_npv) <> SIGN(l_prev_npv) AND
3286 l_crossed_zero = 'N' AND
3287 n_iterations > 1 THEN
3288 l_crossed_zero := 'Y';
3289 IF SIGN( l_npv) = 1 THEN
3290 l_positive_npv := l_npv;
3291 l_negative_npv := l_prev_npv;
3292 l_positive_npv_irr := l_irr;
3293 l_negative_npv_irr := l_prev_irr;
3294 ELSE
3295 l_positive_npv := l_prev_npv;
3296 l_negative_npv := l_npv;
3297 l_positive_npv_irr := l_prev_irr;
3298 l_negative_npv_irr := l_irr;
3299 END IF;
3300 END IF;
3301
3302 IF( SIGN(l_npv) = 1) THEN
3303 l_positive_npv := l_npv;
3304 l_positive_npv_irr := l_irr;
3305 ELSE
3306 l_negative_npv := l_npv;
3307 l_negative_npv_irr := l_irr;
3308 END IF;
3309 IF l_crossed_zero = 'Y'
3310 THEN
3311 -- Means First time we have got two opposite signed NPVs
3312 -- Introducing Interpolation approach instead of the Binary Method
3313 IF n_iterations > 1 then
3314 l_abs_incr_rate := abs(( l_positive_npv_irr - l_negative_npv_irr )
3315 / ( l_positive_npv - l_negative_npv ) * l_positive_npv) ;
3316 IF ( l_positive_npv_irr < l_negative_npv_irr ) THEN
3317 l_irr := l_positive_npv_irr + l_abs_incr_rate;
3318 ELSE
3319 l_irr := l_positive_npv_irr - l_abs_incr_rate;
3320 END IF;
3321 l_irr_decided := 'Y';
3322 ELSE
3323 -- Feel so we wont be here any time ..
3324 -- Use Binary Method to reach the desired IRR
3325 l_abs_incr_rate := ABS(l_increment_rate) / 2;
3326 END IF;
3327 ELSE
3328 -- If still not crossed zero, increment the rate with l_increment_rate as it is ..
3329 l_abs_incr_rate := ABS(l_increment_rate);
3330 END IF;
3331 IF n_iterations > 1 THEN
3332 IF SIGN(l_npv) <> SIGN(l_prev_npv) THEN
3333 IF l_prev_incr_sign = 1 THEN
3334 -- Change sign of the increment if the current and previous npvs are of different signs
3335 l_increment_rate := - l_abs_incr_rate;
3336 ELSE
3337 -- Proceed with the same increment if the current and previous npvs are of same sign
3338 l_increment_rate := l_abs_incr_rate;
3339 END IF; -- l_prev_incr_sign
3340 ELSE -- IF SIGN(l_npv) <> SIGN(l_prev_npv)
3341 -- Current and Previous npvs are of same signs
3342 IF l_prev_incr_sign = 1 THEN
3343 -- Proceed with the same increment
3344 l_increment_rate := l_abs_incr_rate;
3345 ELSE
3346 l_increment_rate := - l_abs_incr_rate;
3347 END IF;
3348 END IF;
3349 ELSE -- Else for n_iterations If ..
3350 -- First Iteration ...
3351 IF SIGN(l_npv) = -1
3352 THEN
3353 l_increment_rate := -l_increment_rate;
3354 END IF;
3355 END IF; -- n_iteratios if ..
3356 l_prev_irr := l_irr;
3357 IF l_irr_decided = 'N'
3358 THEN
3359 l_irr := l_irr + l_increment_rate;
3360 ELSE
3361 -- l_irr has been already decided .. just change the flag here ..
3362 l_irr_decided := 'N';
3363 END IF;
3364 -- If IRR exceeded the limit set in the profile, then raise an error
3365 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3366 'l_irr ' || round( l_irr, 4 ) );
3367 IF ABS(l_irr) > l_irr_limit THEN
3368 OKL_API.SET_MESSAGE (
3369 p_app_name => G_APP_NAME,
3370 p_msg_name => 'OKL_IRR_CALC_IRR_LIMIT',
3371 p_token1 => 'IRR_LIMIT',
3372 p_token1_value => l_irr_limit*100);
3373 x_return_status := OKL_API.G_RET_STS_ERROR;
3374 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3375 '---------------- IRR crossed the limit --------------------------- ' );
3376 RAISE OKL_API.G_EXCEPTION_ERROR;
3377 --EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3378 END IF;
3379 l_prev_incr_sign := SIGN(l_increment_rate);
3380 l_prev_npv_sign := SIGN(l_npv);
3381 l_prev_npv := l_npv;
3382 END IF;
3383 END LOOP; -- (Loop on n_iterations .. )
3384 -- Setting up the return variables
3385 x_return_status := l_return_status;
3386 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
3387 x_msg_data => x_msg_data);
3388 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3389 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
3390 EXCEPTION
3391 WHEN OKL_API.G_EXCEPTION_ERROR THEN
3392 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3393 p_api_name => l_api_name,
3394 p_pkg_name => G_PKG_NAME,
3395 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
3396 x_msg_count => x_msg_count,
3397 x_msg_data => x_msg_data,
3398 p_api_type => g_api_type);
3399 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
3400 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3401 p_api_name => l_api_name,
3402 p_pkg_name => G_PKG_NAME,
3403 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
3404 x_msg_count => x_msg_count,
3405 x_msg_data => x_msg_data,
3406 p_api_type => g_api_type);
3407 WHEN OTHERS THEN
3408 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3409 p_api_name => l_api_name,
3410 p_pkg_name => G_PKG_NAME,
3411 p_exc_name => 'OTHERS',
3412 x_msg_count => x_msg_count,
3413 x_msg_data => x_msg_data,
3414 p_api_type => g_api_type);
3415 END compute_irr;
3416 -- Procedure -- for solving the Financed Amount when EOTs
3417 -- are of type Percent !
3418 -- Please be sure that no down payments, Trade in , Subsidy are being
3419 -- passed in the pricing param recrod, they need to be handled irrespective
3420 -- whether they are direct amounts or percentage of Asset Cost.
3421 PROCEDURE compute_iir_sfp(
3422 p_api_version IN NUMBER,
3423 p_init_msg_list IN VARCHAR2,
3424 x_return_status OUT NOCOPY VARCHAR2,
3425 x_msg_count OUT NOCOPY NUMBER,
3426 x_msg_data OUT NOCOPY VARCHAR2,
3427 p_start_date IN DATE,
3428 p_day_count_method IN VARCHAR2,
3429 p_pricing_method IN VARCHAR2,
3430 p_initial_guess IN NUMBER,
3431 px_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type,
3432 px_iir IN OUT NOCOPY NUMBER,
3433 x_closing_balance OUT NOCOPY NUMBER,
3434 x_residual_percent OUT NOCOPY NUMBER,
3435 x_residual_int_factor OUT NOCOPY NUMBER)
3436 AS
3437 -- Local Variables
3438 l_api_version CONSTANT NUMBER DEFAULT 1.0;
3439 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_iir_sfp';
3440 l_return_status VARCHAR2(1);
3441
3442 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
3443 || G_PKG_NAME || '.' || UPPER(l_api_name);
3444 l_debug_enabled VARCHAR2(10);
3445 is_debug_procedure_on BOOLEAN;
3446 is_debug_statement_on BOOLEAN;
3447 l_days_in_month VARCHAR2(30);
3448 l_days_in_year VARCHAR2(30);
3449 l_start_date DATE;
3450 l_cash_inflows_tbl cash_inflows_tbl_type;
3451 l_asset_cost NUMBER;
3452 l_residual_amount NUMBER;
3453 l_next_cif_date DATE;
3454 l_residuals_tbl cash_inflows_tbl_type;
3455 cf_index NUMBER;
3456 res_index NUMBER;
3457 i NUMBER;
3458 l_opening_bal NUMBER;
3459 l_closing_bal NUMBER;
3460 l_rate NUMBER;
3461 l_iir NUMBER;
3462 l_days_per_annum NUMBER;
3463 l_interest_factor NUMBER;
3464 l_residual_percent NUMBER;
3465 BEGIN
3466 l_return_status := OKL_API.G_RET_STS_SUCCESS;
3467 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
3468 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
3469
3470 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3471 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
3472 -- check for logging on STATEMENT level
3473 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
3474 -- Call START_ACTIVITY to create savepoint, check compatibility
3475 -- and initialize message list
3476 l_return_status := OKL_API.START_ACTIVITY(
3477 p_api_name => l_api_name,
3478 p_pkg_name => G_PKG_NAME,
3479 p_init_msg_list => p_init_msg_list,
3480 l_api_version => l_api_version,
3481 p_api_version => p_api_version,
3482 p_api_type => g_api_type,
3483 x_return_status => x_return_status);
3484 --Check if activity started successfully
3485 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3486 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3487 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3488 RAISE OKL_API.G_EXCEPTION_ERROR;
3489 END IF;
3490 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','-Start' );
3491 get_days_in_year_and_month(
3492 p_day_count_method => p_day_count_method,
3493 x_days_in_month => l_days_in_month,
3494 x_days_in_year => l_days_in_year,
3495 x_return_status => l_return_status);
3496 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);
3497 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3498 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3499 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3500 RAISE OKL_API.G_EXCEPTION_ERROR;
3501 END IF;
3502 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3503 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
3504 -- Initializations
3505 l_start_date := p_start_date;
3506 l_asset_cost := nvl(px_pricing_parameter_rec.financed_amount, 0);
3507 l_residuals_tbl := px_pricing_parameter_rec.residual_inflows;
3508 l_residual_amount := 0;
3509 -- Introducing new pricing method called SFR, to
3510 -- Handle the SF method when the Residual Amt is percentage of OEC
3511 IF p_pricing_method <> 'SFP'
3512 THEN
3513 -- Not handling other pricing scenarios as of now
3514 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3515 'Compute_iir_sfp currently supports only Solve for Financed Amount EOT Percent Pricing method only' );
3516 OKL_API.SET_MESSAGE (
3517 p_app_name => G_APP_NAME,
3518 p_msg_name => 'OKL_LP_INVALID_PRICING_METHOD');
3519 RAISE OKL_API.G_EXCEPTION_ERROR;
3520 END IF;
3521 IF px_pricing_parameter_rec.cash_inflows IS NOT NULL AND
3522 px_pricing_parameter_rec.cash_inflows.COUNT > 0
3523 THEN
3524 cf_index := px_pricing_parameter_rec.cash_inflows.FIRST;
3525 i := 1; -- Store inflows as an 1-Based Array
3526 l_next_cif_date := p_start_date;
3527 -- Loop thorugh the Cash Inflows ..
3528 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3529 'Cash Inflows: --------------------------------------------------- ' );
3530 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3531 'Date | Amount | Days | Purpose| Arrears | Interest Acc. on Capital |l_next_cif_date ' );
3532 WHILE cf_index <= px_pricing_parameter_rec.cash_inflows.LAST
3533 LOOP
3534 -- Copy a record from px_table to l_cash_inflows_tbl ..
3535 -- rate, cf_date, is_arrears, cf_miss_pay, amount .. will be copied
3536 l_cash_inflows_tbl(i) := px_pricing_parameter_rec.cash_inflows(cf_index);
3537 l_cash_inflows_tbl(i).cf_days := GET_DAY_COUNT(
3538 p_days_in_month => l_days_in_month,
3539 p_days_in_year => l_days_in_year,
3540 p_start_date => l_next_cif_date,
3541 p_end_date => l_cash_inflows_tbl(i).cf_date,
3542 p_arrears => l_cash_inflows_tbl(i).is_arrears,
3543 x_return_status => l_return_status);
3544 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3545 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3546 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3547 RAISE OKL_API.G_EXCEPTION_ERROR;
3548 END IF;
3549 IF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_PRINCIPAL_PAYMENT')
3550 THEN
3551 l_cash_inflows_tbl(i).cf_purpose := 'P';
3552 ELSIF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_INTEREST_PAYMENT')
3553 THEN
3554 l_cash_inflows_tbl(i).cf_purpose := 'I';
3555 ELSE
3556 l_cash_inflows_tbl(i).cf_purpose := 'B';
3557 END IF;
3558 -- Interest calculated for l_next_cif_date to l_cash_inflows_tbl(i).cf_date
3559 l_days_per_annum := get_days_per_annum(
3560 p_day_convention => p_day_count_method,
3561 p_start_date => p_start_date,
3562 p_cash_inflow_date => l_cash_inflows_tbl(i).cf_date,
3563 x_return_status => l_return_status );
3564 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3565 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3566 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3567 RAISE OKL_API.G_EXCEPTION_ERROR;
3568 END IF;
3569 -- Sum the Interest based on the capitalized amount
3570 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3571 l_cash_inflows_tbl(i).cf_date || '|' || round(l_cash_inflows_tbl(i).cf_amount,4)
3572 || '|' || l_cash_inflows_tbl(i).cf_days || '|' || l_cash_inflows_tbl(i).cf_purpose
3573 || '|' || l_cash_inflows_tbl(i).is_Arrears || '|' || '--'
3574 || '|' || l_next_cif_date);
3575 -- Incrementing the Start Date for next period
3576 l_next_cif_date := l_cash_inflows_tbl(cf_index).cf_date;
3577 IF l_cash_inflows_tbl(cf_index).is_arrears = 'Y'
3578 THEN
3579 l_next_cif_date := l_next_cif_date + 1;
3580 END IF;
3581 -- Increment the indexes
3582 cf_index := px_pricing_parameter_rec.cash_inflows.NEXT(cf_index);
3583 i := i + 1;
3584 END LOOP; -- End While Looping on px_cash_inflow_tbl
3585 END IF; -- If px_cash_inflow_tbl
3586 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3587 'Residuals: -------------------------------------' );
3588 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3589 'Date | Residual Amount | Days | Purpose| Arrears' );
3590 -- Handling Residual Value Streams
3591 IF l_residuals_tbl.COUNT > 0
3592 THEN
3593 res_index := l_residuals_tbl.FIRST;
3594 WHILE res_index <= l_residuals_tbl.LAST
3595 LOOP
3596 l_residual_amount := l_residual_amount + l_residuals_tbl(res_index).cf_amount;
3597 -- To get rate, instead of using the get_rate api, we can directly take the rate from the
3598 -- last inflow ..
3599 l_residuals_tbl(res_index).cf_rate := l_cash_inflows_tbl(l_cash_inflows_tbl.LAST).cf_rate;
3600 IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
3601 THEN
3602 l_residuals_tbl(res_index).cf_days := 0;
3603 ELSE
3604 l_residuals_tbl(res_index).cf_days := GET_DAY_COUNT(
3605 p_days_in_month => l_days_in_month,
3606 p_days_in_year => l_days_in_year,
3607 p_start_date => l_next_cif_date,
3608 p_end_date => l_residuals_tbl(res_index).cf_date,
3609 p_arrears => 'Y',
3610 x_return_status => l_return_status);
3611 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3612 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3613 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3614 RAISE OKL_API.G_EXCEPTION_ERROR;
3615 END IF;
3616 END IF; -- IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
3617 l_next_cif_date := l_residuals_tbl( res_index ).cf_date;
3618 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3619 l_residuals_tbl(res_index).cf_date || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
3620 || '|' || l_residuals_tbl(res_index).cf_days || '|' || l_residuals_tbl(res_index).cf_purpose
3621 || '|' || l_residuals_tbl(res_index).is_Arrears);
3622 -- Increment the Residual Table Index
3623 res_index := l_residuals_tbl.NEXT( res_index );
3624 END LOOP;
3625 END IF;
3626 -- Compute_iir can directly calculate the Financed Amount/Subsidy/Down payment/Trade in Amount
3627 -- without any iterations !!
3628 IF p_pricing_method = 'SFP'
3629 THEN
3630 -- Pricing Logic for Solve for Financed Amount/ Solve for Subsidy
3631 l_opening_bal := 0;
3632 l_closing_bal := 0; -- Targetting l_closing_bal as zero
3633 l_rate := 0;
3634 l_interest_factor := 1;
3635 l_residual_percent := 0;
3636 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3637 'Targeting Closing Balance: ' || l_closing_bal );
3638 IF l_residuals_tbl IS NOT NULL AND
3639 l_residuals_tbl.COUNT > 0
3640 THEN
3641 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3642 'Residual Details: -----------------------------------------------------------------' );
3643 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3644 'Days/Annum | Rate | Closing Balance|Days|Residual Amount|Interest Factor on Res. Amount|Opening Balance' );
3645 res_index := l_residuals_tbl.COUNT;
3646 WHILE res_index >= 1
3647 LOOP
3648 IF p_pricing_method = 'SFP'
3649 THEN
3650 l_days_per_annum := get_days_per_annum(
3651 p_day_convention => p_day_count_method,
3652 p_start_date => p_start_date,
3653 p_cash_inflow_date => l_residuals_tbl(res_index).cf_date,
3654 x_return_status => l_return_status );
3655 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3656 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3657 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3658 RAISE OKL_API.G_EXCEPTION_ERROR;
3659 END IF;
3660 -- Sum the Residual Percentage. Cf_amount will be storing the percentages
3661 -- instead of directly the amounts
3662 l_residual_percent := l_residual_percent + nvl( l_residuals_tbl(res_index).cf_amount, 0);
3663 l_rate := 1 + ( l_residuals_tbl(res_index).cf_days *
3664 l_residuals_tbl(res_index).cf_rate /l_days_per_annum );
3665 -- Multiply this interest factor
3666 l_interest_factor := l_interest_factor * l_rate;
3667 END IF;
3668 -- Decrement the Iterator
3669 res_index := res_index - 1;
3670 END LOOP;
3671 ELSE
3672 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3673 'No Residual Amounts Passed !!! ' );
3674 END IF;
3675 IF l_cash_inflows_tbl IS NOT NULL AND
3676 l_cash_inflows_tbl.COUNT > 0
3677 THEN
3678 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3679 'Inflows Details: ------------------------------------------------------------------' );
3680 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3681 'Days/Annum | Rate | Closing Balance|Days|Inflow Amount|Interest Factor on Inflow Amount|Opening Balance' );
3682 -- Looping through Inflows in Reverse way
3683 cf_index := l_cash_inflows_tbl.COUNT;
3684 WHILE cf_index >= 1
3685 LOOP
3686 l_days_per_annum := get_days_per_annum(
3687 p_day_convention => p_day_count_method,
3688 p_start_date => p_start_date,
3689 p_cash_inflow_date => l_cash_inflows_tbl(cf_index).cf_date,
3690 x_return_status => l_return_status );
3691 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3692 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3693 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3694 RAISE OKL_API.G_EXCEPTION_ERROR;
3695 END IF;
3696 l_rate := 1 + ( l_cash_inflows_tbl(cf_index).cf_days *
3697 l_cash_inflows_tbl(cf_index).cf_rate /l_days_per_annum );
3698 -- Multiply this interest factor
3699 l_interest_factor := l_interest_factor * l_rate;
3700 l_opening_bal := ( l_closing_bal + l_cash_inflows_tbl(cf_index).cf_amount ) / l_rate;
3701 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3702 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
3703 || '|' || round(l_cash_inflows_tbl(cf_index).cf_amount,4) || '|' || round( l_rate, 4 )
3704 || '|' || round(l_opening_bal,4));
3705 l_closing_bal := l_opening_bal;
3706 -- Decrement the Iterator
3707 cf_index := cf_index - 1;
3708 END LOOP;
3709 END IF; -- IF l_cash_inflow_tbl is not null
3710 -- Now, after looping through the Residuals and then the Rent Inflows,
3711 -- the Opening Balance is nothing but the Financed Amount.
3712 -- The opening balance is the amount represent which should be the starting
3713 -- Financed Amount such that at the end the closing balance is ZERO.
3714 -- The above logic is just nothing but the Reverse Approach !!
3715 -- Store the Financed Amount and return now !
3716 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3717 ' Closing Balance | Residual Percent | Residual Interest Factor ');
3718 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3719 ROUND( l_closing_bal, 4 ) || ' | ' || round(l_residual_percent, 4) || ' | ' || round(l_interest_factor, 4));
3720 -- Solve for Financed Amount Logic when the Residuals are percentage of OEC
3721 x_closing_balance := l_closing_bal; -- This is the OEC'
3722 x_residual_percent := l_residual_percent;
3723 x_residual_int_factor := l_interest_factor;
3724 END IF;
3725 -- Set ther return values and return them !!
3726 x_return_status := l_return_status;
3727 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
3728 x_msg_data => x_msg_data);
3729 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3730 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
3731 EXCEPTION
3732 WHEN OKL_API.G_EXCEPTION_ERROR THEN
3733 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3734 p_api_name => l_api_name,
3735 p_pkg_name => G_PKG_NAME,
3736 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
3737 x_msg_count => x_msg_count,
3738 x_msg_data => x_msg_data,
3739 p_api_type => g_api_type);
3740 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
3741 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3742 p_api_name => l_api_name,
3743 p_pkg_name => G_PKG_NAME,
3744 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
3745 x_msg_count => x_msg_count,
3746 x_msg_data => x_msg_data,
3747 p_api_type => g_api_type);
3748 WHEN OTHERS THEN
3749 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
3750 p_api_name => l_api_name,
3751 p_pkg_name => G_PKG_NAME,
3752 p_exc_name => 'OTHERS',
3753 x_msg_count => x_msg_count,
3754 x_msg_data => x_msg_data,
3755 p_api_type => g_api_type);
3756 END compute_iir_sfp;
3757 -- Procedure: Calculation of the IIR
3758 PROCEDURE compute_iir(
3759 p_api_version IN NUMBER,
3760 p_init_msg_list IN VARCHAR2,
3761 x_return_status OUT NOCOPY VARCHAR2,
3762 x_msg_count OUT NOCOPY NUMBER,
3763 x_msg_data OUT NOCOPY VARCHAR2,
3764 p_start_date IN DATE,
3765 p_day_count_method IN VARCHAR2,
3766 p_pricing_method IN VARCHAR2,
3767 p_initial_guess IN NUMBER,
3768 px_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type,
3769 px_iir IN OUT NOCOPY NUMBER,
3770 x_payment OUT NOCOPY NUMBER)
3771 AS
3772 -- Local Variables
3773 l_api_version CONSTANT NUMBER DEFAULT 1.0;
3774 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_iir';
3775 l_return_status VARCHAR2(1);
3776
3777 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
3778 || G_PKG_NAME || '.' || UPPER(l_api_name);
3779 l_debug_enabled VARCHAR2(10);
3780 is_debug_procedure_on BOOLEAN;
3781 is_debug_statement_on BOOLEAN;
3782 l_days_in_month VARCHAR2(30);
3783 l_days_in_year VARCHAR2(30);
3784 l_start_date DATE;
3785 l_cash_inflows_tbl cash_inflows_tbl_type;
3786 l_asset_cost NUMBER;
3787 l_tradein_amt NUMBER;
3788 l_subsidy_amt NUMBER;
3789 l_downpayment_amt NUMBER;
3790 l_ast_cap_fee_amt NUMBER;
3791 l_residual_amount NUMBER;
3792 l_next_cif_date DATE;
3793 l_residuals_tbl cash_inflows_tbl_type;
3794 l_investment NUMBER;
3795 l_adv_amount NUMBER;
3796 l_interest NUMBER;
3797 cf_index NUMBER;
3798 res_index NUMBER;
3799 i NUMBER;
3800 n_iterations NUMBER;
3801 l_opening_bal NUMBER;
3802 l_closing_bal NUMBER;
3803 l_payment NUMBER;
3804 l_principal_payment NUMBER;
3805 l_diff NUMBER;
3806 l_prev_diff NUMBER;
3807 l_positive_diff_pay NUMBER := 0;
3808 l_negative_diff_pay NUMBER := 0;
3809 l_positive_diff NUMBER := 0;
3810 l_negative_diff NUMBER := 0;
3811 l_crossed_zero VARCHAR2(1);
3812 l_periodic_amount NUMBER;
3813 l_prev_periodic_amount NUMBER := 0;
3814 l_increment NUMBER;
3815 l_abs_incr NUMBER;
3816 l_prev_incr_sign NUMBER;
3817 l_prev_diff_sign NUMBER;
3818 l_rate NUMBER;
3819 l_iir NUMBER;
3820 l_prev_iir NUMBER;
3821 l_positive_diff_iir NUMBER;
3822 l_negative_diff_iir NUMBER;
3823 l_days_per_annum NUMBER;
3824 l_interest_factor NUMBER;
3825 l_residual_percent NUMBER;
3826 BEGIN
3827 l_return_status := OKL_API.G_RET_STS_SUCCESS;
3828 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
3829 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
3830
3831 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
3832 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
3833 -- check for logging on STATEMENT level
3834 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
3835 -- Call START_ACTIVITY to create savepoint, check compatibility
3836 -- and initialize message list
3837 l_return_status := OKL_API.START_ACTIVITY(
3838 p_api_name => l_api_name,
3839 p_pkg_name => G_PKG_NAME,
3840 p_init_msg_list => p_init_msg_list,
3841 l_api_version => l_api_version,
3842 p_api_version => p_api_version,
3843 p_api_type => g_api_type,
3844 x_return_status => x_return_status);
3845 --Check if activity started successfully
3846 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3847 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3848 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3849 RAISE OKL_API.G_EXCEPTION_ERROR;
3850 END IF;
3851 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','-Start' );
3852 get_days_in_year_and_month(
3853 p_day_count_method => p_day_count_method,
3854 x_days_in_month => l_days_in_month,
3855 x_days_in_year => l_days_in_year,
3856 x_return_status => l_return_status);
3857 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);
3858 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3859 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3860 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3861 RAISE OKL_API.G_EXCEPTION_ERROR;
3862 END IF;
3863 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3864 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
3865 -- Initializations
3866 l_start_date := p_start_date;
3867 l_asset_cost := nvl(px_pricing_parameter_rec.financed_amount, 0);
3868 l_tradein_amt := nvl(px_pricing_parameter_rec.trade_in, 0);
3869 l_subsidy_amt := nvl(px_pricing_parameter_rec.subsidy, 0);
3870 l_downpayment_amt := nvl(px_pricing_parameter_rec.down_payment, 0);
3871 l_ast_cap_fee_amt := nvl(px_pricing_parameter_rec.cap_fee_amount, 0);
3872 l_residuals_tbl := px_pricing_parameter_rec.residual_inflows;
3873 l_periodic_amount := 0;
3874 l_investment := 0;
3875 l_adv_amount := 0;
3876 l_interest := 0;
3877 l_residual_amount := 0;
3878 -- Introducing new pricing method called SFR, to
3879 -- Handle the SF method when the Residual Amt is percentage of OEC
3880 IF p_pricing_method <> 'SP' AND
3881 p_pricing_method <> 'SM' AND
3882 p_pricing_method <> 'SF' AND
3883 p_pricing_method <> 'SFP' AND
3884 p_pricing_method <> 'SS' AND
3885 p_pricing_method <> 'SY' AND
3886 p_pricing_method <> 'SI' AND -- Solve for Trade in
3887 p_pricing_method <> 'SD' AND
3888 p_pricing_method <> 'TR' AND
3889 p_pricing_method <> 'SPP'
3890 THEN
3891 -- Not handling other pricing scenarios as of now
3892 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3893 'Compute_iir currently supports only Solve for Payment, Solve for Financed Amount, ' );
3894 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3895 'Solve for Subsidy, Solve for Subsidy, Down Payment, Tradein, Missing Payment Pricing Scenarios only, Target Rate ( IIR) ' );
3896 OKL_API.SET_MESSAGE (
3897 p_app_name => G_APP_NAME,
3898 p_msg_name => 'OKL_LP_INVALID_PRICING_METHOD');
3899 RAISE OKL_API.G_EXCEPTION_ERROR;
3900 END IF;
3901 IF p_pricing_method = 'SP' OR
3902 p_pricing_method = 'SY' OR
3903 p_pricing_method = 'SM' OR
3904 p_pricing_method = 'TR' OR
3905 p_pricing_method = 'SPP'
3906 THEN
3907 -- Solve for Payment Scenario
3908 -- So, validate whether we have been given the Financed Amount,
3909 -- and Residual Value properly atleast
3910 IF px_pricing_parameter_rec.financed_amount IS NULL
3911 THEN
3912 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3913 'Financed Amount cannot be null .. Pricing Method '|| p_pricing_method );
3914 -- Raise an Error
3915
3916 RAISE OKL_API.G_EXCEPTION_ERROR;
3917 END IF;
3918 -- The cash inflows should have rate populated !
3919 FOR t IN px_pricing_parameter_rec.cash_inflows.FIRST ..
3920 px_pricing_parameter_rec.cash_inflows.LAST
3921 LOOP
3922 IF px_pricing_parameter_rec.cash_inflows(t).cf_rate IS NULL AND
3923 p_pricing_method <> 'SY'
3924 THEN
3925 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3926 'Streams Passed are not having the Rate. Pricing Method '|| p_pricing_method );
3927 -- Raise an Error
3928 OKL_API.set_message(
3929 G_APP_NAME,
3930 OKL_API.G_INVALID_VALUE,
3931 OKL_API.G_COL_NAME_TOKEN,
3932 'CF_RATE');
3933 RAISE OKL_API.G_EXCEPTION_ERROR;
3934 END IF;
3935 END LOOP;
3936 END IF;
3937 IF p_pricing_method = 'SF' AND
3938 p_pricing_method = 'SFP'
3939 THEN
3940 -- Place validations for Solve for Financed Amount, such that
3941 -- Rate and Amounts should be present for all inflows in the px_cash_inflow_tbl table
3942 -- Also, validations what we need to impose for this table is
3943 -- a/ The inflow elements table should be ordered by date
3944 NULL;
3945 END IF;
3946 IF p_pricing_method = 'SS'
3947 THEN
3948 -- Solve for Subsidy Scenario
3949 -- So, validate whether we have been given the Financed Amount, Cash Inflows
3950 -- and Residual Value properly atleast
3951 IF px_pricing_parameter_rec.financed_amount IS NULL
3952 THEN
3953 -- Raise an Error
3954 RAISE OKL_API.G_EXCEPTION_ERROR;
3955 END IF;
3956 END IF;
3957 -- Calculate the Investment ..
3958 -- C - S - D - T
3959 l_investment := l_asset_cost - l_tradein_amt - l_subsidy_amt - l_downpayment_amt + l_ast_cap_fee_amt;
3960 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3961 'Investment including the Cap. Fee for this Asset (l_investment) ' || l_investment );
3962 IF px_pricing_parameter_rec.cash_inflows IS NOT NULL AND
3963 px_pricing_parameter_rec.cash_inflows.COUNT > 0
3964 THEN
3965 cf_index := px_pricing_parameter_rec.cash_inflows.FIRST;
3966 i := 1; -- Store inflows as an 1-Based Array
3967 l_next_cif_date := p_start_date;
3968 -- Loop thorugh the Cash Inflows ..
3969 -- 1/ Calculate the days, average rate if rates are different ..
3970 -- 2/ Sum the amounts which you are getting on or before the p_start_date
3971 -- into l_adv_amount, so that we can later validate such that
3972 -- l_investment should be greater than the l_adv_amount
3973 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3974 'Cash Inflows: --------------------------------------------------- ' );
3975 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
3976 'Date | Amount | Days | Purpose| Arrears | Interest Acc. on Capital |l_next_cif_date | cf_ratio ' );
3977 WHILE cf_index <= px_pricing_parameter_rec.cash_inflows.LAST
3978 LOOP
3979 -- Copy a record from px_table to l_cash_inflows_tbl ..
3980 -- rate, cf_date, is_arrears, cf_miss_pay, amount .. will be copied
3981 l_cash_inflows_tbl(i) := px_pricing_parameter_rec.cash_inflows(cf_index);
3982 l_cash_inflows_tbl(i).cf_days := GET_DAY_COUNT(
3983 p_days_in_month => l_days_in_month,
3984 p_days_in_year => l_days_in_year,
3985 p_start_date => l_next_cif_date,
3986 p_end_date => l_cash_inflows_tbl(i).cf_date,
3987 p_arrears => l_cash_inflows_tbl(i).is_arrears,
3988 x_return_status => l_return_status);
3989 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3990 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3991 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
3992 RAISE OKL_API.G_EXCEPTION_ERROR;
3993 END IF;
3994 IF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_PRINCIPAL_PAYMENT')
3995 THEN
3996 l_cash_inflows_tbl(i).cf_purpose := 'P';
3997 ELSIF ( l_cash_inflows_tbl(i).cf_purpose = 'UNSCHEDULED_INTEREST_PAYMENT')
3998 THEN
3999 l_cash_inflows_tbl(i).cf_purpose := 'I';
4000 ELSE
4001 l_cash_inflows_tbl(i).cf_purpose := 'B';
4002 END IF;
4003 -- Sum the amounts, which we are getting on or before the Start Date
4004 IF l_cash_inflows_tbl(i).cf_date <= p_start_date
4005 THEN
4006 l_adv_amount := l_adv_amount + nvl( l_cash_inflows_tbl(i).cf_amount, 0 );
4007 END IF;
4008 -- Interest calculated for l_next_cif_date to l_cash_inflows_tbl(i).cf_date
4009 l_days_per_annum := get_days_per_annum(
4010 p_day_convention => p_day_count_method,
4011 p_start_date => p_start_date,
4012 p_cash_inflow_date => l_cash_inflows_tbl(i).cf_date,
4013 x_return_status => l_return_status );
4014 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4015 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4016 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4017 RAISE OKL_API.G_EXCEPTION_ERROR;
4018 END IF;
4019 -- Sum the Interest based on the capitalized amount
4020 l_interest := l_interest +
4021 (l_investment * l_cash_inflows_tbl(i).cf_rate * l_cash_inflows_tbl(i).cf_days / l_days_per_annum );
4022
4023 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4024 l_cash_inflows_tbl(i).cf_date || '|' || round(l_cash_inflows_tbl(i).cf_amount,4)
4025 || '|' || l_cash_inflows_tbl(i).cf_days || '|' || l_cash_inflows_tbl(i).cf_purpose
4026 || '|' || l_cash_inflows_tbl(i).is_Arrears || '|' || l_interest
4027 || '|' || l_next_cif_date || ' | ' || l_cash_inflows_tbl(i).cf_ratio);
4028 -- Incrementing the Start Date for next period
4029 l_next_cif_date := l_cash_inflows_tbl(cf_index).cf_date;
4030 IF l_cash_inflows_tbl(cf_index).is_arrears = 'Y'
4031 THEN
4032 l_next_cif_date := l_next_cif_date + 1;
4033 END IF;
4034 -- Increment the indexes
4035 cf_index := px_pricing_parameter_rec.cash_inflows.NEXT(cf_index);
4036 i := i + 1;
4037 END LOOP; -- End While Looping on px_cash_inflow_tbl
4038 END IF; -- If px_cash_inflow_tbl
4039 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4040 'Residuals: -------------------------------------' );
4041 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4042 'Date | Residual Amount | Days | Purpose| Arrears' );
4043 -- Handling Residual Value Streams
4044 IF l_residuals_tbl.COUNT > 0
4045 THEN
4046 res_index := l_residuals_tbl.FIRST;
4047 WHILE res_index <= l_residuals_tbl.LAST
4048 LOOP
4049 l_residual_amount := l_residual_amount + l_residuals_tbl(res_index).cf_amount;
4050 -- Get rate as on that date when residuals are returned
4051 -- Instead of using the get_rate api, we can directly take the rate from the
4052 -- last inflow .. Think over this !!!
4053 l_residuals_tbl(res_index).cf_rate := l_cash_inflows_tbl(l_cash_inflows_tbl.LAST).cf_rate;
4054 IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
4055 THEN
4056 l_residuals_tbl(res_index).cf_days := 0;
4057 ELSE
4058 l_residuals_tbl(res_index).cf_days := GET_DAY_COUNT(
4059 p_days_in_month => l_days_in_month,
4060 p_days_in_year => l_days_in_year,
4061 p_start_date => l_next_cif_date,
4062 p_end_date => l_residuals_tbl(res_index).cf_date,
4063 p_arrears => 'Y',
4064 x_return_status => l_return_status);
4065 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4066 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4067 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4068 RAISE OKL_API.G_EXCEPTION_ERROR;
4069 END IF;
4070 END IF; -- IF l_next_cif_date >= l_residuals_tbl( res_index ).cf_date
4071 l_next_cif_date := l_residuals_tbl( res_index ).cf_date;
4072 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4073 l_residuals_tbl(res_index).cf_date || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
4074 || '|' || l_residuals_tbl(res_index).cf_days || '|' || l_residuals_tbl(res_index).cf_purpose
4075 || '|' || l_residuals_tbl(res_index).is_Arrears);
4076 -- Increment the Residual Table Index
4077 res_index := l_residuals_tbl.NEXT( res_index );
4078 END LOOP;
4079 END IF;
4080 -- Compute_iir can directly calculate the Financed Amount/Subsidy/Down payment/Trade in Amount
4081 -- without any iterations !!
4082 -- For solving the Payment/ Missing Payment/Yields compute_iir will use the
4083 -- iterative interpolation approach !
4084 IF p_pricing_method = 'SF' OR
4085 p_pricing_method = 'SS' OR
4086 p_pricing_method = 'SD' OR
4087 p_pricing_method = 'SI' OR -- Solve for Tradein
4088 p_pricing_method = 'SFP'
4089 THEN
4090 -- Pricing Logic for Solve for Financed Amount/ Solve for Subsidy
4091 l_opening_bal := 0;
4092 l_closing_bal := 0; -- Targetting l_closing_bal as zero
4093 l_rate := 0;
4094 l_interest_factor := 1;
4095 l_residual_percent := 0;
4096 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4097 'Targeting Closing Balance: ' || l_closing_bal );
4098 IF l_residuals_tbl IS NOT NULL AND
4099 l_residuals_tbl.COUNT > 0
4100 THEN
4101 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4102 'Residual Details: -----------------------------------------------------------------' );
4103 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4104 'Days/Annum | Rate | Closing Balance|Days|Residual Amount|Interest Factor on Res. Amount|Opening Balance' );
4105 res_index := l_residuals_tbl.COUNT;
4106 WHILE res_index >= 1
4107 LOOP
4108 IF p_pricing_method = 'SFP'
4109 THEN
4110 -- Sum the Residual Percentage. Cf_amount will be storing the percentages
4111 -- instead of directly the amounts
4112 l_residual_percent := l_residual_percent + nvl( l_residuals_tbl(res_index).cf_amount, 0);
4113 ELSE
4114 -- Interest calculated from p_start_date to l_residuals_tbl(res_index).cf_date
4115 l_days_per_annum := get_days_per_annum(
4116 p_day_convention => p_day_count_method,
4117 p_start_date => p_start_date,
4118 p_cash_inflow_date => l_residuals_tbl(res_index).cf_date,
4119 x_return_status => l_return_status );
4120 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4121 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4122 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4123 RAISE OKL_API.G_EXCEPTION_ERROR;
4124 END IF;
4125 l_rate := 1 + ( l_residuals_tbl(res_index).cf_days *
4126 l_residuals_tbl(res_index).cf_rate /l_days_per_annum );
4127 l_opening_bal := ( l_closing_bal + l_residuals_tbl(res_index).cf_amount ) / l_rate;
4128 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4129 l_days_per_annum || '|' || l_residuals_tbl(res_index).cf_rate || ' | ' || round(l_closing_bal,4)
4130 || '|' || l_residuals_tbl(res_index).cf_days || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
4131 || '|' || round( l_rate, 4 ) || '|' || round(l_opening_bal,4));
4132 l_closing_bal := l_opening_bal;
4133 END IF;
4134 -- Decrement the Iterator
4135 res_index := res_index - 1;
4136 END LOOP;
4137 ELSE
4138 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4139 'No Residual Amounts Passed !!! ' );
4140 END IF;
4141 IF l_cash_inflows_tbl IS NOT NULL AND
4142 l_cash_inflows_tbl.COUNT > 0
4143 THEN
4144 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4145 'Inflows Details: ------------------------------------------------------------------' );
4146 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4147 'Days/Annum | Rate | Closing Balance|Days|Inflow Amount|Interest Factor on Inflow Amount|Opening Balance' );
4148 -- Looping through Inflows in Reverse way
4149 cf_index := l_cash_inflows_tbl.COUNT;
4150 WHILE cf_index >= 1
4151 LOOP
4152 -- Interest calculated from p_start_date to l_residuals_tbl(res_index).cf_date
4153 l_days_per_annum := get_days_per_annum(
4154 p_day_convention => p_day_count_method,
4155 p_start_date => p_start_date,
4156 p_cash_inflow_date => l_cash_inflows_tbl(cf_index).cf_date,
4157 x_return_status => l_return_status );
4158 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4159 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4160 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4161 RAISE OKL_API.G_EXCEPTION_ERROR;
4162 END IF;
4163 l_rate := 1 + ( l_cash_inflows_tbl(cf_index).cf_days *
4164 l_cash_inflows_tbl(cf_index).cf_rate /l_days_per_annum );
4165 -- Multiply this interest factor
4166 IF p_pricing_method = 'SFP'
4167 THEN
4168 l_interest_factor := l_interest_factor * l_rate;
4169 END IF;
4170 l_opening_bal := ( l_closing_bal + l_cash_inflows_tbl(cf_index).cf_amount ) / l_rate;
4171 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4172 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
4173 || '|' || round(l_cash_inflows_tbl(cf_index).cf_amount,4) || '|' || round( l_rate, 4 )
4174 || '|' || round(l_opening_bal,4));
4175 l_closing_bal := l_opening_bal;
4176 -- Decrement the Iterator
4177 cf_index := cf_index - 1;
4178 END LOOP;
4179 END IF; -- IF l_cash_inflow_tbl is not null
4180 -- Now, after looping through the Residuals and then the Rent Inflows,
4181 -- the Opening Balance is nothing but the Financed Amount.
4182 -- The opening balance is the amount represent which should be the starting
4183 -- Financed Amount such that at the end the closing balance is ZERO.
4184 -- The above logic is just nothing but the Reverse Approach !!
4185 -- Store the Financed Amount and return now !
4186 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4187 'l_closing_bal | l_investment ' );
4188 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4189 ROUND( l_closing_bal, 4 ) || ' | ' || ROUND( l_investment, 4) );
4190 IF p_pricing_method = 'SF'
4191 THEN
4192 -- Solve for Financed Amount Logic
4193 px_pricing_parameter_rec.financed_amount := l_closing_bal - l_investment;
4194 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4195 'The Financed Amount should be: ' || round(px_pricing_parameter_rec.financed_amount, 4) );
4196 ELSIF p_pricing_method = 'SFP'
4197 THEN
4198 -- Solve for Financed Amount Logic when the Residuals are percentage of OEC
4199 px_pricing_parameter_rec.financed_amount := l_closing_bal - l_investment; -- This is the OEC'
4200 -- RV pays for that part of OEC that is not paid out by the payments.
4201 -- Hence, the present value of RV is infact the component of OEC that is not paid by the payments.
4202 -- so, RV component of OEC = RV / interest rate factor
4203 -- Hence, OEC = RV component of OEC + payments component of OEC ( OEC' )
4204 -- OEC = RV / interest rate factor + OEC'
4205 -- OEC = OEC' * interest_factor / ( interest_factor - residual_percent )
4206 IF l_residual_percent > 0 AND
4207 (l_interest_factor - l_residual_percent ) <> 0
4208 THEN
4209 -- If there was any residual percentage declared then only the
4210 -- RV Component of OEC will be present.
4211 -- Also, px_pricing_parameter_rec.financed_amount by now holds the OEC'
4212 px_pricing_parameter_rec.financed_amount :=
4213 (px_pricing_parameter_rec.financed_amount * l_interest_factor ) /
4214 ( l_interest_factor - l_residual_percent);
4215 END IF;
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 = 'SS'
4219 THEN
4220 -- Solve for Subsidy Amount
4221 px_pricing_parameter_rec.subsidy := l_investment - l_closing_bal;
4222 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4223 'Subsidy Amount ' || ROUND( px_pricing_parameter_rec.subsidy, 4) );
4224 ELSIF p_pricing_method = 'SI' -- Solve for Trade-in
4225 THEN
4226 -- Solve for Trade in amount ..
4227 px_pricing_parameter_rec.trade_in := l_investment - l_closing_bal;
4228 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4229 'Tradein Amount ' || ROUND( px_pricing_parameter_rec.trade_in, 4) );
4230 ELSIF p_pricing_method = 'SD'
4231 THEN
4232 -- Solve for Down payment amount ...
4233 px_pricing_parameter_rec.down_payment := l_investment - l_closing_bal;
4234 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4235 'Down Payment Amount ' || ROUND( px_pricing_parameter_rec.down_payment, 4) );
4236 END IF; -- IF p_pricing_method
4237 -- End of Pricing Logic for Solve for Financed Amount/Solve for Subsidy
4238 ELSIF p_pricing_method = 'SP' OR
4239 p_pricing_method = 'SY' OR
4240 p_pricing_method = 'SM' OR -- Solve for Missing Payment Amount !
4241 p_pricing_method = 'TR' OR
4242 p_pricing_method = 'SPP'
4243 THEN
4244 -- Initial Guess for the Payment Amount
4245 -- Formula is based on the Simple Interest Calculation ..
4246 -- Payment = (l_investment + interest for l_investment based on avg rate - Residual Value )
4247 -- / Number of Periods
4248 IF p_pricing_method = 'SP' OR
4249 p_pricing_method = 'SM' OR
4250 p_pricing_method = 'TR' OR
4251 p_pricing_method = 'SPP'
4252 THEN
4253 l_periodic_amount := ( l_investment + l_interest - l_residual_amount ) / l_cash_inflows_tbl.COUNT ;
4254 l_increment := l_periodic_amount / 2;
4255 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4256 'l_investment | l_interest | l_residual_value | Number of Terms| l_periodic_payment | First Increment' );
4257 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4258 round(l_investment, 4) || '|' || round(l_interest, 4) || '|' ||
4259 round(l_residual_amount, 4) || '|' || round(l_cash_inflows_tbl.COUNT ) || '|' ||
4260 round(l_periodic_amount, 4) || '|' || round(l_increment, 4));
4261 ELSE
4262 l_iir := nvl( p_initial_guess, 0.1 );
4263 l_increment := 0.1;
4264 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4265 'l_investment | l_residual_value | Initial IIR | First Increment' );
4266 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4267 round(l_investment, 4) || '|' || round(l_residual_amount, 4) || '|' ||
4268 round(l_iir, 4) || '|' || l_increment);
4269 END IF;
4270 -- Logic for Solve for Payments
4271 n_iterations := 1;
4272 l_crossed_zero := 'N';
4273 LOOP
4274 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Iteration # ' || n_iterations );
4275 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4276 'Cash Inflows: ----------------------------------------------------------------------------' );
4277 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4278 'Days/Annum|Rate|Days|Opening Balance|Payment Amount|Interest Income|Principal Payment|Closing Balance' );
4279 l_opening_bal := l_investment;
4280 FOR cf_index in l_cash_inflows_tbl.FIRST .. l_cash_inflows_tbl.LAST
4281 LOOP
4282 IF p_pricing_method = 'SP' OR
4283 p_pricing_method = 'TR'
4284 THEN
4285 l_payment := l_periodic_amount;
4286 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4287 ELSIF p_pricing_method = 'SPP'
4288 THEN
4289 l_payment := l_periodic_amount * nvl(l_cash_inflows_tbl(cf_index).cf_ratio,1);
4290 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4291 ELSIF p_pricing_method = 'SM'
4292 THEN
4293 IF l_cash_inflows_tbl(cf_index).cf_rate IS NOT NULL AND
4294 l_cash_inflows_tbl(cf_index).cf_amount IS NULL
4295 THEN
4296 -- Payment level for which the amount is being calculated iteratively !
4297 l_payment := l_periodic_amount;
4298 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4299 ELSE
4300 l_payment := l_cash_inflows_tbl(cf_index).cf_amount;
4301 l_rate := l_cash_inflows_tbl(cf_index).cf_rate;
4302 END IF;
4303 ELSE
4304 l_payment := l_cash_inflows_tbl(cf_index).cf_amount;
4305 l_rate := l_iir;
4306 END IF;
4307 -- Interest calculated for p_start_date to l_cash_inflows_tbl(i).cf_date
4308 l_days_per_annum := get_days_per_annum(
4309 p_day_convention => p_day_count_method,
4310 p_start_date => p_start_date,
4311 p_cash_inflow_date => l_cash_inflows_tbl(cf_index).cf_date,
4312 x_return_status => l_return_status );
4313 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4314 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4315 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4316 RAISE OKL_API.G_EXCEPTION_ERROR;
4317 END IF;
4318 IF ( l_cash_inflows_tbl(cf_index).cf_purpose = 'B' )
4319 THEN
4320 l_interest := l_opening_bal * l_cash_inflows_tbl(cf_index).cf_days
4321 * l_rate /l_days_per_annum;
4322 ELSIF ( l_cash_inflows_tbl(cf_index).cf_purpose = 'P' )
4323 THEN
4324 l_interest := 0;
4325 ELSIF ( l_cash_inflows_tbl(cf_index).cf_purpose = 'I' )
4326 THEN
4327 l_interest := l_principal_payment;
4328 END IF;
4329 l_principal_payment := l_payment - l_interest;
4330 l_closing_bal := l_opening_bal - l_principal_payment;
4331 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4332 l_days_per_annum || '|' || round(l_rate,4)
4333 || '|' || l_cash_inflows_tbl(cf_index).cf_days
4334 || '|' || round(l_opening_bal,4) || '|' || round(l_payment,4)
4335 || '|' || round(l_interest,4) || '|' || round(l_principal_payment,4)
4336 || '|' || round(l_closing_bal,4) );
4337 l_opening_bal := l_closing_bal;
4338 END LOOP;
4339 IF l_residuals_tbl IS NOT NULL AND
4340 l_residuals_tbl.COUNT > 0
4341 THEN
4342 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S','Residuals: ---------- ' );
4343 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4344 'Rate|Days|Opening Balance|Residual Amount|Interest Income|Principal Payment|Closing Balance' );
4345
4346 FOR res_index in l_residuals_tbl.FIRST .. l_residuals_tbl.LAST
4347 LOOP
4348 l_payment := l_residuals_tbl(res_index).cf_amount;
4349 IF p_pricing_method = 'SP' OR
4350 p_pricing_method = 'SM' OR
4351 p_pricing_method = 'TR' OR
4352 p_pricing_method = 'SPP'
4353 THEN
4354 l_rate := l_residuals_tbl(res_index).cf_rate;
4355 ELSE
4356 l_rate := l_iir;
4357 END IF;
4358 -- Interest calculated for p_start_date to l_cash_inflows_tbl(i).cf_date
4359 l_days_per_annum := get_days_per_annum(
4360 p_day_convention => p_day_count_method,
4361 p_start_date => p_start_date,
4362 p_cash_inflow_date => l_residuals_tbl(res_index).cf_date,
4363 x_return_status => l_return_status );
4364 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4365 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4366 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4367 RAISE OKL_API.G_EXCEPTION_ERROR;
4368 END IF;
4369 l_interest := l_opening_bal * l_residuals_tbl(res_index).cf_days
4370 * l_rate /l_days_per_annum;
4371 l_principal_payment := l_payment - l_interest;
4372 l_closing_bal := l_opening_bal - l_principal_payment;
4373 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4374 l_days_per_annum || '|' || l_rate || '|' || l_residuals_tbl(res_index).cf_days
4375 || '|' || round(l_opening_bal,4) || '|' || round(l_residuals_tbl(res_index).cf_amount,4)
4376 || '|' || round(l_interest,4) || '|' || round(l_principal_payment, 4)
4377 || '|' || round(l_closing_bal,4) );
4378 l_opening_bal := l_closing_bal;
4379 END LOOP;
4380 END IF;
4381 l_diff := l_opening_bal;
4382 IF ROUND( l_diff, 4 ) = 0
4383 THEN
4384 IF p_pricing_method = 'SP' OR
4385 p_pricing_method = 'SM' OR
4386 p_pricing_method = 'TR' OR
4387 p_pricing_method = 'SPP'
4388 THEN
4389 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4390 'CALCULATED PAYMENT AMOUNT = ' || l_periodic_amount );
4391 x_payment := l_periodic_amount;
4392 ELSE
4393 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4394 'IMPLICIT INTEREST RATE =' || l_iir );
4395 px_iir := l_iir;
4396 END IF;
4397 x_return_status := OKL_API.G_RET_STS_SUCCESS;
4398
4399 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
4400 x_msg_data => x_msg_data);
4401 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4402 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
4403 EXIT;
4404 END IF; -- If ROUND(L_DIFF, 4) = 0
4405 -- Else Use the Interpolation method
4406 IF n_iterations > 1 AND
4407 SIGN(l_diff) <> SIGN(l_prev_diff) AND
4408 l_crossed_zero = 'N'
4409 THEN
4410 l_crossed_zero := 'Y';
4411 IF ( SIGN( l_diff) = 1 )
4412 THEN
4413 -- Positive Diff ones
4414 l_positive_diff := l_diff;
4415 l_negative_diff := l_prev_diff;
4416 IF p_pricing_method = 'SP' OR
4417 p_pricing_method = 'SM' OR
4418 p_pricing_method = 'TR' OR
4419 p_pricing_method = 'SPP'
4420 THEN
4421 l_positive_diff_pay := l_periodic_amount;
4422 l_negative_diff_pay := l_prev_periodic_amount;
4423 ELSE
4424 l_positive_diff_iir := l_iir;
4425 l_negative_diff_iir := l_prev_iir;
4426 END IF;
4427 ELSE
4428 -- Negative Diff ones
4429 l_positive_diff := l_prev_diff;
4430 l_negative_diff := l_diff;
4431 IF p_pricing_method = 'SP' OR
4432 p_pricing_method = 'SM' OR
4433 p_pricing_method = 'TR' OR
4434 p_pricing_method = 'SPP'
4435 THEN
4436 l_positive_diff_pay := l_prev_periodic_amount;
4437 l_negative_diff_pay := l_periodic_amount;
4438 ELSE
4439 l_positive_diff_iir := l_prev_iir;
4440 l_negative_diff_iir := l_iir;
4441 END IF;
4442 END IF; -- IF SIGN(L_DIFF) = 1
4443 END IF; -- n_iterations > 1 IF
4444 -- Else if this is the first time store in appropriate variables
4445 IF( SIGN(l_diff) = 1)
4446 THEN
4447 l_positive_diff := l_diff;
4448 IF p_pricing_method = 'SP' OR
4449 p_pricing_method = 'SM' OR
4450 p_pricing_method = 'TR' OR
4451 p_pricing_method = 'SPP'
4452 THEN
4453 l_positive_diff_pay := l_periodic_amount;
4454 ELSE
4455 l_positive_diff_iir := l_iir;
4456 END IF;
4457 ELSE
4458 l_negative_diff := l_diff;
4459 IF p_pricing_method = 'SP' OR
4460 p_pricing_method = 'SM' OR
4461 p_pricing_method = 'TR' OR
4462 p_pricing_method = 'SPP'
4463 THEN
4464 l_negative_diff_pay := l_periodic_amount;
4465 ELSE
4466 l_negative_diff_iir := l_iir;
4467 END IF;
4468 END IF;
4469 IF l_crossed_zero = 'Y' THEN
4470 -- Use interpolation method ...
4471 IF n_iterations > 1
4472 THEN
4473 IF p_pricing_method = 'SP' OR
4474 p_pricing_method = 'SM' OR
4475 p_pricing_method = 'TR' OR
4476 p_pricing_method = 'SPP'
4477 THEN
4478 l_abs_incr := abs(( l_positive_diff_pay - l_negative_diff_pay ) /
4479 ( l_positive_diff - l_negative_diff ) * l_diff);
4480 ELSE
4481 l_abs_incr := abs(( l_positive_diff_iir - l_negative_diff_iir ) /
4482 ( l_positive_diff - l_negative_diff ) * l_diff);
4483 END IF;
4484 ELSE
4485 l_abs_incr := ABS(l_increment) / 2;
4486 END IF;
4487 ELSE
4488 l_abs_incr := ABS(l_increment);
4489 END IF;
4490
4491 IF n_iterations > 1 THEN
4492 IF SIGN(l_diff) <> l_prev_diff_sign THEN
4493 IF l_prev_incr_sign = 1 THEN
4494 l_increment := -l_abs_incr;
4495 ELSE
4496 l_increment := l_abs_incr;
4497 END IF;
4498 ELSE
4499 IF l_prev_incr_sign = 1 THEN
4500 l_increment := l_abs_incr;
4501 ELSE
4502 l_increment := - l_abs_incr;
4503 END IF;
4504 END IF;
4505 ELSE -- First Iteration
4506 IF p_pricing_method = 'SP' OR
4507 p_pricing_method = 'SM' OR
4508 p_pricing_method = 'TR' OR
4509 p_pricing_method = 'SPP'
4510 THEN
4511 l_increment := -l_increment;
4512 END IF;
4513 IF SIGN(l_diff) = 1 THEN
4514 l_increment := -l_increment;
4515 ELSE
4516 l_increment := l_increment;
4517 END IF;
4518 END IF;
4519 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4520 'l_diff ' || round(l_diff,4) );
4521 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4522 'l_prev_diff ' || round(l_prev_diff,4) );
4523 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4524 'l_crossed_zero ' || l_crossed_zero );
4525 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4526 'l_abs_incr ' || l_abs_incr );
4527 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4528 'l_increment ' || l_increment );
4529 IF p_pricing_method = 'SP' OR
4530 p_pricing_method = 'SM' OR
4531 p_pricing_method = 'TR' OR
4532 p_pricing_method = 'SPP'
4533 THEN
4534 l_prev_periodic_amount := l_periodic_amount;
4535 l_periodic_amount := l_periodic_amount + l_increment;
4536 ELSE
4537 l_prev_iir := l_iir;
4538 l_iir := l_iir + l_increment;
4539 END IF;
4540 IF n_iterations > 100
4541 THEN
4542 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
4543 p_msg_name => 'OKL_IIR_CALC_IIR_LIMIT',
4544 p_token1 => 'IIR_LIMIT',
4545 p_token1_value => 100);
4546 RAISE OKL_API.G_EXCEPTION_ERROR;
4547 END IF;
4548 l_prev_incr_sign := SIGN(l_increment);
4549 l_prev_diff_sign := SIGN(l_diff);
4550 l_prev_diff := l_diff;
4551 -- Increment the n_iterations index ..
4552 n_iterations := n_iterations + 1;
4553 END LOOP; -- Loop on n_iterations
4554 -- End of the Pricing Logic for Solve for Payments
4555 END IF; -- IF p_pricing_method ...
4556 -- Set ther return values and return them !!
4557 x_return_status := l_return_status;
4558 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
4559 x_msg_data => x_msg_data);
4560 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4561 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
4562 EXCEPTION
4563 WHEN OKL_API.G_EXCEPTION_ERROR THEN
4564 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4565 p_api_name => l_api_name,
4566 p_pkg_name => G_PKG_NAME,
4567 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
4568 x_msg_count => x_msg_count,
4569 x_msg_data => x_msg_data,
4570 p_api_type => g_api_type);
4571 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
4572 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4573 p_api_name => l_api_name,
4574 p_pkg_name => G_PKG_NAME,
4575 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
4576 x_msg_count => x_msg_count,
4577 x_msg_data => x_msg_data,
4578 p_api_type => g_api_type);
4579 WHEN OTHERS THEN
4580 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4581 p_api_name => l_api_name,
4582 p_pkg_name => G_PKG_NAME,
4583 p_exc_name => 'OTHERS',
4584 x_msg_count => x_msg_count,
4585 x_msg_data => x_msg_data,
4586 p_api_type => g_api_type);
4587 END compute_iir;
4588
4589 -- Validates whether for a particular object ( Eg. Quick Quote )
4590 -- the inputed pricing method is valid or not ( Eg. SY, TR, SP, SF .. etc )
4591 FUNCTION validate_pricing_method(
4592 p_pricing_method IN VARCHAR2,
4593 p_object_type IN VARCHAR2,
4594 x_return_status IN OUT NOCOPY VARCHAR2)
4595 RETURN BOOLEAN
4596 IS
4597 l_valid BOOLEAN;
4598 BEGIN
4599 l_valid := FALSE;
4600 --print( 'validate_pricing_method: p_pricing_method = ' || p_pricing_method );
4601 IF 'RC|SF|SP|SS|SY|TR' LIKE '%'||p_pricing_method||'%' AND
4602 p_object_type = 'QQ'
4603 THEN
4604 l_valid := TRUE;
4605 END IF;
4606 x_return_status := OKL_API.G_RET_STS_SUCCESS;
4607 RETURN l_valid;
4608 EXCEPTION
4609 WHEN OKL_API.G_EXCEPTION_ERROR
4610 THEN
4611 x_return_status := G_RET_STS_ERROR;
4612 RETURN false;
4613 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR
4614 THEN
4615 x_return_status := G_RET_STS_UNEXP_ERROR;
4616 RETURN false;
4617 WHEN OTHERS
4618 THEN
4619 OKL_API.SET_MESSAGE (
4620 p_app_name => G_APP_NAME,
4621 p_msg_name => G_DB_ERROR,
4622 p_token1 => G_PROG_NAME_TOKEN,
4623 p_token1_value => 'validate_pricing_method',
4624 p_token2 => G_SQLCODE_TOKEN,
4625 p_token2_value => sqlcode,
4626 p_token3 => G_SQLERRM_TOKEN,
4627 p_token3_value => sqlerrm);
4628
4629 x_return_status := G_RET_STS_UNEXP_ERROR;
4630 RETURN false;
4631 END validate_pricing_method;
4632
4633
4634 -- API which accepts the Lease Rate Set id
4635 -- and returns all the Lease Rate set Details, Factors, and Levels
4636 -- based on the term and end of term %age passeed.
4637 PROCEDURE get_lease_rate_factors(
4638 p_api_version IN NUMBER,
4639 p_init_msg_list IN VARCHAR2,
4640 x_return_status OUT NOCOPY VARCHAR2,
4641 x_msg_count OUT NOCOPY NUMBER,
4642 x_msg_data OUT NOCOPY VARCHAR2,
4643 p_lrt_id IN NUMBER, -- Assuming LRS ID Header
4644 p_start_date IN DATE,
4645 p_term_in_months IN NUMBER,
4646 p_eot_percentage IN NUMBER,
4647 x_lrs_details OUT NOCOPY lrs_details_rec_type,
4648 x_lrs_factor OUT NOCOPY lrs_factor_rec_type,
4649 x_lrs_levels OUT NOCOPY lrs_levels_tbl_type)
4650 IS
4651 -- Cursor Declarations
4652 CURSOR lrs_version_details_csr(
4653 p_lrs_version_id IN okl_ls_rt_fctr_sets_v.ID%TYPE,
4654 p_date IN DATE )
4655 IS
4656 SELECT
4657 hdr.id header_id,
4658 ver.rate_set_version_id version_id,
4659 hdr.NAME name,
4660 hdr.lrs_type_code lrs_type_code,
4661 hdr.FRQ_CODE frq_code,
4662 hdr.currency_code currency_code,
4663 ver.sts_code sts_code,
4664 ver.effective_from_date effective_from_date,
4665 ver.effective_to_date effective_to_date,
4666 ver.arrears_yn arrears_yn,
4667 ver.end_of_term_ver_id end_of_term_ver_id,
4668 ver.std_rate_tmpl_ver_id std_rate_tmpl_ver_id,
4669 ver.adj_mat_version_id adj_mat_version_id,
4670 ver.version_number version_number,
4671 ver.lrs_rate lrs_version_rate,
4672 ver.rate_tolerance rate_tolerance,
4673 ver.residual_tolerance residual_tolerance,
4674 ver.deferred_pmts deferred_pmts,
4675 ver.advance_pmts advance_pmts
4676 FROM okl_ls_rt_fctr_sets_v hdr,
4677 okl_fe_rate_set_versions_v ver
4678 WHERE ver.rate_set_id = hdr.id
4679 AND ver.rate_set_version_id = p_lrs_version_id
4680 AND trunc(ver.effective_from_date) <= p_date
4681 AND nvl(trunc(ver.effective_to_date), p_date) >= p_date;
4682
4683 CURSOR lrs_factors_csr(
4684 p_lrs_version_id IN NUMBER,
4685 p_term IN NUMBER,
4686 p_eot_percentage IN NUMBER,
4687 p_res_tolerance IN NUMBER -- From the version record
4688 )
4689 IS
4690 SELECT fac.id factor_id,
4691 fac.term_in_months term_in_months,
4692 fac.residual_value_percent residual_value_percent
4693 FROM okl_ls_rt_fctr_ents_v fac
4694 WHERE fac.rate_set_version_id = p_lrs_version_id
4695 AND fac.term_in_months = p_term
4696 AND p_eot_percentage BETWEEN fac.residual_value_percent - nvl(p_res_tolerance, 0) AND
4697 fac.residual_value_percent + nvl(p_res_tolerance, 0);
4698
4699
4700 CURSOR lrs_levels_csr( p_lrs_factor_id IN NUMBER )
4701 IS
4702 SELECT lvl.sequence_number sequence_number,
4703 lvl.periods periods,
4704 lvl.lease_rate_factor lease_rate_factor
4705 FROM okl_fe_rate_set_levels lvl
4706 WHERE lvl.rate_set_factor_id = p_lrs_factor_id
4707 ORDER BY sequence_number ASC;
4708
4709 -- Local Variables
4710 l_api_version CONSTANT NUMBER DEFAULT 1.0;
4711 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lease_rate_factors';
4712 l_return_status VARCHAR2(1);
4713 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
4714 || G_PKG_NAME || '.' || UPPER(l_api_name);
4715 l_debug_enabled VARCHAR2(10);
4716 is_debug_procedure_on BOOLEAN;
4717 is_debug_statement_on BOOLEAN;
4718 -- Variable Declarations
4719 lrs_details_rec lrs_details_rec_type;
4720 lrs_factor lrs_factor_rec_type;
4721 lrs_levels lrs_levels_tbl_type;
4722 lvl_index NUMBER;
4723 BEGIN
4724 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4725 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
4726 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
4727 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4728 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
4729 -- check for logging on STATEMENT level
4730 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
4731 -- Call START_ACTIVITY to create savepoint, check compatibility
4732 -- and initialize message list
4733 l_return_status := OKL_API.START_ACTIVITY(
4734 p_api_name => l_api_name,
4735 p_pkg_name => G_PKG_NAME,
4736 p_init_msg_list => p_init_msg_list,
4737 l_api_version => l_api_version,
4738 p_api_version => p_api_version,
4739 p_api_type => g_api_type,
4740 x_return_status => x_return_status);
4741 --Check if activity started successfully
4742 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4743 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4744 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4745 RAISE OKL_API.G_EXCEPTION_ERROR;
4746 END IF;
4747 -- Actual logic Begins here
4748 IF p_start_date IS NULL OR
4749 p_lrt_id IS NULL OR
4750 p_eot_percentage IS NULL OR
4751 p_term_in_months IS NULL
4752 THEN
4753 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4754 'Missing required input value ' );
4755
4756 RAISE OKL_API.G_EXCEPTION_ERROR;
4757 END IF;
4758 -- Start with fetching the Lease Rate Set Header n Version information
4759 l_return_status := OKL_API.G_RET_STS_ERROR;
4760 FOR t_rec IN lrs_version_details_csr(
4761 p_lrs_version_id => p_lrt_id,
4762 p_date => p_start_date)
4763 LOOP
4764 lrs_details_rec.header_id := t_rec.header_id;
4765 lrs_details_rec.version_id := t_rec.version_id;
4766 lrs_details_rec.name := t_rec.name;
4767 lrs_details_rec.lrs_type_code := t_rec.lrs_type_code;
4768 lrs_details_rec.frq_code := t_rec.frq_code;
4769 lrs_details_rec.currency_code := t_rec.currency_code;
4770 lrs_details_rec.sts_code := t_rec.sts_code;
4771 lrs_details_rec.effective_from_date := t_rec.effective_from_date;
4772 lrs_details_rec.effective_to_date := t_rec.effective_to_date ;
4773 lrs_details_rec.arrears_yn := t_rec.arrears_yn ;
4774 lrs_details_rec.end_of_term_ver_id := t_rec.end_of_term_ver_id ;
4775 lrs_details_rec.std_rate_tmpl_ver_id := t_rec.std_rate_tmpl_ver_id ;
4776 lrs_details_rec.adj_mat_version_id := t_rec.adj_mat_version_id ;
4777 lrs_details_rec.version_number := t_rec.version_number ;
4778 lrs_details_rec.lrs_version_rate := t_rec.lrs_version_rate ;
4779 lrs_details_rec.rate_tolerance := t_rec.rate_tolerance ;
4780 lrs_details_rec.residual_tolerance := t_rec.residual_tolerance ;
4781 lrs_details_rec.deferred_pmts := t_rec.deferred_pmts ;
4782 lrs_details_rec.advance_pmts := t_rec.advance_pmts ;
4783 -- Using l_return_status as a flag
4784 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4785 END LOOP;
4786 IF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4787 RAISE OKL_API.G_EXCEPTION_ERROR;
4788 END IF;
4789 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4790 ' Successfully fetched the Lease Rate Set Header n Version Details !' );
4791 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4792 ' p_term_in_months | p_eof_percentage | Residual Tolerance ' ||
4793 p_term_in_months || ' | ' || round(p_eot_percentage, 4)
4794 || ' | ' || round(lrs_details_rec.residual_tolerance, 4));
4795 -- Fetch the Factors Information
4796 l_return_status := OKL_API.G_RET_STS_ERROR;
4797 FOR t_rec IN lrs_factors_csr(
4798 p_lrs_version_id => lrs_details_rec.version_id,
4799 p_term => p_term_in_months,
4800 p_eot_percentage => p_eot_percentage,
4801 p_res_tolerance => lrs_details_rec.residual_tolerance)
4802 LOOP
4803 lrs_factor.factor_id := t_rec.factor_id;
4804 lrs_factor.term_in_months := t_rec.term_in_months;
4805 lrs_factor.residual_value_percent := t_rec.residual_value_percent;
4806 -- Using l_return_status as a flag
4807 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4808 END LOOP; -- lrs_factors
4809 IF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4810 RAISE OKL_API.G_EXCEPTION_ERROR;
4811 END IF;
4812 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4813 'Successfully fetched the Lesae Rate Set Factors !' );
4814 -- Fetch the levels Information
4815 l_return_status := OKL_API.G_RET_STS_ERROR;
4816 lvl_index := 1;
4817 FOR t_rec IN lrs_levels_csr( p_lrs_factor_id => lrs_factor.factor_id )
4818 LOOP
4819 lrs_levels(lvl_index).sequence_number := t_rec.sequence_number;
4820 lrs_levels(lvl_index).periods := t_rec.periods;
4821 lrs_levels(lvl_index).lease_rate_factor := t_rec.lease_rate_factor;
4822 -- Using l_return_status as a flag
4823 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4824 -- Increment the lvl_index
4825 lvl_index := lvl_index + 1;
4826 END LOOP; -- lrs_levels
4827 IF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4828 RAISE OKL_API.G_EXCEPTION_ERROR;
4829 END IF;
4830 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4831 'Successfully fetched the Lease Rate Factor Levels !' );
4832 -- Setting up the return variables ...
4833 x_lrs_details := lrs_details_rec;
4834 x_lrs_factor := lrs_factor;
4835 x_lrs_levels := lrs_levels;
4836 x_return_status := l_return_status;
4837 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
4838 x_msg_data => x_msg_data);
4839 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4840 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
4841 EXCEPTION
4842 WHEN OKL_API.G_EXCEPTION_ERROR THEN
4843 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4844 p_api_name => l_api_name,
4845 p_pkg_name => G_PKG_NAME,
4846 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
4847 x_msg_count => x_msg_count,
4848 x_msg_data => x_msg_data,
4849 p_api_type => g_api_type);
4850 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
4851 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4852 p_api_name => l_api_name,
4853 p_pkg_name => G_PKG_NAME,
4854 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
4855 x_msg_count => x_msg_count,
4856 x_msg_data => x_msg_data,
4857 p_api_type => g_api_type);
4858 WHEN OTHERS THEN
4859 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4860 p_api_name => l_api_name,
4861 p_pkg_name => G_PKG_NAME,
4862 p_exc_name => 'OTHERS',
4863 x_msg_count => x_msg_count,
4864 x_msg_data => x_msg_data,
4865 p_api_type => g_api_type);
4866 END get_lease_rate_factors;
4867
4868 -- API which accepts the standard rate template version id and
4869 -- returns all the SRT details !
4870 PROCEDURE get_standard_rates(
4871 p_api_version IN NUMBER,
4872 p_init_msg_list IN VARCHAR2,
4873 x_return_status OUT NOCOPY VARCHAR2,
4874 x_msg_count OUT NOCOPY NUMBER,
4875 x_msg_data OUT NOCOPY VARCHAR2,
4876 p_srt_id IN NUMBER, -- Version ID
4877 p_start_date IN DATE,
4878 x_srt_details OUT NOCOPY srt_details_rec_type)
4879 IS
4880 -- Cursor Declarations
4881 CURSOR srt_details_csr(
4882 p_srt_version_id IN NUMBER,
4883 p_date IN DATE )
4884 IS
4885 SELECT hdr.std_rate_tmpl_id srt_header_id,
4886 ver.std_rate_tmpl_ver_id srt_version_id,
4887 hdr.template_name template_name,
4888 hdr.currency_code currency_code,
4889 ver.version_number version_number,
4890 ver.effective_from_date effective_from_date,
4891 ver.effective_to_date effective_to_date,
4892 ver.sts_code sts_code,
4893 hdr.pricing_engine_code pricing_engine_code,
4894 hdr.rate_type_code rate_type_code,
4895 ver.srt_rate srt_rate,
4896 hdr.index_id index_id,
4897 ver.spread spread,
4898 ver.day_convention_code day_convention_code,
4899 hdr.frequency_code frequency_code,
4900 ver.adj_mat_version_id adj_mat_version_id,
4901 ver.min_adj_rate min_adj_rate,
4902 ver.max_adj_rate max_adj_rate
4903 FROM okl_fe_std_rt_tmp_v hdr,
4904 okl_fe_std_rt_tmp_vers ver
4905 WHERE ver.std_rate_tmpl_ver_id = p_srt_version_id AND
4906 hdr.std_rate_tmpl_id = ver.std_rate_tmpl_id AND
4907 ver.effective_from_date <= p_date AND
4908 nvl(ver.effective_to_date, p_date) >= p_date;
4909
4910 -- Fetch the Rate from the if the rate_type_code is INDEX.
4911 Cursor srt_index_rate_csr(
4912 p_srt_header_id IN NUMBER,
4913 p_date IN DATE)
4914 IS
4915 SELECT indx.value srt_rate
4916 FROM okl_fe_std_rt_tmp_all_b hdr,
4917 okl_index_values indx
4918 WHERE hdr.std_rate_tmpl_id = p_srt_header_id
4919 AND hdr.index_id = indx.idx_id
4920 AND p_date BETWEEN indx.datetime_valid AND NVL(indx.datetime_invalid,p_date+1);
4921 -- Local Variables
4922 l_api_version CONSTANT NUMBER DEFAULT 1.0;
4923 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_standard_rates';
4924 l_return_status VARCHAR2(1);
4925 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
4926 || G_PKG_NAME || '.' || UPPER(l_api_name);
4927 l_debug_enabled VARCHAR2(10);
4928 is_debug_procedure_on BOOLEAN;
4929 is_debug_statement_on BOOLEAN;
4930 srt_details srt_details_rec_type;
4931 BEGIN
4932 l_return_status := OKL_API.G_RET_STS_SUCCESS;
4933 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
4934 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
4935
4936 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
4937 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
4938 -- check for logging on STATEMENT level
4939 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
4940 -- Call START_ACTIVITY to create savepoint, check compatibility
4941 -- and initialize message list
4942 l_return_status := OKL_API.START_ACTIVITY(
4943 p_api_name => l_api_name,
4944 p_pkg_name => G_PKG_NAME,
4945 p_init_msg_list => p_init_msg_list,
4946 l_api_version => l_api_version,
4947 p_api_version => p_api_version,
4948 p_api_type => g_api_type,
4949 x_return_status => x_return_status);
4950 --Check if activity started successfully
4951 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
4952 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4953 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
4954 RAISE OKL_API.G_EXCEPTION_ERROR;
4955 END IF;
4956 IF p_start_date IS NULL
4957 THEN
4958 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4959 'Start Date is null !! ' );
4960 OKL_API.set_message(
4961 G_APP_NAME,
4962 OKL_API.G_INVALID_VALUE,
4963 OKL_API.G_COL_NAME_TOKEN,
4964 'EXPECTED START DATE');
4965 RAISE OKL_API.G_EXCEPTION_ERROR;
4966 END IF;
4967 IF p_srt_id IS NULL
4968 THEN
4969 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4970 'Standard Rate Template ID is required !! ' );
4971 OKL_API.set_message(
4972 G_APP_NAME,
4973 OKL_API.G_REQUIRED_VALUE,
4974 OKL_API.G_COL_NAME_TOKEN,
4975 'STANDARD RATE TEMPLATE ID');
4976 RAISE OKL_API.G_EXCEPTION_ERROR;
4977 END IF;
4978 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4979 ': p_srt_id= ' || p_srt_id );
4980 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
4981 ': p_start_date= '|| p_start_date );
4982
4983 l_return_status := OKL_API.G_RET_STS_ERROR;
4984 FOR t_rec IN srt_details_csr(
4985 p_srt_version_id => p_srt_id,
4986 p_date => p_start_date )
4987 LOOP
4988 srt_details.srt_header_id := t_rec.srt_header_id;
4989 srt_details.srt_version_id := t_rec.srt_version_id;
4990 srt_details.template_name := t_rec.template_name;
4991 srt_details.currency_code := t_rec.currency_code;
4992 srt_details.version_number := t_rec.version_number;
4993 srt_details.effective_from_date := t_rec.effective_from_date;
4994 srt_details.effective_to_date := t_rec.effective_to_date;
4995 srt_details.sts_code := t_rec.sts_code;
4996 srt_details.pricing_engine_code := t_rec.pricing_engine_code;
4997 srt_details.rate_type_code := t_rec.rate_type_code;
4998 srt_details.srt_rate := t_rec.srt_rate;
4999 srt_details.index_id := t_rec.index_id;
5000 srt_details.spread := t_rec.spread;
5001 srt_details.day_convention_code := t_rec.day_convention_code;
5002 srt_details.frequency_code := t_rec.frequency_code;
5003 srt_details.adj_mat_version_id := t_rec.adj_mat_version_id;
5004 srt_details.min_adj_rate := t_rec.min_adj_rate;
5005 srt_details.max_adj_rate := t_rec.max_adj_rate;
5006 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5007 'Successfully fetched the SRT Header n Version Details ' );
5008 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5009 'SRT Rate Type Code | Min Adj Rate | Max. Adj Rate | Rate | Spread ');
5010 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5011 srt_details.rate_type_code || ' | ' || srt_details.min_adj_rate
5012 || ' | ' || srt_details.max_adj_rate || ' | ' || srt_details.srt_rate || ' | ' || srt_details.spread);
5013
5014 -- Using l_return_status as flag
5015 l_return_status := OKL_API.G_RET_STS_SUCCESS;
5016 END LOOP; -- srt_details_csr
5017 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5018 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5019 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5020 RAISE OKL_API.G_EXCEPTION_ERROR;
5021 END IF;
5022
5023 IF srt_details.rate_type_code = G_QQ_SRT_RATE_TYPE
5024 THEN
5025 -- Initialize l_return_status to 'E'
5026 l_return_status := OKL_API.G_RET_STS_ERROR;
5027 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5028 ': p_srt_header_id = ' || srt_details.srt_header_id );
5029 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5030 ': p_start_date=' || p_start_date );
5031 FOR t_rec IN srt_index_rate_csr(
5032 p_srt_header_id => srt_details.srt_header_id,
5033 p_date => p_start_date)
5034 LOOP
5035 srt_details.srt_rate := t_rec.srt_rate;
5036 -- Using l_return_status as flag
5037 l_return_status := OKL_API.G_RET_STS_SUCCESS;
5038 END LOOP; -- srt_index_rate_csr
5039 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5040 ': After srt_index_rate_csr ' || l_return_status );
5041 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5042 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5043 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5044 RAISE OKL_API.G_EXCEPTION_ERROR;
5045 END IF;
5046 END IF; -- IF srt_details.rate_type_code = 'INDEX'
5047 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5048 'Rate from the SRT ' || srt_details.srt_rate );
5049 -- Setting up the return variables ..
5050 x_srt_details := srt_details;
5051 x_return_status := OKL_API.G_RET_STS_SUCCESS;
5052 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
5053 x_msg_data => x_msg_data);
5054 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
5055 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
5056 EXCEPTION
5057 WHEN OKL_API.G_EXCEPTION_ERROR THEN
5058 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5059 p_api_name => l_api_name,
5060 p_pkg_name => G_PKG_NAME,
5061 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
5062 x_msg_count => x_msg_count,
5063 x_msg_data => x_msg_data,
5064 p_api_type => g_api_type);
5065 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
5066 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5067 p_api_name => l_api_name,
5068 p_pkg_name => G_PKG_NAME,
5069 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
5070 x_msg_count => x_msg_count,
5071 x_msg_data => x_msg_data,
5072 p_api_type => g_api_type);
5073 WHEN OTHERS THEN
5074 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5075 p_api_name => l_api_name,
5076 p_pkg_name => G_PKG_NAME,
5077 p_exc_name => 'OTHERS',
5078 x_msg_count => x_msg_count,
5079 x_msg_data => x_msg_data,
5080 p_api_type => g_api_type);
5081 END get_standard_rates;
5082
5083 PROCEDURE compute_bk_yield(
5084 p_api_version IN NUMBER,
5085 p_init_msg_list IN VARCHAR2,
5086 x_return_status OUT NOCOPY VARCHAR2,
5087 x_msg_count OUT NOCOPY NUMBER,
5088 x_msg_data OUT NOCOPY VARCHAR2,
5089 p_start_date IN DATE,
5090 p_day_count_method IN VARCHAR2,
5091 p_pricing_method IN VARCHAR2,
5092 p_initial_guess IN NUMBER,
5093 p_term IN NUMBER,
5094 px_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type,
5095 x_bk_yield IN OUT NOCOPY NUMBER,
5096 x_termination_tbl OUT NOCOPY cash_inflows_tbl_type,
5097 x_pre_tax_inc_tbl OUT NOCOPY cash_inflows_tbl_type)
5098 IS
5099 -- Local Variables
5100 l_api_version CONSTANT NUMBER DEFAULT 1.0;
5101 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'compute_bk_yield';
5102 l_return_status VARCHAR2(1);
5103 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
5104 || G_PKG_NAME || '.' || UPPER(l_api_name);
5105 l_debug_enabled VARCHAR2(10);
5106 is_debug_procedure_on BOOLEAN;
5107 is_debug_statement_on BOOLEAN;
5108 l_start_date DATE;
5109 l_end_date DATE;
5110 i NUMBER;
5111 p NUMBER;
5112 t NUMBER;
5113 m NUMBER;
5114 l_days_in_month VARCHAR2(30);
5115 l_days_in_year VARCHAR2(30);
5116 cf_index NUMBER;
5117 l_se_date DATE;
5118 res_index NUMBER;
5119 l_days NUMBER;
5120 l_tmp_interest NUMBER;
5121 l_is_arrears VARCHAR2(1);
5122 l_cf_inflows cash_inflows_tbl_type;
5123 l_residuals cash_inflows_tbl_type;
5124 l_termination_val_tbl cash_inflows_tbl_type;
5125 l_pre_tax_income_tbl cash_inflows_tbl_type;
5126 l_investment NUMBER := 0;
5127 l_residual_amount NUMBER := 0;
5128 l_termination_val NUMBER := 0;
5129 n_iterations NUMBER;
5130 l_k_start_date DATE;
5131 l_k_end_date DATE;
5132 l_k_se_date DATE;
5133 l_term_complete VARCHAR2(1) := 'N';
5134 l_crossed_zero VARCHAR2(1) := 'N';
5135 l_diff NUMBER;
5136 l_prev_diff NUMBER;
5137 l_prev_diff_sign NUMBER;
5138 l_prev_incr_sign NUMBER;
5139 l_positive_diff NUMBER;
5140 l_negative_diff NUMBER;
5141 l_bk_yield NUMBER;
5142 l_prev_bk_yeild NUMBER;
5143 l_increment NUMBER := 0.1;
5144 l_abs_incr NUMBER := 0;
5145 l_positive_diff_bk_yeild NUMBER := 0;
5146 l_negative_diff_bk_yeild NUMBER := 0;
5147 l_days_per_annum NUMBER := 0;
5148 BEGIN
5149 l_return_status := OKL_API.G_RET_STS_SUCCESS;
5150 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
5151 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
5152 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
5153 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
5154 -- check for logging on STATEMENT level
5155 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
5156 -- Call START_ACTIVITY to create savepoint, check compatibility
5157 -- and initialize message list
5158 l_return_status := OKL_API.START_ACTIVITY(
5159 p_api_name => l_api_name,
5160 p_pkg_name => G_PKG_NAME,
5161 p_init_msg_list => p_init_msg_list,
5162 l_api_version => l_api_version,
5163 p_api_version => p_api_version,
5164 p_api_type => g_api_type,
5165 x_return_status => x_return_status);
5166 --Check if activity started successfully
5167 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5168 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5169 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5170 RAISE OKL_API.G_EXCEPTION_ERROR;
5171 END IF;
5172 -- Actual logic Begins here
5173 -- Validate the input parameters
5174 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5175 'COMPUTE_BK_YIELD -------------- Start !! ' );
5176 get_days_in_year_and_month(
5177 p_day_count_method => p_day_count_method,
5178 x_days_in_month => l_days_in_month,
5179 x_days_in_year => l_days_in_year,
5180 x_return_status => l_return_status);
5181 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5182 'After get_day_count_method ' || l_return_status);
5183 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5184 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5185 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5186 RAISE OKL_API.G_EXCEPTION_ERROR;
5187 END IF;
5188
5189 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5190 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
5191 IF p_start_date IS NULL OR
5192 p_term IS NULL OR p_term <= 0 OR
5193 px_pricing_parameter_rec.cash_inflows IS NULL OR
5194 px_pricing_parameter_rec.cash_inflows.COUNT <= 0
5195 THEN
5196 -- Show the error message and
5197 RAISE OKL_API.G_EXCEPTION_ERROR;
5198 END IF;
5199 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5200 'Input Parameters p_start_date, count(cash_inflows) = '
5201 || p_start_date || ',' || px_pricing_parameter_rec.cash_inflows.COUNT );
5202 -- Dealing with the Cash Inflows
5203 l_start_date := p_start_date;
5204 cf_index := 1;
5205 i := px_pricing_parameter_rec.cash_inflows.FIRST;
5206 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5207 'Date | Amount | Arrears ' );
5208 WHILE i <= px_pricing_parameter_rec.cash_inflows.LAST
5209 LOOP
5210 l_cf_inflows(cf_index) := px_pricing_parameter_rec.cash_inflows(i);
5211 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5212 l_cf_inflows(cf_index).cf_date
5213 || ' | ' || l_cf_inflows(cf_index).cf_amount || ' | ' ||
5214 l_cf_inflows(cf_index).is_arrears );
5215 -- Increment the indexes
5216 i := px_pricing_parameter_rec.cash_inflows.NEXT( i );
5217 cf_index := cf_index + 1;
5218 END LOOP; -- WHILE cf_index <= l_cf_inflows.LAST
5219 -- Dealing with the Residual Inflows now .. :-;
5220 l_start_date := p_start_date;
5221 l_residual_amount := 0;
5222 res_index := 1;
5223 i := px_pricing_parameter_rec.residual_inflows.FIRST;
5224 WHILE i <= px_pricing_parameter_rec.residual_inflows.LAST
5225 LOOP
5226 l_residuals(res_index) := px_pricing_parameter_rec.residual_inflows(i);
5227 -- Store the total Residual Amount
5228 l_residual_amount := l_residual_amount + nvl( l_residuals(res_index).cf_amount, 0 );
5229 -- cf_amount, cf_date, is_stub, is_arrears, cf_dpp, cf_ppy, cf_days,( cf_rate ?? )
5230 -- would have been already populated.
5231 -- Increment the indexes
5232 i := l_residuals.NEXT( i );
5233 res_index := res_index + 1;
5234 END LOOP; -- WHILE cf_index <= l_cf_inflows.LAST
5235 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5236 'Total Residual Amount ' || round(l_residual_amount , 4) );
5237 -- Calculation of the Invested amount
5238 -- Investment = Item Original Cost ( Financed amount ) - Subsidy - Down Payment - Trade In;
5239 l_investment := nvl( px_pricing_parameter_rec.financed_amount, 0 ) -
5240 nvl( px_pricing_parameter_rec.subsidy, 0 ) -
5241 nvl( px_pricing_parameter_rec.down_payment, 0 ) -
5242 nvl( px_pricing_parameter_rec.trade_in, 0 );
5243 IF l_investment <= 0
5244 THEN
5245 -- Initial Investment itself cant be negative !!
5246 RAISE OKL_API.G_EXCEPTION_ERROR;
5247 END IF; -- IF l_investment ..
5248
5249 -- Initialize the things
5250 n_iterations := 0;
5251 l_k_start_date := p_start_date;
5252 l_bk_yield := nvl( p_initial_guess, 0.1 );
5253 l_increment := 0.1;
5254 l_is_arrears := l_cf_inflows(1).is_arrears;
5255 -- Fetch the end date
5256 okl_stream_generator_pvt.add_months_new(
5257 p_start_date => l_start_date,
5258 p_months_after => p_term,
5259 x_date => l_k_end_date,
5260 x_return_status => l_return_status);
5261 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5262 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5263 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5264 RAISE OKL_API.G_EXCEPTION_ERROR;
5265 END IF;
5266 l_k_end_date := l_k_end_date - 1;
5267 -- Actual Logic for calculation of the Booking Yield.
5268 LOOP
5269 -- Incrementing the Iteration Index
5270 n_iterations := n_iterations + 1;
5271 -- Initialize the things
5272 l_termination_val := l_investment;
5273 l_pre_tax_income_tbl.DELETE;
5274 l_termination_val_tbl.DELETE;
5275 cf_index := 1;
5276 p := 1;
5277 t := 1;
5278 l_term_complete := 'N';
5279 l_crossed_zero := 'N';
5280 l_start_date := l_k_start_date;
5281 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5282 'Iteration # ' || n_iterations );
5283 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5284 'Booking |-Investment-|-Residual-|-Termination-|--------------|--------------|');
5285 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5286 '-Yield--|------------|--Value---|-----Value---|l_k_start_date| l_k_end_date |');
5287 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5288 round( l_bk_yield, 4 ) || '|' || round(l_investment , 4) || '|' || round(l_residual_amount , 4)
5289 || '|' || round(l_termination_val , 4) || '|' || l_k_start_date || '|' || l_k_end_date);
5290 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5291 'Bk. Yield | Arrears | Days/Annum | Start Date | End Date | Days | Interest | Termination value ' );
5292 -- Main while loop ... !!! Loops until the term completes ;-)
5293 WHILE l_term_complete = 'N'
5294 LOOP
5295 IF LAST_DAY( trunc(l_start_date) ) <>
5296 LAST_DAY( trunc(l_cf_inflows(cf_index).cf_date ) )
5297 THEN
5298 -- Handling till the end of the month ..
5299 -- Period: ( l_start_date, LAST_DAY(l_start_day) ]
5300 l_end_date := LAST_DAY( l_start_date );
5301 l_days := get_day_count(
5302 p_days_in_month => l_days_in_month,
5303 p_days_in_year => l_days_in_year,
5304 p_start_date => l_start_date,
5305 p_end_date => l_end_date,
5306 p_arrears => 'Y', -- Calculate until the end of the month !
5307 x_return_status => l_return_status);
5308 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5309 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5310 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5311 RAISE OKL_API.G_EXCEPTION_ERROR;
5312 END IF;
5313 l_days_per_annum := get_days_per_annum(
5314 p_day_convention => p_day_count_method,
5315 p_start_date => p_start_date,
5316 p_cash_inflow_date => l_start_date,
5317 x_return_status => l_return_status );
5318 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5319 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5320 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5321 RAISE OKL_API.G_EXCEPTION_ERROR;
5322 END IF;
5323 l_tmp_interest := l_termination_val * l_days * l_bk_yield / l_days_per_annum;
5324 l_termination_val := l_termination_val + l_tmp_interest;
5325 l_termination_val_tbl(t).cf_amount := l_termination_val;
5326 -- Making the l_se_date to LAST_DAY(l_start_date)
5327 l_se_date := LAST_DAY(l_start_date);
5328 IF ( nvl(p_day_count_method, 'THIRTY') = 'THIRTY' AND
5329 TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' ) OR
5330 ( nvl(p_day_count_method, 'THIRTY' ) = '365' AND
5331 TO_CHAR(LAST_DAY(l_se_date), 'DD' ) = '29' AND
5332 TO_CHAR(l_se_date, 'MON' ) = 'FEB' )
5333 THEN
5334 l_se_date := l_se_date - 1;
5335 END IF;
5336 l_termination_val_tbl(t).cf_date := LAST_DAY(l_se_date);
5337 t := t + 1;
5338 -- If l_start_date = l_k_start_date OR
5339 -- l_start_date is first of the month then no need to accumulate the pretax income
5340 -- else accumulate the pre-tax income.
5341 IF TRUNC(l_start_date) = TRUNC(l_k_start_date) OR
5342 to_number(to_char(l_start_date, 'DD' )) = 1
5343 THEN
5344 -- No need to accumulate
5345 l_pre_tax_income_tbl(p).cf_amount := l_tmp_interest;
5346 ELSE
5347 -- Accumulate
5348 l_pre_tax_income_tbl(p).cf_amount := nvl( l_pre_tax_income_tbl(p).cf_amount , 0)
5349 + l_tmp_interest;
5350 END IF;
5351 l_pre_tax_income_tbl(p).cf_date := l_se_date;
5352 p := p + 1;
5353 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5354 round( l_bk_yield, 4 ) || ' | ' || l_is_arrears || ' | ' || l_days_per_annum
5355 || ' | ' || l_start_date || ' | ' || l_end_date || ' | ' || l_days
5356 || ' | ' || round( l_tmp_interest, 4 ) || ' | ' || round(l_termination_val, 4 ) );
5357 -- Increment the things
5358 -- Change the start date to first of next month
5359 l_start_date := l_end_date + 1;
5360 ELSE
5361 -- Current month is having the payment ..
5362 -- Handling the period from ( l_start_date , l_cf_inflows(cf_index).cf_date )
5363 l_end_date := l_cf_inflows(cf_index).cf_date;
5364 l_days := get_day_count(
5365 p_days_in_month => l_days_in_month,
5366 p_days_in_year => l_days_in_year,
5367 p_start_date => l_start_date,
5368 p_end_date => l_end_date,
5369 p_arrears => l_is_arrears,
5370 x_return_status => l_return_status);
5371 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5372 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5373 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5374 RAISE OKL_API.G_EXCEPTION_ERROR;
5375 END IF;
5376 -- Based on the day convention, get the days/annum
5377 l_days_per_annum := get_days_per_annum(
5378 p_day_convention => p_day_count_method,
5379 p_start_date => p_start_date,
5380 p_cash_inflow_date => l_start_date,
5381 x_return_status => l_return_status );
5382 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5383 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5384 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5385 RAISE OKL_API.G_EXCEPTION_ERROR;
5386 END IF;
5387 -- Calculation of Interest
5388 l_tmp_interest := l_termination_val * l_days * l_bk_yield / l_days_per_annum;
5389 -- Termination value streams assignments
5390 l_termination_val := l_termination_val + l_tmp_interest;
5391 l_termination_val := l_termination_val - l_cf_inflows(cf_index).cf_amount;
5392 l_termination_val_tbl(t).cf_amount := l_termination_val;
5393 l_termination_val_tbl(t).cf_date := l_cf_inflows(cf_index).cf_date;
5394 -- Pre_tax streams assignments
5395 t := t + 1;
5396 IF l_pre_tax_income_tbl.exists(p)
5397 THEN
5398 l_pre_tax_income_tbl(p).cf_amount := nvl( l_pre_tax_income_tbl(p).cf_amount, 0 ) +
5399 l_tmp_interest;
5400 ELSE
5401 l_pre_tax_income_tbl(p).cf_amount := l_tmp_interest;
5402 END IF;
5403 -- Date for the Pre-Tax Income will be put above
5404 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5405 round( l_bk_yield, 4 ) || ' | ' || l_is_arrears || ' | ' || l_days_per_annum
5406 || ' | ' || l_start_date || ' | ' || l_end_date || ' | ' || l_days
5407 || ' | ' || round( l_tmp_interest, 4 ) || ' | ' || round(l_termination_val, 4 ) );
5408 -- Increment the cf_index
5409 l_start_date := l_cf_inflows(cf_index).cf_date;
5410 IF l_is_arrears = 'Y' AND
5411 TRUNC(l_start_date) <> TRUNC(LAST_DAY( l_start_date)) AND
5412 l_start_date < l_k_end_date
5413 THEN
5414 l_start_date := l_start_date + 1;
5415 END IF;
5416 cf_index := cf_index + 1;
5417 END IF;
5418 -- Check whether we have crossed the Stream Element dates or not???
5419 IF cf_index > l_cf_inflows.LAST
5420 THEN
5421 m := 1;
5422 -- Last Cash Inflow
5423 LOOP
5424 IF LAST_DAY(l_start_date) <> LAST_DAY(l_k_end_date) THEN
5425 l_end_date := LAST_DAY(l_start_date);
5426 ELSE
5427 l_end_date := l_k_end_date;
5428 END IF;
5429 l_days := get_day_count(
5430 p_days_in_month => l_days_in_month,
5431 p_days_in_year => l_days_in_year,
5432 p_start_date => l_start_date,
5433 p_end_date => l_end_date,
5434 p_arrears => 'Y', -- Calculate until the end of the month !
5435 x_return_status => l_return_status);
5436 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5437 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5438 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5439 RAISE OKL_API.G_EXCEPTION_ERROR;
5440 END IF;
5441 /* IF l_is_arrears= 'Y' AND m = 1 AND l_days >= 1
5442 THEN
5443 l_days := l_days - 1;
5444 END IF;*/
5445 -- Get days/annum based on the day count method
5446 l_days_per_annum := get_days_per_annum(
5447 p_day_convention => p_day_count_method,
5448 p_start_date => p_start_date,
5449 p_cash_inflow_date => l_start_date,
5450 x_return_status => l_return_status );
5451 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5452 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5453 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5454 RAISE OKL_API.G_EXCEPTION_ERROR;
5455 END IF;
5456 -- Interest Calculation
5457 l_tmp_interest := l_termination_val * l_days * l_bk_yield / l_days_per_annum;
5458 -- Termination value streams assignment
5459 l_termination_val := l_termination_val + l_tmp_interest;
5460 -- If the current month is the first one .. !
5461 IF m = 1
5462 THEN
5463 -- Accumulate the Pre-Tax Income
5464 l_pre_tax_income_tbl(p).cf_amount := l_pre_tax_income_tbl(p).cf_amount
5465 + l_tmp_interest;
5466 ELSE
5467 -- Pre-Tax is calculated for entire month
5468 -- Hence, no need to accumulate.
5469 l_pre_tax_income_tbl(p).cf_amount := l_tmp_interest;
5470 END IF;
5471 l_pre_tax_income_tbl(p).cf_date := l_end_date;
5472 p := p + 1;
5473
5474 IF TRUNC(l_end_date) = TRUNC(l_k_end_date)
5475 THEN
5476 l_termination_val := l_termination_val - l_residual_amount;
5477 l_term_complete := 'Y';
5478 END IF;
5479 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5480 round( l_bk_yield, 4 ) || ' | ' || 'Y' || ' | ' || l_days_per_annum
5481 || ' | ' || l_start_date || ' | ' || l_end_date || ' | ' || l_days
5482 || ' | ' || round( l_tmp_interest, 4 ) || ' | ' || round(l_termination_val, 4 ) );
5483 -- Termination value streams assignment
5484 l_termination_val_tbl(t).cf_amount := l_termination_val;
5485 l_termination_val_tbl(t).cf_date := l_end_date;
5486 t := t + 1;
5487 EXIT WHEN TRUNC(l_end_date) = TRUNC(l_k_end_date);
5488 -- Increment the Start Date to Next Month First
5489 l_start_date := LAST_DAY(l_start_date) + 1;
5490 -- Increment m
5491 m := m + 1;
5492 END LOOP; -- Loop on m
5493 END IF; -- IF cf_index = l_cf_inflows.LAST
5494 END LOOP; -- Looping through the Inflows
5495 -- Assign the termination value at the end of the period to l_diff and proceed !!
5496 l_diff := l_termination_val;
5497 -- If the current bk_yield is making the termination value as zero at the end of the
5498 -- period, then we have attained the solution, hence return the termination value
5499 -- and pre_tax streams along with the bk_yield !!
5500 IF ROUND(l_diff, 4) = 0
5501 THEN
5502 FOR p in l_pre_tax_income_tbl.FIRST .. l_pre_tax_income_tbl.LAST
5503 LOOP
5504 x_pre_tax_inc_tbl(p).cf_date := trunc(l_pre_tax_income_tbl(p).cf_date);
5505 x_pre_tax_inc_tbl(p).cf_amount := l_pre_tax_income_tbl(p).cf_amount;
5506 x_pre_tax_inc_tbl(p).line_number := p;
5507 END LOOP;
5508 FOR t in l_termination_val_tbl.FIRST .. l_termination_val_tbl.LAST
5509 LOOP
5510 x_termination_tbl(t).cf_date := trunc(l_termination_val_tbl(t).cf_date);
5511 x_termination_tbl(t).cf_amount := l_termination_val_tbl(t).cf_amount;
5512 x_termination_tbl(t).line_number := t;
5513 END LOOP;
5514 x_termination_tbl(x_termination_tbl.LAST).cf_amount := l_residual_amount;
5515 x_bk_yield := l_bk_yield;
5516 -- Achieved the booking yeild, now returning back
5517 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5518 'BOOKING YIELD = ' || round( x_bk_yield, 4));
5519 x_return_status := 'S';
5520 RETURN;
5521 END IF;
5522 -- Using Interpolation approach to estimate/increment the next
5523 -- propsed booking yield .. !
5524 IF n_iterations > 1 AND
5525 SIGN(l_diff) <> SIGN(l_prev_diff)
5526 AND l_crossed_zero = 'N'
5527 THEN
5528 l_crossed_zero := 'Y';
5529 IF (SIGN(l_diff) = 1)
5530 THEN
5531 l_positive_diff := l_diff;
5532 l_negative_diff := l_prev_diff;
5533 l_positive_diff_bk_yeild := l_bk_yield;
5534 l_negative_diff_bk_yeild := l_prev_bk_yeild;
5535 ELSE
5536 l_positive_diff := l_prev_diff;
5537 l_negative_diff := l_diff;
5538 l_positive_diff_bk_yeild := l_prev_bk_yeild;
5539 l_negative_diff_bk_yeild := l_bk_yield;
5540 END IF;
5541 END IF;
5542 IF (SIGN(l_diff) = 1)
5543 THEN
5544 l_positive_diff := l_diff;
5545 l_positive_diff_bk_yeild := l_bk_yield;
5546 ELSE
5547 l_negative_diff := l_diff;
5548 l_negative_diff_bk_yeild := l_bk_yield;
5549 END IF;
5550 IF l_crossed_zero = 'Y'
5551 THEN
5552 IF n_iterations > 1
5553 THEN
5554 l_abs_incr := abs((l_positive_diff_bk_yeild - l_negative_diff_bk_yeild) /
5555 (l_positive_diff - l_negative_diff) * l_diff);
5556 ELSE
5557 l_abs_incr := ABS(l_increment) / 2;
5558 END IF;
5559 ELSE
5560 l_abs_incr := ABS(l_increment);
5561 END IF;
5562 IF n_iterations > 1
5563 THEN
5564 IF SIGN(l_diff) <> l_prev_diff_sign
5565 THEN
5566 IF l_prev_incr_sign = 1
5567 THEN
5568 l_increment := - l_abs_incr;
5569 ELSE
5570 l_increment := l_abs_incr;
5571 END IF;
5572 ELSE
5573 IF l_prev_incr_sign = 1
5574 THEN
5575 l_increment := l_abs_incr;
5576 ELSE
5577 l_increment := - l_abs_incr;
5578 END IF;
5579 END IF;
5580 ELSE
5581 IF SIGN(l_diff) = 1
5582 THEN
5583 l_increment := - l_increment;
5584 ELSE
5585 l_increment := l_increment;
5586 END IF;
5587 END IF;
5588 l_prev_bk_yeild := l_bk_yield;
5589 l_bk_yield := l_bk_yield + l_increment;
5590 l_prev_incr_sign := SIGN(l_increment);
5591 l_prev_diff_sign := SIGN(l_diff);
5592 l_prev_diff := l_diff;
5593 END LOOP; -- Loop on n_iterations
5594 -- Actual logic Ends here
5595 x_return_status := l_return_status;
5596 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
5597 x_msg_data => x_msg_data);
5598 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
5599 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
5600 EXCEPTION
5601 WHEN OKL_API.G_EXCEPTION_ERROR THEN
5602 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5603 p_api_name => l_api_name,
5604 p_pkg_name => G_PKG_NAME,
5605 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
5606 x_msg_count => x_msg_count,
5607 x_msg_data => x_msg_data,
5608 p_api_type => g_api_type);
5609 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
5610 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5611 p_api_name => l_api_name,
5612 p_pkg_name => G_PKG_NAME,
5613 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
5614 x_msg_count => x_msg_count,
5615 x_msg_data => x_msg_data,
5616 p_api_type => g_api_type);
5617 WHEN OTHERS THEN
5618 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
5619 p_api_name => l_api_name,
5620 p_pkg_name => G_PKG_NAME,
5621 p_exc_name => 'OTHERS',
5622 x_msg_count => x_msg_count,
5623 x_msg_data => x_msg_data,
5624 p_api_type => g_api_type);
5625 END compute_bk_yield;
5626
5627 PROCEDURE get_qq_rc_cash_flows(
5628 p_api_version IN NUMBER,
5629 p_init_msg_list IN VARCHAR2,
5630 x_return_status OUT NOCOPY VARCHAR2,
5631 x_msg_count OUT NOCOPY NUMBER,
5632 x_msg_data OUT NOCOPY VARCHAR2,
5633 p_qq_hdr_rec IN so_hdr_rec_type,
5634 x_days_in_month OUT NOCOPY VARCHAR2,
5635 x_days_in_year OUT NOCOPY VARCHAR2,
5636 x_item_cat_cf_tbl OUT NOCOPY item_cat_cf_tbl_type)
5637 IS
5638 l_api_version CONSTANT NUMBER DEFAULT 1.0;
5639 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_rc_cash_flows';
5640 l_return_status VARCHAR2(1);
5641 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
5642 || G_PKG_NAME || '.' || UPPER(l_api_name);
5643 l_debug_enabled VARCHAR2(10);
5644 is_debug_procedure_on BOOLEAN;
5645 is_debug_statement_on BOOLEAN;
5646 -- Cursor Declarations
5647 CURSOR item_cat_csr( p_qq_id NUMBER )
5648 IS
5649 SELECT id
5650 ,item_category_id
5651 ,value
5652 ,basis
5653 ,nvl(nvl(end_of_term_value, end_of_term_value_default), 0) end_of_term_amount
5654 ,lease_rate_factor
5655 FROM OKL_QUICK_QUOTE_LINES_B qql
5656 WHERE qql.quick_quote_id = p_qq_id
5657 AND TYPE = G_ITEMCATEGORY_TYPE; -- Item Category Type
5658
5659 CURSOR get_cat_name(p_category_id IN NUMBER) IS
5660 SELECT category_concat_segs name,
5661 description
5662 FROM mtl_categories_v
5663 WHERE category_id = p_category_id;
5664 cat_rec get_cat_name%ROWTYPE;
5665
5666 -- Cursor to get the Financial Adjustments defined @ QQ Level
5667 CURSOR fin_adj_csr( p_qq_id NUMBER, p_tot_item_cost IN NUMBER )
5668 IS
5669 SELECT TYPE type
5670 ,SUM(CASE basis
5671 WHEN 'FIXED' THEN value
5672 WHEN 'ASSET_COST' THEN value * p_tot_item_cost * .01
5673 END ) AS fin_value
5674 FROM OKL_QUICK_QUOTE_LINES_B qql
5675 WHERE qql.quick_quote_id = p_qq_id
5676 AND TYPE IN ( G_DOWNPAYMENT_TYPE, -- Down Payment Type
5677 G_TRADEIN_TYPE, -- Trade in Type
5678 G_SUBSIDY_TYPE ) -- Subsidy Type
5679 GROUP BY TYPE
5680 ORDER BY TYPE;
5681
5682 -- Cursor to fetch the End of Term Option Type
5683 CURSOR get_eot_type( p_qq_id NUMBER )
5684 IS
5685 SELECT qq.id
5686 ,qq.reference_number
5687 ,eot.end_of_term_name
5688 ,eot.eot_type_code eot_type_code
5689 ,eot.end_of_term_id end_of_term_id
5690 ,eotversion.end_of_term_ver_id
5691 FROM OKL_QUICK_QUOTES_B qq,
5692 okl_fe_eo_term_vers eotversion,
5693 okl_fe_eo_terms_all_b eot
5694 WHERE qq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
5695 AND eot.end_of_term_id = eotversion.end_of_term_id
5696 AND qq.id = p_qq_id;
5697 -- Local Variables
5698 l_lrs_details lrs_details_rec_type;
5699 l_lrs_factor lrs_factor_rec_type;
5700 l_lrs_levels lrs_levels_tbl_type;
5701 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
5702 l_adj_factor NUMBER;
5703 l_got_adj_factor BOOLEAN;
5704 l_eot_percentage NUMBER;
5705 l_asset_fin_amt NUMBER;
5706 l_months_per_period NUMBER;
5707 l_months_after NUMBER;
5708 l_item_cat_cf_tbl item_cat_cf_tbl_type;
5709 cf_index NUMBER; -- Using as an index for Cash flow levels
5710 i NUMBER; -- Using as an index for Item Categories
5711 l_periods NUMBER;
5712 l_sum_fin_amt NUMBER; -- Sum of Financed Amount
5713 l_tot_down_payment NUMBER;
5714 l_tot_tradein NUMBER;
5715 l_tot_subsidy NUMBER;
5716 l_eot_type_code VARCHAR2(30);
5717 BEGIN
5718 l_return_status := OKL_API.G_RET_STS_SUCCESS;
5719 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
5720 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
5721 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
5722 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
5723 -- check for logging on STATEMENT level
5724 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
5725 l_return_status := OKL_API.START_ACTIVITY(
5726 p_api_name => l_api_name,
5727 p_pkg_name => G_PKG_NAME,
5728 p_init_msg_list => p_init_msg_list,
5729 l_api_version => l_api_version,
5730 p_api_version => p_api_version,
5731 p_api_type => g_api_type,
5732 x_return_status => x_return_status);
5733 --Check if activity started successfully
5734 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5735 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5736 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5737 RAISE OKL_API.G_EXCEPTION_ERROR;
5738 END IF;
5739 -- Know the type of the EOT and then proceed with the values directly or calculate the amount
5740 FOR t_rec IN get_eot_type(p_qq_id => p_qq_hdr_rec.id)
5741 LOOP
5742 l_eot_type_code := t_rec.eot_type_code;
5743 END LOOP;
5744 -- First of all, Calculate the Total OEC for all the Assets.
5745 l_sum_fin_amt := 0;
5746 i := 1;
5747 FOR t_rec IN item_cat_csr( p_qq_id => p_qq_hdr_rec.id )
5748 LOOP
5749 l_sum_fin_amt := l_sum_fin_amt + t_rec.value;
5750 -- Populate the Item Cat PL/SQL Table for calculation of the Proportionated Financial Adjustments
5751 l_item_cat_cf_tbl(i).line_id := t_rec.id;
5752 l_item_cat_cf_tbl(i).item_category_id := t_rec.item_category_id;
5753 -- Returning the Asset COST in the Financed Amount COLUMN, remember we are not returning C-S-D-T here !!
5754 l_item_cat_cf_tbl(i).financed_amount := t_rec.value; -- Populating the Cash Flow Record
5755 -- Increment i
5756 i := i + 1;
5757 END LOOP;
5758 -- Fetch the Financial adjustments, Down Payment/Tradein/Subsidy defined @ QQ level ..
5759 FOR t_rec IN fin_adj_csr( p_qq_id => p_qq_hdr_rec.id
5760 ,p_tot_item_cost => l_sum_fin_amt )
5761 LOOP
5762 IF t_rec.type = G_DOWNPAYMENT_TYPE
5763 THEN
5764 l_tot_down_payment := t_rec.fin_value;
5765 ELSIF t_rec.type = G_TRADEIN_TYPE
5766 THEN
5767 l_tot_tradein := t_rec.fin_value;
5768 ELSIF t_rec.type = G_SUBSIDY_TYPE
5769 THEN
5770 l_tot_subsidy := t_rec.fin_value;
5771 END IF;
5772 END LOOP;
5773 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5774 'TOTALS: p_qq_id | p_tot_item_cost | Tot Down Payment | Trade in | Subsidy ');
5775 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5776 p_qq_hdr_rec.id || ' | ' || round(l_sum_fin_amt, 4) || ' | ' ||
5777 round( l_tot_down_payment, 4) || ' | ' || round( l_tot_tradein, 4) || ' | ' || round( l_tot_subsidy, 4) );
5778 -- Code for distributing the fin. adj. @ QQ level to individual item categories !
5779 -- Approach is to proportionate the financial adjustments entered @ Header level
5780 -- based on the item category cost
5781 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5782 'PROPORTIONATED AMOUNTS: Item ID | Financed Amount | Down Payment | Trade in | Subsidy ');
5783 FOR t IN l_item_cat_cf_tbl.FIRST .. l_item_cat_cf_tbl.LAST
5784 LOOP
5785 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);
5786 l_item_cat_cf_tbl(t).subsidy := nvl(l_tot_subsidy * l_item_cat_cf_tbl(t).financed_amount/l_sum_fin_amt, 0);
5787 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);
5788 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5789 l_item_cat_cf_tbl(t).line_id || ' | ' || round(l_item_cat_cf_tbl(t).financed_amount, 4) || ' | ' ||
5790 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) );
5791 END LOOP;
5792 -- 1/ Check for the structured_pricing column in p_qq_hdr_rec.structured_pricing
5793 -- IF 'N' then fetch the lease rate factor levels for each item category
5794 IF p_qq_hdr_rec.structured_pricing IS NULL OR
5795 p_qq_hdr_rec.structured_pricing = 'N'
5796 THEN
5797 l_got_adj_factor := FALSE;
5798 i := 1;
5799 FOR t_rec IN item_cat_csr( p_qq_id => p_qq_hdr_rec.id )
5800 LOOP
5801 -- Calculate EOT %age. FORMULA: EOT %age = EOT of the Asset / Assets OEC * 100
5802 IF l_eot_type_code = 'AMOUNT' OR l_eot_type_code = 'RESIDUAL_AMOUNT'
5803 THEN
5804 l_eot_percentage := (t_rec.end_of_term_amount / t_rec.VALUE ) * 100;
5805 l_item_cat_cf_tbl(i).eot_amount := t_rec.end_of_term_amount;
5806 ELSE
5807 -- End of Term Amount is representing actually the percentage
5808 l_eot_percentage := t_rec.end_of_term_amount;
5809 l_item_cat_cf_tbl(i).eot_amount := (t_rec.end_of_term_amount * t_rec.VALUE ) / 100;
5810 END IF;
5811 -- Loop through all the assets and fetch the corresponding LRF and payment amounts !
5812 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5813 'Extracting the information from Lease Rate Set ' );
5814 l_lrs_levels.DELETE;
5815 -- Extract the data from the Lease Rate Set !
5816 get_lease_rate_factors(
5817 p_api_version => p_api_version,
5818 p_init_msg_list => p_init_msg_list,
5819 x_return_status => l_return_status,
5820 x_msg_count => x_msg_count,
5821 x_msg_data => x_msg_data,
5822 p_lrt_id => p_qq_hdr_rec.rate_card_id,
5823 p_start_date => p_qq_hdr_rec.expected_start_date,
5824 p_term_in_months => p_qq_hdr_rec.term,
5825 p_eot_percentage => l_eot_percentage,
5826 x_lrs_details => l_lrs_details,
5827 x_lrs_factor => l_lrs_factor,
5828 x_lrs_levels => l_lrs_levels);
5829 IF l_return_status <> OKL_API.G_RET_STS_SUCCESS
5830 THEN
5831 OPEN get_cat_name(p_category_id => t_rec.item_category_id);
5832 FETCH get_cat_name INTO cat_rec;
5833 CLOSE get_cat_name;
5834 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5835 'Couldnot found the Lease Rate Factor levels for Item Category ' || cat_rec.name );
5836 -- Show the message and then return back throwing an error!
5837 OKL_API.set_message(
5838 p_app_name => G_APP_NAME,
5839 p_msg_name => 'OKL_LP_NO_LRS_LEVELS_FOUND',
5840 p_token1 => 'ITEMCAT',
5841 p_token1_value => cat_rec.name,
5842 p_token2 => 'ITEMTERM',
5843 p_token2_value => p_qq_hdr_rec.term,
5844 p_token3 => 'ITEMEOTPERCENT',
5845 p_token3_value => ROUND(l_eot_percentage,4) );
5846 RAISE OKL_API.G_EXCEPTION_ERROR;
5847 END IF;
5848 -- Apply the adjustment matrix if needed!
5849 IF l_lrs_details.adj_mat_version_id IS NOT NULL AND
5850 l_got_adj_factor = FALSE
5851 THEN
5852 l_ac_rec_type.src_id := l_lrs_details.adj_mat_version_id; -- Pricing adjustment matrix ID
5853 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
5854 l_ac_rec_type.target_id := p_qq_hdr_rec.ID ; -- Quote ID
5855 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
5856 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
5857 l_ac_rec_type.target_eff_from := p_qq_hdr_rec.expected_start_date; -- Quote effective From
5858 l_ac_rec_type.term := p_qq_hdr_rec.term; -- Remaining four will be from teh business object like QQ / LQ
5859 l_ac_rec_type.territory := p_qq_hdr_rec.sales_territory_id;
5860 l_ac_rec_type.deal_size := l_sum_fin_amt; -- Not sure how to pass this value
5861 l_ac_rec_type.customer_credit_class := NULL; -- Not sure how to pass this even ..
5862 -- Fetching the deal_size ..
5863 -- Calling the API to get the adjustment factor ..
5864 okl_ec_evaluate_pvt. get_adjustment_factor(
5865 p_api_version => p_api_version,
5866 p_init_msg_list => p_init_msg_list,
5867 x_return_status => x_return_status,
5868 x_msg_count => x_msg_count,
5869 x_msg_data => x_msg_data,
5870 p_okl_ac_rec => l_ac_rec_type,
5871 x_adjustment_factor => l_adj_factor );
5872 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5873 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5874 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5875 RAISE OKL_API.G_EXCEPTION_ERROR;
5876 END IF;
5877 END IF;
5878 IF l_got_adj_factor = FALSE
5879 THEN
5880 l_got_adj_factor := TRUE;
5881 l_adj_factor := nvl( l_adj_factor, 0 );
5882 END IF;
5883 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Adjustment Factor ' || l_adj_factor );
5884 -- Calculating the Asset Level Financed Amount. i.e C- nvl(S+D+T, 0)
5885 l_asset_fin_amt := l_item_cat_cf_tbl(i).financed_amount - nvl( l_item_cat_cf_tbl(i).subsidy +
5886 l_item_cat_cf_tbl(i).down_payment + l_item_cat_cf_tbl(i).trade_in, 0);
5887 -- Store the Item Category details in the PL/SQL table to return back ..
5888 l_item_cat_cf_tbl(i).cash_flow_rec.due_arrears_yn := l_lrs_details.arrears_yn;
5889 l_item_cat_cf_tbl(i).cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
5890 -- Get the Months factor!
5891 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
5892 p_frequency => l_lrs_details.frq_code,
5893 x_return_status => l_return_status);
5894 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5895 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5896 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5897 RAISE OKL_API.G_EXCEPTION_ERROR;
5898 END IF;
5899 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Months/Period ' || l_months_per_period );
5900 -- Populating the Cash Flow Levels
5901 l_months_after := 0;
5902 cf_index := 1;
5903 FOR t in l_lrs_levels.FIRST .. l_lrs_levels.LAST
5904 LOOP
5905 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).fqy_code := l_lrs_details.frq_code;
5906 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).number_of_periods := l_lrs_levels(t).periods;
5907 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;
5908 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).is_stub := 'N';
5909 l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).rate := l_lrs_levels(t).lease_rate_factor;
5910 -- Need to populate the start date per line .. !!
5911 okl_stream_generator_pvt.add_months_new(
5912 p_start_date => p_qq_hdr_rec.expected_start_date,
5913 p_months_after => l_months_after,
5914 x_date => l_item_cat_cf_tbl(i).cash_flow_level_tbl(cf_index).start_date,
5915 x_return_status => l_return_status);
5916 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5917 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5918 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5919 RAISE OKL_API.G_EXCEPTION_ERROR;
5920 END IF;
5921 -- Add to the l_months_after
5922 l_months_after := l_months_after + ( l_lrs_levels(t).periods * l_months_per_period );
5923 -- Increment the index
5924 cf_index := cf_index + 1;
5925 END LOOP;
5926 -- Increment the item category index
5927 i := i + 1;
5928 END LOOP;
5929 ELSE
5930 -- Note:
5931 -- When user hasn't picked the LRS for Rate Card pricing and wishes
5932 -- to enter the LRF .. ie. Structured Pricing, Suresh PB has confirmed
5933 -- that irrespective of the line level pricing has been checked or not
5934 -- sales team will populate the LRF in OKL_QUICK_QUOTE_LINES_B.
5935 -- Hence, pricing can just fetch the LRF in OKL_QUICK_QUOTE_LINES_B and
5936 -- then build the cash flows from that ..
5937 -- Get the Months factor!
5938 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
5939 p_frequency => p_qq_hdr_rec.target_frequency,
5940 x_return_status => l_return_status);
5941 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
5942 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5943 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
5944 RAISE OKL_API.G_EXCEPTION_ERROR;
5945 END IF;
5946 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Months/Period ' || l_months_per_period );
5947 l_periods := p_qq_hdr_rec.term / l_months_per_period;
5948 -- Need to validate that the term / ( frequency factor ) should be a whole number !
5949 IF l_periods <> TRUNC( l_periods )
5950 THEN
5951 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Periods has to be a whole number ');
5952 OKL_API.set_message( G_APP_NAME, OKL_API.G_INVALID_VALUE, OKL_API.G_COL_NAME_TOKEN, 'l_periods');
5953 RAISE OKL_API.G_EXCEPTION_ERROR;
5954 END IF;
5955 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5956 'Line ID | OEC | EOT Amount | Arrears YN | Freq | Periods | LRF | Amt | Start Date ' );
5957 i := 1;
5958 -- Loop through all item categories and build the corresponding cash flows ..
5959 FOR t_rec IN item_cat_csr( p_qq_id => p_qq_hdr_rec.id )
5960 LOOP
5961 -- Calculate the EOT Amount. FORMULA: EOT% = EOT % * Asset OEC / 100;
5962 IF l_eot_type_code = 'AMOUNT' OR l_eot_type_code = 'RESIDUAL_AMOUNT'
5963 THEN
5964 l_item_cat_cf_tbl(i).eot_amount := t_rec.end_of_term_amount;
5965 ELSE
5966 l_item_cat_cf_tbl(i).eot_amount := t_rec.value * t_rec.end_of_term_amount / 100;
5967 END IF;
5968 -- Calculate the Asset level Financed Amount: FORMULA: Asset Fin. Amt = C - NVL(S+D+T, 0)
5969 l_asset_fin_amt := l_item_cat_cf_tbl(i).financed_amount - nvl( l_item_cat_cf_tbl(i).subsidy +
5970 l_item_cat_cf_tbl(i).down_payment + l_item_cat_cf_tbl(i).trade_in, 0);
5971 -- Populating the Cash Flow Record
5972 l_item_cat_cf_tbl(i).cash_flow_rec.due_arrears_yn := p_qq_hdr_rec.target_arrears;
5973 l_item_cat_cf_tbl(i).cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
5974 -- Populating the Cash Flow Levels
5975 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).fqy_code := p_qq_hdr_rec.target_frequency;
5976 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).number_of_periods := l_periods;
5977 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).amount := t_rec.lease_rate_factor * l_asset_fin_amt;
5978 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).is_stub := 'N';
5979 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).start_date := p_qq_hdr_rec.expected_start_date;
5980 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).rate := t_rec.lease_rate_factor;
5981 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
5982 t_rec.ID || ' | ' || round(l_item_cat_cf_tbl(i).financed_amount,2) || ' | ' || round(t_rec.end_of_term_amount, 2) || ' | ' ||
5983 p_qq_hdr_rec.target_arrears || ' | ' || p_qq_hdr_rec.target_frequency || ' | ' || l_periods || ' | ' ||
5984 t_rec.lease_rate_factor || ' | ' || round(l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).amount,2) || ' | ' ||
5985 l_item_cat_cf_tbl(i).cash_flow_level_tbl(1).start_date );
5986 -- Increment the item category index
5987 i := i + 1;
5988 END LOOP; -- Loop on item_cat_csr
5989 END IF;
5990 -- Fetch the day convention from the Stream Generation Template ...
5991 get_qq_sgt_day_convention(
5992 p_api_version => p_api_version,
5993 p_init_msg_list => p_init_msg_list,
5994 x_return_status => l_return_status,
5995 x_msg_count => x_msg_count,
5996 x_msg_data => x_msg_data,
5997 p_qq_id => p_qq_hdr_rec.id,
5998 x_days_in_month => x_days_in_month,
5999 x_days_in_year => x_days_in_year);
6000 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6001 'After get_qq_sgt_day_convention ' || l_return_status );
6002 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6003 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6004 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6005 RAISE OKL_API.G_EXCEPTION_ERROR;
6006 END IF;
6007 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6008 'SGT Day convention: ' || x_days_in_month || ' / ' || x_days_in_year);
6009 -- Return the values ...
6010 x_item_cat_cf_tbl := l_item_cat_cf_tbl;
6011 x_return_status := l_return_status;
6012 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
6013 x_msg_data => x_msg_data);
6014 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6015 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
6016 EXCEPTION
6017 WHEN OKL_API.G_EXCEPTION_ERROR THEN
6018 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6019 p_api_name => l_api_name,
6020 p_pkg_name => G_PKG_NAME,
6021 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
6022 x_msg_count => x_msg_count,
6023 x_msg_data => x_msg_data,
6024 p_api_type => g_api_type);
6025 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
6026 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6027 p_api_name => l_api_name,
6028 p_pkg_name => G_PKG_NAME,
6029 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
6030 x_msg_count => x_msg_count,
6031 x_msg_data => x_msg_data,
6032 p_api_type => g_api_type);
6033 WHEN OTHERS THEN
6034 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6035 p_api_name => l_api_name,
6036 p_pkg_name => G_PKG_NAME,
6037 p_exc_name => 'OTHERS',
6038 x_msg_count => x_msg_count,
6039 x_msg_data => x_msg_data,
6040 p_api_type => g_api_type);
6041 END get_qq_rc_cash_flows;
6042
6043
6044 -- This API is responsible to create cash flow and cash flow details records when
6045 -- the pricing type is Target Rate or
6046 -- User has picked the rate from SRT/LRS
6047 -- User has picked the structured pricing and mentiond the rate, periods, amount ..etc
6048 --
6049 -- Returns the populated cash flow record and cash flow levels table
6050 PROCEDURE get_qq_cash_flows(
6051 p_api_version IN NUMBER,
6052 p_init_msg_list IN VARCHAR2,
6053 x_return_status OUT NOCOPY VARCHAR2,
6054 x_msg_count OUT NOCOPY NUMBER,
6055 x_msg_data OUT NOCOPY VARCHAR2,
6056 p_qq_hdr_rec IN so_hdr_rec_type,
6057 p_eot_percentage IN NUMBER,
6058 p_oec IN NUMBER,
6059 x_days_in_month OUT NOCOPY VARCHAR2,
6060 x_days_in_year OUT NOCOPY VARCHAR2,
6061 x_cash_flow_rec OUT NOCOPY so_cash_flows_rec_type,
6062 x_cash_flow_det_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
6063 IS
6064 -- Local Variables
6065 l_api_version CONSTANT NUMBER DEFAULT 1.0;
6066 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_qq_cash_flows (QQ)';
6067 l_return_status VARCHAR2(1);
6068
6069 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
6070 || G_PKG_NAME || '.' || UPPER(l_api_name);
6071 l_debug_enabled VARCHAR2(10);
6072 is_debug_procedure_on BOOLEAN;
6073 is_debug_statement_on BOOLEAN;
6074
6075 -- Cursor Declarations
6076 CURSOR get_deal_size_csr( p_qq_id NUMBER )
6077 IS
6078 SELECT sum(VALUE) deal_size
6079 FROM OKL_QUICK_QUOTE_LINES_B qql
6080 WHERE qql.quick_quote_id = p_qq_id
6081 AND qql.TYPE = G_ITEMCATEGORY_TYPE; -- Item Category Type
6082 -- Local Variables declaration
6083 l_cash_flow_rec so_cash_flows_rec_type;
6084 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
6085 i NUMBER; -- Index for looping over the Cash Flow Details
6086 l_months_per_period NUMBER;
6087 l_months_after NUMBER;
6088 -- Lease Rate Factor Variables
6089 l_lrs_details lrs_details_rec_type;
6090 l_lrs_factor lrs_factor_rec_type;
6091 l_lrs_levels lrs_levels_tbl_type;
6092 -- Standard Rate Template Variables
6093 l_srt_details srt_details_rec_type;
6094 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
6095 l_adj_factor NUMBER;
6096 l_deal_size NUMBER;
6097 l_months_factor NUMBER;
6098 BEGIN
6099 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6100 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
6101 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
6102 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6103 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
6104 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
6105 l_return_status := OKL_API.START_ACTIVITY(
6106 p_api_name => l_api_name,
6107 p_pkg_name => G_PKG_NAME,
6108 p_init_msg_list => p_init_msg_list,
6109 l_api_version => l_api_version,
6110 p_api_version => p_api_version,
6111 p_api_type => g_api_type,
6112 x_return_status => x_return_status);
6113 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6114 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6115 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6116 RAISE OKL_API.G_EXCEPTION_ERROR;
6117 END IF;
6118 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6119 'Pricing Method is ' || p_qq_hdr_rec.pricing_method );
6120 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6121 ': p_qq_hdr_rec.rate_template_id=' || p_qq_hdr_rec.rate_template_id );
6122 i := 1;
6123 l_months_after := 0;
6124 l_adj_factor := 0;
6125
6126 IF p_qq_hdr_rec.rate_template_id IS NOT NULL
6127 THEN
6128 -- Extract details from the Standard Rate Template
6129 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6130 'Fetching the Details from the Standard Rate Template ' );
6131 get_standard_rates(
6132 p_api_version => p_api_version,
6133 p_init_msg_list => p_init_msg_list,
6134 x_return_status => l_return_status,
6135 x_msg_count => x_msg_count,
6136 x_msg_data => x_msg_data,
6137 p_srt_id => p_qq_hdr_rec.rate_template_id,
6138 p_start_date => p_qq_hdr_rec.expected_start_date,
6139 x_srt_details => l_srt_details);
6140 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6141 ': l_return_status ' || l_return_status );
6142 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6143 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6144 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6145 RAISE OKL_API.G_EXCEPTION_ERROR;
6146 END IF;
6147 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6148 'Using SRT ' || l_srt_details.template_name || ' Version ' || l_srt_details.version_number
6149 || ' Status ' || l_srt_details.sts_code || ' Pricing Engine ' || l_srt_details.pricing_engine_code
6150 || ' Rate Type ' || l_srt_details.rate_type_code || ' Day Convention ' || l_srt_details.day_convention_code );
6151 IF l_srt_details.adj_mat_version_id IS NOT NULL
6152 THEN
6153 -- Fetch the Deal Size
6154 OPEN get_deal_size_csr( p_qq_id => p_qq_hdr_rec.ID );
6155 FETCH get_deal_size_csr INTO l_deal_size;
6156 CLOSE get_deal_size_csr;
6157 -- Populate the Adjustment mat. rec.
6158 l_ac_rec_type.src_id := l_srt_details.adj_mat_version_id; -- Pricing adjustment matrix ID
6159 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
6160 l_ac_rec_type.target_id := p_qq_hdr_rec.ID ; -- Quote ID
6161 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
6162 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
6163 l_ac_rec_type.target_eff_from := p_qq_hdr_rec.expected_start_date; -- Quote effective From
6164 l_ac_rec_type.term := p_qq_hdr_rec.term; -- Remaining four will be from teh business object like QQ / LQ
6165 l_ac_rec_type.territory := p_qq_hdr_rec.sales_territory_id;
6166 l_ac_rec_type.deal_size := l_deal_size;
6167 l_ac_rec_type.customer_credit_class := NULL; -- Not sure how to pass this even ..
6168 -- Calling the API to get the adjustment factor ..
6169 okl_ec_evaluate_pvt. get_adjustment_factor(
6170 p_api_version => p_api_version,
6171 p_init_msg_list => p_init_msg_list,
6172 x_return_status => x_return_status,
6173 x_msg_count => x_msg_count,
6174 x_msg_data => x_msg_data,
6175 p_okl_ac_rec => l_ac_rec_type,
6176 x_adjustment_factor => l_adj_factor );
6177 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6178 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6179 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6180 RAISE OKL_API.G_EXCEPTION_ERROR;
6181 END IF;
6182 END IF;
6183 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6184 'Adjustment Factor ' || l_adj_factor );
6185 -- Populating the Cash flows
6186 l_cash_flow_rec.due_arrears_yn := p_qq_hdr_rec.target_arrears;
6187 l_cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
6188 -- Populating the Cash flow levels
6189 l_cash_flow_det_tbl(1).fqy_code := l_srt_details.frequency_code;
6190 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
6191 IF nvl( l_srt_details.min_adj_rate,l_cash_flow_det_tbl(1).rate) > l_cash_flow_det_tbl(1).rate
6192 THEN
6193 l_cash_flow_det_tbl(1).rate := l_srt_details.min_adj_rate;
6194 ELSIF nvl( l_srt_details.max_adj_rate,l_cash_flow_det_tbl(1).rate) < l_cash_flow_det_tbl(1).rate
6195 THEN
6196 l_cash_flow_det_tbl(1).rate := l_srt_details.max_adj_rate;
6197 END IF;
6198 l_cash_flow_det_tbl(1).is_stub := 'N';
6199 l_cash_flow_det_tbl(1).start_date := p_qq_hdr_rec.expected_start_date;
6200 l_cash_flow_det_tbl(1).number_of_periods := p_qq_hdr_rec.target_periods;
6201 l_cash_flow_det_tbl(1).amount := p_qq_hdr_rec.target_amount;
6202 x_days_in_year := l_srt_details.day_convention_code;
6203 IF x_days_in_year = '360'
6204 THEN
6205 x_days_in_month := '30';
6206 ELSIF x_days_in_year = '365' OR x_days_in_year = 'ACTUAL'
6207 THEN
6208 x_days_in_month := 'ACTUAL';
6209 END IF;
6210 ELSIF p_qq_hdr_rec.pricing_method = 'TR'
6211 THEN
6212 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6213 'Building the Cash flows n Inflows ' || p_qq_hdr_rec.pricing_method );
6214 -- Populating the Cash flows
6215 l_cash_flow_rec.due_arrears_yn := p_qq_hdr_rec.target_arrears;
6216 l_cash_flow_rec.start_date := p_qq_hdr_rec.expected_start_date;
6217 -- Populating the Cash flow levels
6218 l_cash_flow_det_tbl(1).fqy_code := p_qq_hdr_rec.target_frequency;
6219 l_cash_flow_det_tbl(1).rate := p_qq_hdr_rec.target_rate; -- Rate is being stored as Percentage
6220 l_cash_flow_det_tbl(1).is_stub := 'N';
6221 l_cash_flow_det_tbl(1).start_date := p_qq_hdr_rec.expected_start_date;
6222 l_months_factor := okl_stream_generator_pvt.get_months_factor(
6223 p_frequency => p_qq_hdr_rec.target_frequency,
6224 x_return_status => x_return_status);
6225 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6226 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6227 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6228 RAISE OKL_API.G_EXCEPTION_ERROR;
6229 END IF;
6230 l_cash_flow_det_tbl(1).number_of_periods := p_qq_hdr_rec.term / l_months_factor;
6231 IF l_cash_flow_det_tbl(1).number_of_periods <> TRUNC( l_cash_flow_det_tbl(1).number_of_periods )
6232 THEN
6233 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'Periods has to be a whole number ');
6234 OKL_API.set_message( G_APP_NAME, OKL_API.G_INVALID_VALUE, OKL_API.G_COL_NAME_TOKEN, 'Target Frequency');
6235 RAISE OKL_API.G_EXCEPTION_ERROR;
6236 END IF;
6237 -- Fetch the day convention from the Stream Generation Template ...
6238 get_qq_sgt_day_convention(
6239 p_api_version => p_api_version,
6240 p_init_msg_list => p_init_msg_list,
6241 x_return_status => l_return_status,
6242 x_msg_count => x_msg_count,
6243 x_msg_data => x_msg_data,
6244 p_qq_id => p_qq_hdr_rec.id,
6245 x_days_in_month => x_days_in_month,
6246 x_days_in_year => x_days_in_year);
6247 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6248 'After get_qq_sgt_day_convention ' || 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 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6255 'SGT Day convention: ' || x_days_in_month || ' / ' || x_days_in_year);
6256 ELSIF p_qq_hdr_rec.structured_pricing <> 'N'
6257 THEN
6258 -- Structured Pricing API
6259 -- Get the Pricing Details
6260 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6261 'Fetching from the Cash Flows ');
6262 get_qq_cash_flows(
6263 p_api_version => p_api_version,
6264 p_init_msg_list => p_init_msg_list,
6265 x_return_status => l_return_status,
6266 x_msg_count => x_msg_count,
6267 x_msg_data => x_msg_data,
6268 p_cf_source_type => G_CF_SOURCE_QQ,
6269 p_qq_id => p_qq_hdr_rec.id,
6270 x_days_in_month => x_days_in_month,
6271 x_days_in_year => x_days_in_year,
6272 x_cash_flow_rec => l_cash_flow_rec, -- Cash Flow Record
6273 x_cash_flow_det_tbl => l_cash_flow_det_tbl); -- Cash Flow Details Table
6274 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6275 'After get_qq_cash_flows ' || l_return_status );
6276 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6277 'l_cash_flow_det_tbl.COUNT ' || l_cash_flow_det_tbl.COUNT);
6278 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6279 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6280 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6281 RAISE OKL_API.G_EXCEPTION_ERROR;
6282 END IF;
6283 END IF; -- IF p_qq_hdr_rec.pricing_method
6284 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6285 ': Built the Cash flows and Levels ' );
6286 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6287 'Arrears = ' || l_cash_flow_rec.due_arrears_yn
6288 || 'Start Date=' || l_cash_flow_rec.start_date );
6289 IF l_cash_flow_det_tbl.COUNT > 0
6290 THEN
6291 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6292 ': Frequency | Rate | Stub Amount | Stub Days | Periods | Amount | Start Date ' );
6293 FOR t IN l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
6294 LOOP
6295 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6296 l_cash_flow_det_tbl(t).fqy_code || '|' || l_cash_flow_det_tbl(t).rate
6297 || '|' || l_cash_flow_det_tbl(t).stub_days || '|' || l_cash_flow_det_tbl(t).stub_amount
6298 || '|' || l_cash_flow_det_tbl(t).number_of_periods || '|' || l_cash_flow_det_tbl(t).amount
6299 || '|' || l_cash_flow_det_tbl(t).START_DATE || '|' || l_cash_flow_det_tbl(t).is_stub );
6300 END LOOP;
6301 END IF;
6302 -- Setting up the return variables
6303 x_cash_flow_rec := l_cash_flow_rec;
6304 x_cash_flow_det_tbl := l_cash_flow_det_tbl;
6305 x_return_status := l_return_status;
6306 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
6307 x_msg_data => x_msg_data);
6308 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6309 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
6310 EXCEPTION
6311 WHEN OKL_API.G_EXCEPTION_ERROR THEN
6312 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6313 p_api_name => l_api_name,
6314 p_pkg_name => G_PKG_NAME,
6315 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
6316 x_msg_count => x_msg_count,
6317 x_msg_data => x_msg_data,
6318 p_api_type => g_api_type);
6319 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
6320 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6321 p_api_name => l_api_name,
6322 p_pkg_name => G_PKG_NAME,
6323 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
6324 x_msg_count => x_msg_count,
6325 x_msg_data => x_msg_data,
6326 p_api_type => g_api_type);
6327 WHEN OTHERS THEN
6328 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6329 p_api_name => l_api_name,
6330 p_pkg_name => G_PKG_NAME,
6331 p_exc_name => 'OTHERS',
6332 x_msg_count => x_msg_count,
6333 x_msg_data => x_msg_data,
6334 p_api_type => g_api_type);
6335 END get_qq_cash_flows;
6336
6337 -- This API is responsible to create cash flow and cash flow details records when
6338 -- User has picked the rate from SRT for an Asset / Lease Quote
6339 -- User has picked the structured pricing and mentiond the rate, periods, amount ..etc
6340 -- either at the Lease Quote or Asset Level !
6341 -- Returns the populated cash flow record and cash flow levels table
6342 PROCEDURE get_lq_cash_flows(
6343 p_api_version IN NUMBER,
6344 p_init_msg_list IN VARCHAR2,
6345 x_return_status OUT NOCOPY VARCHAR2,
6346 x_msg_count OUT NOCOPY NUMBER,
6347 x_msg_data OUT NOCOPY VARCHAR2,
6348 p_id IN NUMBER,
6349 p_lq_srt_id IN NUMBER,
6350 p_cf_source IN VARCHAR2,
6351 p_adj_mat_cat_rec IN adj_mat_cat_rec,
6352 p_pricing_method IN VARCHAR2,
6353 x_days_in_month OUT NOCOPY VARCHAR2,
6354 x_days_in_year OUT NOCOPY VARCHAR2,
6355 x_cash_flow_rec OUT NOCOPY so_cash_flows_rec_type,
6356 x_cash_flow_det_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
6357 IS
6358 -- Local Variables
6359 l_api_version CONSTANT NUMBER DEFAULT 1.0;
6360 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lq_cash_flows';
6361 l_return_status VARCHAR2(1);
6362
6363 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
6364 || G_PKG_NAME || '.' || UPPER(l_api_name);
6365 l_debug_enabled VARCHAR2(10);
6366 is_debug_procedure_on BOOLEAN;
6367 is_debug_statement_on BOOLEAN;
6368
6369 -- Cursor Declarations ..
6370 CURSOR quote_csr(qteid NUMBER)
6371 IS
6372 SELECT qte.expected_start_date expected_start_date,
6373 qte.target_rate_type target_rate_type,
6374 qte.target_frequency target_frequency,
6375 qte.target_arrears_yn target_arrears,
6376 qte.target_rate target_rate,
6377 qte.target_periods target_periods,
6378 qte.target_amount target_amount,
6379 qte.term term,
6380 qte.structured_pricing structured_pricing,
6381 qte.pricing_method pricing_method
6382 FROM okl_lease_quotes_b qte
6383 WHERE qte.id = qteid;
6384 quote_rec quote_csr%ROWTYPE;
6385 -- Cursor to fetch the ID of the CFL defined at Quote Level !
6386 CURSOR get_cfl_id_csr( qteId NUMBER )
6387 IS
6388 SELECT cfl.ID cfl_id,
6389 cfh.id caf_id,
6390 cfo.id cfo_id,
6391 cfh.sty_id stream_type_id
6392 FROM OKL_CASH_FLOW_LEVELS cfl,
6393 OKL_CASH_FLOWS cfh,
6394 OKL_CASH_FLOW_OBJECTS cfo
6395 WHERE cfl.caf_id = cfh.id
6396 AND cfh.cfo_id = cfo.id
6397 AND cfo.source_table = 'OKL_LEASE_QUOTES_B'
6398 AND cfo.source_id = qteId
6399 ORDER BY cfl.start_date;
6400 -- Cursor to fetch the Details from the Asset
6401 CURSOR asset_details_csr( p_astId NUMBER )
6402 IS
6403 SELECT target_arrears,
6404 target_amount,
6405 parent_object_id
6406 FROM OKL_ASSETS_B
6407 WHERE id = p_astId;
6408 -- Cursor to fetch the Details from the Asset
6409 CURSOR fee_details_csr( p_feeId NUMBER )
6410 IS
6411 SELECT target_arrears,
6412 target_amount,
6413 parent_object_id,
6414 payment_type_id
6415 FROM OKL_FEES_B
6416 WHERE id = p_feeId;
6417 -- Cursor to fetch the Cash flow header information
6418 CURSOR lq_cash_flows_csr( p_id NUMBER, p_cf_source_type VARCHAR2 )
6419 IS
6420 SELECT cf.id caf_id
6421 ,dnz_khr_id khr_id
6422 ,dnz_qte_id qte_id
6423 ,cfo_id cfo_id
6424 ,sts_code sts_code
6425 ,sty_id sty_id
6426 ,cft_code cft_code
6427 ,due_arrears_yn due_arrears_yn
6428 ,start_date start_date
6429 ,number_of_advance_periods number_of_advance_periods
6430 ,oty_code oty_code
6431 FROM OKL_CASH_FLOWS cf,
6432 OKL_CASH_FLOW_OBJECTS cfo
6433 WHERE cf.cfo_id = cfo.id
6434 AND cfo.source_table = p_cf_source_type
6435 AND cfo.source_id = p_id;
6436 -- Cursor to fetch the Cash Flow Details
6437 CURSOR lq_cash_flow_levels_csr( p_caf_id NUMBER )
6438 IS
6439 SELECT id cfl_id
6440 ,caf_id
6441 ,fqy_code
6442 ,rate -- No rate is defined at Cash Flows Level.. Need to confirm
6443 ,stub_days
6444 ,stub_amount
6445 ,number_of_periods
6446 ,amount
6447 ,start_date
6448 FROM OKL_CASH_FLOW_LEVELS
6449 WHERE caf_id = p_caf_id
6450 ORDER BY start_date;
6451 -- Local Variables declaration
6452 l_cash_flow_rec so_cash_flows_rec_type;
6453 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
6454 i NUMBER; -- Index for looping over the Cash Flow Details
6455 l_months_per_period NUMBER;
6456 l_months_after NUMBER;
6457 -- Standard Rate Template Variables
6458 l_srt_details srt_details_rec_type;
6459 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
6460 l_adj_factor NUMBER;
6461 l_months_factor NUMBER;
6462 l_lq_id NUMBER;
6463 l_target_arrears NUMBER;
6464 cfl_index BINARY_INTEGER;
6465 BEGIN
6466 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6467 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
6468 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
6469 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6470 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
6471 -- check for logging on STATEMENT level
6472 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
6473 l_return_status := OKL_API.START_ACTIVITY(
6474 p_api_name => l_api_name,
6475 p_pkg_name => G_PKG_NAME,
6476 p_init_msg_list => p_init_msg_list,
6477 l_api_version => l_api_version,
6478 p_api_version => p_api_version,
6479 p_api_type => g_api_type,
6480 x_return_status => x_return_status);
6481 --Check if activity started successfully
6482 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6483 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6484 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6485 RAISE OKL_API.G_EXCEPTION_ERROR;
6486 END IF;
6487 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', ': p_id=' || p_id );
6488 i := 1;
6489 l_months_after := 0;
6490 l_adj_factor := 0;
6491 IF p_cf_source = G_CF_SOURCE_LQ
6492 THEN
6493 l_lq_id := p_id;
6494 ELSIF p_cf_source = G_CF_SOURCE_LQ_ASS
6495 THEN
6496 FOR t_rec IN asset_details_csr( p_id )
6497 LOOP
6498 l_lq_id := t_rec.parent_object_id;
6499 END LOOP;
6500 ELSIF p_cf_source = G_CF_SOURCE_LQ_FEE
6501 THEN
6502 FOR t_rec IN fee_details_csr( p_id )
6503 LOOP
6504 l_lq_id := t_rec.parent_object_id;
6505 END LOOP;
6506 END IF;
6507 -- Check whether the pricing method is of type Rate Card
6508 IF p_lq_srt_id IS NOT NULL
6509 THEN
6510 -- Fetch the target column values ..
6511 OPEN quote_csr(qteid => l_lq_id );
6512 FETCH quote_csr INTO quote_rec;
6513 CLOSE quote_csr;
6514 -- Extract details from the Standard Rate Template
6515 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6516 'Fetching the Details from the Standard Rate Template ' );
6517 get_standard_rates(
6518 p_api_version => p_api_version,
6519 p_init_msg_list => p_init_msg_list,
6520 x_return_status => l_return_status,
6521 x_msg_count => x_msg_count,
6522 x_msg_data => x_msg_data,
6523 p_srt_id => p_lq_srt_id,
6524 p_start_date => p_adj_mat_cat_rec.target_eff_from,
6525 x_srt_details => l_srt_details);
6526 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6527 ': l_return_status ' || l_return_status );
6528 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6529 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6530 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6531 RAISE OKL_API.G_EXCEPTION_ERROR;
6532 END IF;
6533 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6534 'Using SRT ' || l_srt_details.template_name || ' Version ' || l_srt_details.version_number
6535 || ' Status ' || l_srt_details.sts_code || ' Pricing Engine ' || l_srt_details.pricing_engine_code
6536 || ' Rate Type ' || l_srt_details.rate_type_code || ' Day Convention ' ||
6537 l_srt_details.day_convention_code );
6538 -- Need to apply the Adjustment factor to the rate !
6539 IF l_srt_details.adj_mat_version_id IS NOT NULL
6540 THEN
6541 l_ac_rec_type.src_id := l_srt_details.adj_mat_version_id; -- Pricing adjustment matrix ID
6542 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
6543 l_ac_rec_type.target_id := l_lq_id; -- Quote ID
6544 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
6545 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
6546 l_ac_rec_type.target_eff_from := p_adj_mat_cat_rec.target_eff_from; -- Quote effective From
6547 l_ac_rec_type.term := p_adj_mat_cat_rec.term; -- Remaining four will be from teh business object like QQ / LQ
6548 l_ac_rec_type.territory := p_adj_mat_cat_rec.territory;
6549 l_ac_rec_type.deal_size := p_adj_mat_cat_rec.deal_size; -- Not sure how to pass this value
6550 l_ac_rec_type.customer_credit_class := p_adj_mat_cat_rec.customer_credit_class; -- Not sure how to pass this even ..
6551 -- Calling the API to get the adjustment factor ..
6552 okl_ec_evaluate_pvt. get_adjustment_factor(
6553 p_api_version => p_api_version,
6554 p_init_msg_list => p_init_msg_list,
6555 x_return_status => x_return_status,
6556 x_msg_count => x_msg_count,
6557 x_msg_data => x_msg_data,
6558 p_okl_ac_rec => l_ac_rec_type,
6559 x_adjustment_factor => l_adj_factor );
6560 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6561 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6562 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6563 RAISE OKL_API.G_EXCEPTION_ERROR;
6564 END IF;
6565 END IF;
6566 -- Populating the Cash flow Header information
6567 IF p_cf_source = G_CF_SOURCE_LQ
6568 THEN
6569 l_cash_flow_rec.due_arrears_yn := quote_rec.target_arrears;
6570 l_cash_flow_det_tbl(1).amount := quote_rec.target_amount;
6571 ELSIF p_cf_source = G_CF_SOURCE_LQ_ASS
6572 THEN
6573 FOR t_rec IN asset_details_csr( p_id )
6574 LOOP
6575 l_cash_flow_rec.due_arrears_yn := t_rec.target_arrears;
6576 l_cash_flow_det_tbl(1).amount := t_rec.target_amount;
6577 END LOOP;
6578 ELSIF p_cf_source = G_CF_SOURCE_LQ_FEE
6579 THEN
6580 FOR t_rec IN fee_details_csr( p_id )
6581 LOOP
6582 l_cash_flow_rec.due_arrears_yn := t_rec.target_arrears;
6583 l_cash_flow_rec.sty_id := t_rec.payment_type_id;
6584 l_cash_flow_det_tbl(1).amount := t_rec.target_amount;
6585 END LOOP;
6586 END IF;
6587 l_cash_flow_rec.start_date := quote_rec.expected_start_date;
6588 IF quote_rec.pricing_method <> 'SM'
6589 THEN
6590 l_cash_flow_rec.sts_code := 'WORK';
6591 -- Populating the Cash flow levels
6592 l_cash_flow_det_tbl(1).fqy_code := l_srt_details.frequency_code;
6593 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
6594 IF nvl( l_srt_details.min_adj_rate,l_cash_flow_det_tbl(1).rate) > l_cash_flow_det_tbl(1).rate
6595 THEN
6596 l_cash_flow_det_tbl(1).rate := l_srt_details.min_adj_rate;
6597 ELSIF nvl( l_srt_details.max_adj_rate,l_cash_flow_det_tbl(1).rate) < l_cash_flow_det_tbl(1).rate
6598 THEN
6599 l_cash_flow_det_tbl(1).rate := l_srt_details.max_adj_rate;
6600 END IF;
6601 l_cash_flow_det_tbl(1).is_stub := 'N';
6602 l_cash_flow_det_tbl(1).start_date := quote_rec.expected_start_date;
6603 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6604 'GET_LQ p_frequency_passed' || l_srt_details.frequency_code);
6605 l_months_factor := okl_stream_generator_pvt.get_months_factor(
6606 p_frequency => l_srt_details.frequency_code,
6607 x_return_status => l_return_status);
6608 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6609 'p_months_factor'||l_months_factor);
6610 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6611 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6612 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6613 RAISE OKL_API.G_EXCEPTION_ERROR;
6614 END IF;
6615 l_cash_flow_det_tbl(1).number_of_periods := quote_rec.term / l_months_factor;
6616 --l_cash_flow_det_tbl(1).amount has been already fetched from the
6617 -- target_amount column either from OKL_LEASE_QUOTES_B/OKL_ASSETS_B/OKL_FEES_B
6618 ELSE
6619 -- When the LQ is being priced for SM pricng method, on selecting the SRT
6620 -- as the pricing option, the user will be shown to enter the Cash flow levels too.
6621 -- Hence, retrieve the cash flow levels even when the pricing option is SRT.
6622 -- From SRT, get the Rate,Frequency
6623 -- From CFL, get the Advance/Arrears, n, Fetching the Cash Flows Information
6624 l_return_status := OKL_API.G_RET_STS_ERROR;
6625 FOR t_rec in lq_cash_flows_csr( p_id =>p_id,
6626 p_cf_source_type => p_cf_source )
6627 LOOP
6628 l_cash_flow_rec.caf_id := t_rec.caf_id;
6629 l_cash_flow_rec.khr_id := t_rec.khr_id;
6630 l_cash_flow_rec.khr_id := t_rec.khr_id;
6631 l_cash_flow_rec.qte_id := t_rec.qte_id;
6632 l_cash_flow_rec.cfo_id := t_rec.cfo_id;
6633 l_cash_flow_rec.sts_code := t_rec.sts_code;
6634 l_cash_flow_rec.sty_id := t_rec.sty_id;
6635 l_cash_flow_rec.cft_code := t_rec.cft_code;
6636 l_cash_flow_rec.due_arrears_yn := t_rec.due_arrears_yn;
6637 l_cash_flow_rec.start_date := t_rec.start_date;
6638 l_cash_flow_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
6639 -- Use l_retun_status as a flag
6640 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6641 END LOOP;
6642 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
6643 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
6644 THEN
6645 cfl_index := 1;
6646 l_return_status := OKL_API.G_RET_STS_ERROR;
6647 -- Cash Flows exists. So, fetch the Cash Flow Levels
6648 FOR t_rec in lq_cash_flow_levels_csr( l_cash_flow_rec.caf_id )
6649 LOOP
6650 l_cash_flow_det_tbl(cfl_index).cfl_id := t_rec.cfl_id;
6651 l_cash_flow_det_tbl(cfl_index).caf_id := t_rec.caf_id;
6652 l_cash_flow_det_tbl(cfl_index).fqy_code := l_srt_details.frequency_code;
6653 -- Effective Rate from SRT = Rate + Spread + Adj Matrix
6654 l_cash_flow_det_tbl(cfl_index).rate :=
6655 l_srt_details.srt_rate + nvl(l_srt_details.spread,0) + nvl(l_adj_factor,0);
6656 IF nvl( l_srt_details.min_adj_rate,l_cash_flow_det_tbl(cfl_index).rate) >
6657 l_cash_flow_det_tbl(cfl_index).rate
6658 THEN
6659 l_cash_flow_det_tbl(cfl_index).rate := l_srt_details.min_adj_rate;
6660 ELSIF nvl( l_srt_details.max_adj_rate, l_cash_flow_det_tbl(1).rate) <
6661 l_cash_flow_det_tbl(cfl_index).rate
6662 THEN
6663 l_cash_flow_det_tbl(cfl_index).rate := l_srt_details.max_adj_rate;
6664 END IF;
6665 l_cash_flow_det_tbl(cfl_index).stub_days := t_rec.stub_days;
6666 l_cash_flow_det_tbl(cfl_index).stub_amount := t_rec.stub_amount;
6667 l_cash_flow_det_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
6668 l_cash_flow_det_tbl(cfl_index).amount := t_rec.amount;
6669 l_cash_flow_det_tbl(cfl_index).start_date := t_rec.start_date;
6670 -- Remember the flag whether its a stub payment or not
6671 IF t_rec.stub_days IS NOT NULL and t_rec.stub_amount IS NOT NULL
6672 THEN
6673 -- Stub Payment
6674 l_cash_flow_det_tbl(cfl_index).is_stub := 'Y';
6675 ELSE
6676 -- Regular Periodic Payment
6677 l_cash_flow_det_tbl(cfl_index).is_stub := 'N';
6678 END IF;
6679 -- Use l_retun_status as a flag
6680 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6681 -- Increment i
6682 cfl_index := cfl_index + 1;
6683 END LOOP;
6684 ELSE
6685 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6686 END IF;
6687 END IF;
6688 -- Get the Day convention from the SRT itself !
6689 x_days_in_year := l_srt_details.day_convention_code;
6690 IF x_days_in_year = '360'
6691 THEN
6692 x_days_in_month := '30';
6693 ELSIF x_days_in_year = '365' OR x_days_in_year = 'ACTUAL'
6694 THEN
6695 x_days_in_month := 'ACTUAL';
6696 END IF;
6697 ELSIF p_pricing_method = 'TR'
6698 THEN
6699 -- Fetch the target column values ..
6700 OPEN quote_csr(qteid => l_lq_id );
6701 FETCH quote_csr INTO quote_rec;
6702 CLOSE quote_csr;
6703 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6704 'After fetching the quote_csr details ');
6705 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6706 'Building the Cash flows n Inflows ' || p_pricing_method );
6707 -- Populating the Cash flows
6708 IF p_cf_source = G_CF_SOURCE_LQ_FEE
6709 THEN
6710 -- For Rollover/Financed fee, though the PM is TR, where LLO is not applicable
6711 -- there also, pricing will fetch Adv/Arrears, Rate, Frequency will be fetched
6712 -- from the quote, but the Payment Stream ID will be store in the okl_fees_b.payment_sty_id
6713 FOR t_rec IN fee_details_csr( p_id )
6714 LOOP
6715 l_cash_flow_rec.sty_id := t_rec.payment_type_id;
6716 END LOOP;
6717 END IF;
6718 l_cash_flow_rec.due_arrears_yn := quote_rec.target_arrears;
6719 l_cash_flow_rec.start_date := quote_rec.expected_start_date;
6720 -- Populating the Cash flow levels
6721 l_cash_flow_det_tbl(1).fqy_code := quote_rec.target_frequency;
6722 l_cash_flow_det_tbl(1).rate := quote_rec.target_rate; -- Rate is being stored as Percentage
6723 l_cash_flow_det_tbl(1).is_stub := 'N';
6724 l_cash_flow_det_tbl(1).start_date := quote_rec.expected_start_date;
6725 l_cash_flow_det_tbl(1).number_of_periods := quote_rec.target_periods;
6726 -- Need to fetch the CFL Id for the Updation
6727 FOR t_rec IN get_cfl_id_csr( qteId => p_id )
6728 LOOP
6729 l_cash_flow_rec.caf_id := t_rec.caf_id;
6730 l_cash_flow_rec.cfo_id := t_rec.cfo_id;
6731 l_cash_flow_rec.sty_id := t_rec.stream_type_id;
6732 l_cash_flow_det_tbl(1).cfl_id := t_rec.cfl_id;
6733 END LOOP;
6734 get_lq_sgt_day_convention(
6735 p_api_version => p_api_version,
6736 p_init_msg_list => p_init_msg_list,
6737 x_return_status => l_return_status,
6738 x_msg_count => x_msg_count,
6739 x_msg_data => x_msg_data,
6740 p_lq_id => p_id,
6741 x_days_in_month => x_days_in_month,
6742 x_days_in_year => x_days_in_year);
6743 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6744 ': After Fetching the Day convention from the SGT - TR ' );
6745 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6746 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6747 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6748 RAISE OKL_API.G_EXCEPTION_ERROR;
6749 END IF;
6750 ELSE
6751 -- Assuming that the Asset is having Structured Pricing overridden
6752 -- from that of the Payment Structure defined at the Lease Quote level
6753 get_qq_cash_flows(
6754 p_api_version => p_api_version,
6755 p_init_msg_list => p_init_msg_list,
6756 x_return_status => l_return_status,
6757 x_msg_count => x_msg_count,
6758 x_msg_data => x_msg_data,
6759 p_cf_source_type => p_cf_source, -- Pass the source type OKL_ASSETS_B/OKL_LEASE_QUOTES_B
6760 p_qq_id => p_id, -- Pass the id of the Assets/ Lease Quote !
6761 x_days_in_month => x_days_in_month,
6762 x_days_in_year => x_days_in_year,
6763 x_cash_flow_rec => l_cash_flow_rec, -- Cash Flow Record
6764 x_cash_flow_det_tbl => l_cash_flow_det_tbl); -- Cash Flow Details Table
6765 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6766 'After get_qq_cash_flows ' || l_return_status );
6767 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6768 'l_cash_flow_det_tbl.COUNT ' || l_cash_flow_det_tbl.COUNT);
6769 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6770 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6771 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6772 RAISE OKL_API.G_EXCEPTION_ERROR;
6773 END IF;
6774 END IF; -- IF p_qq_hdr_rec.pricing_method
6775 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6776 ': Built the Cash flows and Levels ' );
6777 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6778 'Arrears = ' || l_cash_flow_rec.due_arrears_yn
6779 || 'Start Date=' || l_cash_flow_rec.start_date );
6780 IF l_cash_flow_det_tbl.COUNT > 0
6781 THEN
6782 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6783 ': Frequency | Rate | Stub Amount | Stub Days | Periods | Amount | Start Date ' );
6784 FOR t IN l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
6785 LOOP
6786 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6787 l_cash_flow_det_tbl(t).fqy_code || '|' || l_cash_flow_det_tbl(t).rate
6788 || '|' || l_cash_flow_det_tbl(t).stub_days || '|' || l_cash_flow_det_tbl(t).stub_amount
6789 || '|' || l_cash_flow_det_tbl(t).number_of_periods
6790 || '|' || l_cash_flow_det_tbl(t).amount || '|' || l_cash_flow_det_tbl(t).start_date
6791 || '|' || l_cash_flow_det_tbl(t).is_stub );
6792 END LOOP;
6793 END IF;
6794 -- Setting up the return variables
6795 x_cash_flow_rec := l_cash_flow_rec;
6796 x_cash_flow_det_tbl := l_cash_flow_det_tbl;
6797 x_return_status := l_return_status;
6798
6799 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
6800 x_msg_data => x_msg_data);
6801 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6802 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
6803 EXCEPTION
6804 WHEN OKL_API.G_EXCEPTION_ERROR THEN
6805 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6806 p_api_name => l_api_name,
6807 p_pkg_name => G_PKG_NAME,
6808 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
6809 x_msg_count => x_msg_count,
6810 x_msg_data => x_msg_data,
6811 p_api_type => g_api_type);
6812 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
6813 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6814 p_api_name => l_api_name,
6815 p_pkg_name => G_PKG_NAME,
6816 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
6817 x_msg_count => x_msg_count,
6818 x_msg_data => x_msg_data,
6819 p_api_type => g_api_type);
6820 WHEN OTHERS THEN
6821 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6822 p_api_name => l_api_name,
6823 p_pkg_name => G_PKG_NAME,
6824 p_exc_name => 'OTHERS',
6825 x_msg_count => x_msg_count,
6826 x_msg_data => x_msg_data,
6827 p_api_type => g_api_type);
6828 END get_lq_cash_flows;
6829
6830 -- API to price a quick quote... Just need to pass me the ID ;-)
6831 PROCEDURE price_quick_quote(
6832 p_api_version IN NUMBER,
6833 p_init_msg_list IN VARCHAR2,
6834 x_return_status OUT NOCOPY VARCHAR2,
6835 x_msg_count OUT NOCOPY NUMBER,
6836 x_msg_data OUT NOCOPY VARCHAR2,
6837 p_qq_id IN NUMBER,
6838 x_yileds_rec OUT NOCOPY yields_rec,
6839 x_subsidized_yileds_rec OUT NOCOPY yields_rec,
6840 x_pricing_results_tbl OUT NOCOPY pricing_results_tbl_type )
6841 IS
6842 -- Cursor to fetch EOT Type
6843 CURSOR get_eot_type( p_qq_id NUMBER )
6844 IS
6845 SELECT qq.id
6846 ,qq.reference_number
6847 ,eot.end_of_term_name
6848 ,eot.eot_type_code eot_type_code
6849 ,eot.end_of_term_id end_of_term_id
6850 ,eotversion.end_of_term_ver_id
6851 FROM OKL_QUICK_QUOTES_B qq,
6852 okl_fe_eo_term_vers eotversion,
6853 okl_fe_eo_terms_all_b eot
6854 WHERE qq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
6855 AND eot.end_of_term_id = eotversion.end_of_term_id
6856 AND qq.id = p_qq_id;
6857
6858 --Bug 5884825 PAGARG start
6859 CURSOR get_product_name( p_qq_id NUMBER )
6860 IS
6861 SELECT PDT.NAME PRODUCTNAME
6862 FROM OKL_QUICK_QUOTES_B QQ
6863 , OKL_FE_EO_TERM_VERS EOTVERSION
6864 , OKL_FE_EO_TERMS_ALL_B EOT
6865 , OKL_PRODUCTS PDT
6866 WHERE QQ.END_OF_TERM_OPTION_ID = EOTVERSION.END_OF_TERM_VER_ID
6867 AND EOT.END_OF_TERM_ID = EOTVERSION.END_OF_TERM_ID
6868 AND PDT.ID = EOT.PRODUCT_ID
6869 AND QQ.ID = P_QQ_ID;
6870 --Bug 5884825 PAGARG End
6871
6872 -- Local Variables
6873 l_product_name okl_products.NAME%TYPE;--Bug 5884825 PAGARG
6874 l_api_version CONSTANT NUMBER DEFAULT 1.0;
6875 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'price_quick_quote';
6876 l_return_status VARCHAR2(1);
6877 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
6878 || G_PKG_NAME || '.' || UPPER(l_api_name);
6879 l_debug_enabled VARCHAR2(10);
6880 is_debug_procedure_on BOOLEAN;
6881 is_debug_statement_on BOOLEAN;
6882 -- Declarations
6883 l_valid_pm BOOLEAN; -- Flag holding true/false for valid Pricing Method
6884 l_tot_item_cat_amount NUMBER;
6885 l_tot_rent_payment NUMBER;
6886 l_tot_eot_amount NUMBER;
6887 l_eot_percentage NUMBER;
6888 l_oec NUMBER;
6889 l_hdr_rec so_hdr_rec_type;
6890 l_item_cat_tbl so_asset_details_tbl_type;
6891 l_residual_strms_tbl cash_inflows_tbl_type;
6892 l_pricing_parameters_rec pricing_parameter_rec_type;
6893 l_pricing_parameters_tbl pricing_parameter_tbl_type;
6894 l_pricing_parameters_tbl_cp pricing_parameter_tbl_type;
6895 l_tmp_prc_params_tbl pricing_parameter_tbl_type;
6896 pp_index NUMBER; -- Index for the l_pricing_parameters_tbl
6897 l_fin_adj_rec so_amt_details_rec_type;
6898 l_cash_flow_rec so_cash_flows_rec_type;
6899 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
6900 l_fee_srv_tbl so_fee_srv_tbl_type;
6901 l_strm_ele_tbl cash_inflows_tbl_type;
6902 l_dummy_strm_ele_tbl cash_inflows_tbl_type;
6903 l_eot_date DATE;
6904 l_iir NUMBER;
6905 l_irr NUMBER;
6906 l_bk_yield NUMBER;
6907 l_cf_dpp NUMBER;
6908 l_cf_ppy NUMBER;
6909 l_day_count_method VARCHAR2(30);
6910 l_days_in_month VARCHAR2(30);
6911 l_days_in_year VARCHAR2(30);
6912 l_miss_payment NUMBER;
6913 l_yields_rec yields_rec;
6914 l_subsidized_yields_rec yields_rec;
6915 l_qqlv_rec OKL_QQL_PVT.qqlv_rec_type;
6916 x_qqlv_rec OKL_QQL_PVT.qqlv_rec_type;
6917 x_termination_tbl cash_inflows_tbl_type;
6918 x_pre_tax_inc_tbl cash_inflows_tbl_type;
6919 i NUMBER;
6920 res_index NUMBER := 1;
6921 l_frequency VARCHAR2(30);
6922 l_item_cat_cf_tbl item_cat_cf_tbl_type;
6923 l_tmp_pp_index NUMBER;
6924 l_sgt_days_in_month VARCHAR2(30);
6925 l_sgt_days_in_year VARCHAR2(30);
6926 l_sgt_day_count_method VARCHAR2(30);
6927 l_eot_type_code VARCHAR2(30);
6928 l_net_percent NUMBER;
6929 l_net_financed_amount NUMBER;
6930 l_closing_balance NUMBER;
6931 l_residual_percent NUMBER;
6932 l_residual_int_factor NUMBER;
6933 l_net_adj_amt NUMBER;
6934 BEGIN
6935 l_return_status := OKL_API.G_RET_STS_SUCCESS;
6936 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
6937 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
6938 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
6939 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
6940 -- check for logging on STATEMENT level
6941 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
6942 -- Call START_ACTIVITY to create savepoint, check compatibility
6943 -- and initialize message list
6944 l_return_status := OKL_API.START_ACTIVITY(
6945 p_api_name => l_api_name,
6946 p_pkg_name => G_PKG_NAME,
6947 p_init_msg_list => p_init_msg_list,
6948 l_api_version => l_api_version,
6949 p_api_version => p_api_version,
6950 p_api_type => g_api_type,
6951 x_return_status => x_return_status);
6952 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6953 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6954 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6955 RAISE OKL_API.G_EXCEPTION_ERROR;
6956 END IF;
6957 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6958 ': p_qq_id ' || p_qq_id );
6959
6960 --Bug 5884825 PAGARG start
6961 OPEN get_product_name(p_qq_id);
6962 FETCH get_product_name INTO l_product_name;
6963 CLOSE get_product_name;
6964 --Bug 5884825 PAGARG end
6965
6966 -- Fetch the Header Details such as Start Date, Term, Pricing Method .. etc
6967 get_so_hdr(
6968 p_api_version => p_api_version,
6969 p_init_msg_list => p_init_msg_list,
6970 x_return_status => l_return_status,
6971 x_msg_count => x_msg_count,
6972 x_msg_data => x_msg_data,
6973 p_so_id => p_qq_id,
6974 p_so_type => 'QQ',
6975 x_so_hdr_rec => l_hdr_rec );
6976 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6977 'After get_so_hdr ' || l_return_status );
6978 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6979 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6980 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
6981 RAISE OKL_API.G_EXCEPTION_ERROR;
6982 END IF;
6983 -- Validate the Pricing Method for Quick Quote
6984 -- RC, SF, SP, SS, SY, TR are the permitted pricing methods for the Quick Quote
6985 l_valid_pm := validate_pricing_method(
6986 p_pricing_method => l_hdr_rec.pricing_method,
6987 p_object_type => 'QQ',
6988 x_return_status => l_return_status);
6989 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6990 'After validate_pricing_method ' || l_return_status );
6991 IF l_valid_pm
6992 THEN
6993 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6994 'l_valid_pm = TRUE' );
6995 ELSE
6996 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
6997 'l_valid_pm = FALSE' );
6998 END IF;
6999 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7000 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7001 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7002 RAISE OKL_API.G_EXCEPTION_ERROR;
7003 END IF;
7004 -- If Pricing Method is invalid .. raise exception ..
7005 IF l_valid_pm = FALSE
7006 THEN
7007 -- Display a message and raise an exception ..
7008 OKL_API.SET_MESSAGE(
7009 p_app_name => g_app_name,
7010 p_msg_name => g_invalid_value,
7011 p_token1 => g_col_name_token,
7012 p_token1_value => 'Pricing Method');
7013 RAISE OKL_API.G_EXCEPTION_ERROR;
7014 END IF;
7015 -- Know the type of the EOT and then proceed with the values directly or calculate the amount
7016 FOR t_rec IN get_eot_type( p_qq_id => p_qq_id )
7017 LOOP
7018 l_eot_type_code := t_rec.eot_type_code;
7019 END LOOP;
7020 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7021 'l_eot_type_code=' || l_eot_type_code );
7022 -- Get Item Costs, Residual Values
7023 get_qq_item_cat_details(
7024 p_api_version => p_api_version,
7025 p_init_msg_list => p_init_msg_list,
7026 x_return_status => l_return_status,
7027 x_msg_count => x_msg_count,
7028 x_msg_data => x_msg_data,
7029 p_qq_id => p_qq_id,
7030 p_pricing_method => l_hdr_rec.pricing_method,
7031 x_asset_amounts_tbl => l_item_cat_tbl);
7032 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7033 'After get_qq_item_cat_details ' || l_return_status );
7034 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7035 'l_item_cat_tbl.COUNT ' || l_item_cat_tbl.COUNT );
7036 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7037 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7038 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7039 RAISE OKL_API.G_EXCEPTION_ERROR;
7040 END IF;
7041 -- Loop through the Item Category Table and determine the Total Item Cat Cost
7042 l_tot_item_cat_amount := 0;
7043 l_tot_eot_amount := 0;
7044 IF l_hdr_rec.pricing_method <> 'SF' AND
7045 l_item_cat_tbl IS NOT NULL AND
7046 l_item_cat_tbl.COUNT > 0
7047 THEN
7048 FOR i in l_item_cat_tbl.FIRST .. l_item_cat_tbl.LAST
7049 LOOP
7050 l_tot_item_cat_amount := l_tot_item_cat_amount + nvl( l_item_cat_tbl(i).asset_cost,0);
7051 END LOOP;
7052 END IF;
7053 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7054 'l_tot_item_cat_amount =' || l_tot_item_cat_amount );
7055 -- Calculate the total End of term value amount
7056 l_tot_eot_amount := 0;
7057 IF l_item_cat_tbl IS NOT NULL AND
7058 l_item_cat_tbl.COUNT > 0
7059 THEN
7060 FOR itc_index in l_item_cat_tbl.FIRST .. l_item_cat_tbl.LAST
7061 LOOP
7062 l_tot_eot_amount := l_tot_eot_amount + l_item_cat_tbl(itc_index).end_of_term_amount;
7063 END LOOP;
7064 END IF;
7065 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7066 'l_tot_eot_amount =' || l_tot_eot_amount );
7067 -- Get Finance Adjustment Details
7068 -- like down payment, trade in, subsidy
7069 get_qq_fin_adj_details(
7070 p_api_version => p_api_version,
7071 p_init_msg_list => p_init_msg_list,
7072 x_return_status => l_return_status,
7073 x_msg_count => x_msg_count,
7074 x_msg_data => x_msg_data,
7075 p_qq_id => p_qq_id,
7076 p_pricing_method => l_hdr_rec.pricing_method,
7077 p_item_category_amount => l_tot_item_cat_amount,
7078 x_all_amounts_rec => l_fin_adj_rec);
7079 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7080 'After get_qq_fin_adj_details ' || l_return_status );
7081 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7082 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7083 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7084 RAISE OKL_API.G_EXCEPTION_ERROR;
7085 END IF;
7086 -- Possibly now, we can build the Pricing Parameter Record
7087 l_pricing_parameters_rec.financed_amount := l_tot_item_cat_amount;
7088 l_pricing_parameters_rec.trade_in := l_fin_adj_rec.tradein_amount;
7089 l_pricing_parameters_rec.down_payment := l_fin_adj_rec.down_payment_amount;
7090 l_pricing_parameters_rec.subsidy := l_fin_adj_rec.subsidy_amount;
7091
7092 -- Calculate the eot percentage using the formula
7093 -- ( l_tot_eot_amount / l_tot_item_cat_amount - subsidy - downpayment - trade in ) * 100
7094 l_eot_percentage := 0;
7095 IF l_hdr_rec.pricing_method <> 'SF'
7096 THEN
7097 -- Need to deduct the Trade_in, Subsidy, Down Payment values from the
7098 get_qq_asset_oec (
7099 p_api_version => p_api_version,
7100 p_init_msg_list => p_init_msg_list,
7101 x_return_status => l_return_status,
7102 x_msg_count => x_msg_count,
7103 x_msg_data => x_msg_data,
7104 p_asset_cost => l_tot_item_cat_amount,
7105 p_fin_adj_det_rec => l_fin_adj_rec,
7106 x_oec => l_oec);
7107 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7108 'After get_qq_asset_oec ' || l_return_status );
7109 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7110 'l_oec=' || nvl( l_oec, 0 ) );
7111 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7112 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7113 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7114 RAISE OKL_API.G_EXCEPTION_ERROR;
7115 END IF;
7116 l_eot_percentage := ( l_tot_eot_amount / l_oec ) * 100; -- EOT Percentage;
7117 END IF;
7118 IF l_hdr_rec.pricing_method = 'RC' -- Rate card pricing
7119 THEN
7120 -- Build the cash flows when the pricing method is Rate Card !
7121 get_qq_rc_cash_flows(
7122 p_api_version => p_api_version,
7123 p_init_msg_list => p_init_msg_list,
7124 x_return_status => l_return_status,
7125 x_msg_count => x_msg_count,
7126 x_msg_data => x_msg_data,
7127 p_qq_hdr_rec => l_hdr_rec,
7128 x_days_in_month => l_days_in_month,
7129 x_days_in_year => l_days_in_year,
7130 x_item_cat_cf_tbl => l_item_cat_cf_tbl);
7131 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7132 'After get_qq_rc_cash_flows ' || l_return_status );
7133 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7134 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7135 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7136 RAISE OKL_API.G_EXCEPTION_ERROR;
7137 END IF;
7138 -- The frequency needs to be fetched from the target_frequency
7139 l_frequency := l_item_cat_cf_tbl(1).cash_flow_level_tbl(1).fqy_code;
7140 ELSE
7141 -- Retrieve or build the Cash flows and Levels when user picked
7142 -- Structured pricing / SRT ..
7143 -- Modifying this API to fetch you the pricing day convention
7144 get_qq_cash_flows(
7145 p_api_version => p_api_version,
7146 p_init_msg_list => p_init_msg_list,
7147 x_return_status => l_return_status,
7148 x_msg_count => x_msg_count,
7149 x_msg_data => x_msg_data,
7150 p_qq_hdr_rec => l_hdr_rec,
7151 p_eot_percentage => l_eot_percentage,
7152 p_oec => l_oec,
7153 x_days_in_month => l_days_in_month,
7154 x_days_in_year => l_days_in_year,
7155 x_cash_flow_rec => l_cash_flow_rec, -- Cash Flow Record
7156 x_cash_flow_det_tbl => l_cash_flow_det_tbl); -- Cash Flow Details Table
7157 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7158 'After get_qq_cash_flows ' || l_return_status );
7159 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7160 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7161 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7162 RAISE OKL_API.G_EXCEPTION_ERROR;
7163 END IF;
7164 -- Generate the Streams
7165 IF l_cash_flow_det_tbl IS NOT NULL AND
7166 l_cash_flow_det_tbl.COUNT > 0
7167 THEN
7168 -- Initialize the Strm Count to Zero
7169 gen_so_cf_strms(
7170 p_api_version => p_api_version,
7171 p_init_msg_list => p_init_msg_list,
7172 x_return_status => l_return_status,
7173 x_msg_count => x_msg_count,
7174 x_msg_data => x_msg_data,
7175 p_cash_flow_rec => l_cash_flow_rec,
7176 p_cf_details_tbl => l_cash_flow_det_tbl,
7177 x_cash_inflow_strms_tbl => l_strm_ele_tbl);
7178 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7179 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7180 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7181 RAISE OKL_API.G_EXCEPTION_ERROR;
7182 END IF;
7183 l_frequency := l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code;
7184 ELSE
7185 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7186 'No Cash flow and Cash flow Levels obtained ! ' );
7187 OKL_API.SET_MESSAGE (
7188 p_app_name => G_APP_NAME,
7189 p_msg_name => 'OKL_LLA_PMT_SELECT');
7190 RAISE OKL_API.G_EXCEPTION_ERROR;
7191 END IF;
7192 END IF; -- IF on Rate Card Pricing Method ..
7193 -- Build the Residuals Table
7194 IF l_item_cat_tbl IS NOT NULL AND
7195 l_item_cat_tbl.COUNT > 0
7196 THEN
7197 okl_stream_generator_pvt.add_months_new(
7198 p_start_date => l_hdr_rec.expected_start_date,
7199 p_months_after => l_hdr_rec.term,
7200 x_date => l_eot_date,
7201 x_return_status => l_return_status);
7202 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7203 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7204 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7205 RAISE OKL_API.G_EXCEPTION_ERROR;
7206 END IF;
7207 l_eot_date := l_eot_date - 1;
7208 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7209 'QQ End date: ' || l_eot_date);
7210 -- Get the DPP and PPY inorder to populate for the Residuals Table
7211 get_dpp_ppy(
7212 p_frequency => l_frequency,
7213 x_dpp => l_cf_dpp,
7214 x_ppy => l_cf_ppy,
7215 x_return_status => l_return_status );
7216 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7217 'After get_dpp_ppy : ' || l_return_status);
7218 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7219 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7220 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7221 RAISE OKL_API.G_EXCEPTION_ERROR;
7222 END IF;
7223 IF l_hdr_rec.pricing_method <> 'RC'
7224 THEN
7225 FOR i in l_item_cat_tbl.FIRST .. l_item_cat_tbl.LAST
7226 LOOP
7227 l_residual_strms_tbl(i).line_number := i;
7228 l_residual_strms_tbl(i).cf_amount := l_item_cat_tbl(i).end_of_term_amount;
7229 l_residual_strms_tbl(i).cf_date := l_eot_date;
7230 l_residual_strms_tbl(i).cf_miss_pay := 'N';
7231 l_residual_strms_tbl(i).is_stub := 'N';
7232 l_residual_strms_tbl(i).is_arrears := 'Y';
7233 l_residual_strms_tbl(i).cf_dpp := l_cf_dpp;
7234 l_residual_strms_tbl(i).cf_ppy := l_cf_ppy;
7235 END LOOP;
7236 END IF; -- IF l_hdr_rec.pricing_method <> 'RC'
7237 END IF;
7238 pp_index := 1;
7239 IF l_hdr_rec.pricing_method = 'RC'
7240 THEN
7241 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7242 'Populate the Cash Flows and Levels for all item categories ');
7243 -- Generate the Streams
7244 FOR t IN l_item_cat_cf_tbl.FIRST .. l_item_cat_cf_tbl.LAST
7245 LOOP
7246 l_pricing_parameters_tbl(pp_index).line_type := 'FREE_FORM1';
7247 l_pricing_parameters_tbl(pp_index).line_start_date := l_hdr_rec.expected_start_date;
7248 l_pricing_parameters_tbl(pp_index).financed_amount := l_item_cat_cf_tbl(t).financed_amount;
7249 l_pricing_parameters_tbl(pp_index).down_payment := l_item_cat_cf_tbl(t).down_payment;
7250 l_pricing_parameters_tbl(pp_index).subsidy := l_item_cat_cf_tbl(t).subsidy;
7251 l_pricing_parameters_tbl(pp_index).trade_in := l_item_cat_cf_tbl(t).trade_in;
7252
7253 -- Storing the residual streams ..
7254 res_index := 1;
7255 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).line_number := res_index;
7256 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_amount := l_item_cat_cf_tbl(t).eot_amount;
7257 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_date := l_eot_date;
7258 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_miss_pay := 'N';
7259 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).is_stub := 'N';
7260 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).is_arrears := 'Y';
7261 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_dpp := l_cf_dpp;
7262 l_pricing_parameters_tbl(pp_index).residual_inflows(res_index).cf_ppy := l_cf_ppy;
7263
7264 IF l_item_cat_cf_tbl(t).cash_flow_level_tbl IS NOT NULL AND
7265 l_item_cat_cf_tbl(t).cash_flow_level_tbl.COUNT > 0
7266 THEN
7267 -- Initialize the Strm Count to Zero
7268 gen_so_cf_strms(
7269 p_api_version => p_api_version,
7270 p_init_msg_list => p_init_msg_list,
7271 x_return_status => l_return_status,
7272 x_msg_count => x_msg_count,
7273 x_msg_data => x_msg_data,
7274 p_cash_flow_rec => l_item_cat_cf_tbl(t).cash_flow_rec,
7275 p_cf_details_tbl => l_item_cat_cf_tbl(t).cash_flow_level_tbl,
7276 x_cash_inflow_strms_tbl => l_strm_ele_tbl);
7277 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7278 'After gen_so_cf_strms ' || l_return_status );
7279 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7280 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7281 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7282 RAISE OKL_API.G_EXCEPTION_ERROR;
7283 END IF;
7284 ELSE
7285 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7286 'No Cash flow and Cash flow Levels obtained ! ' );
7287 OKL_API.SET_MESSAGE (
7288 p_app_name => G_APP_NAME,
7289 p_msg_name => 'OKL_LLA_PMT_SELECT');
7290 RAISE OKL_API.G_EXCEPTION_ERROR;
7291 END IF;
7292 l_pricing_parameters_tbl(pp_index).cash_inflows := l_strm_ele_tbl;
7293 l_strm_ele_tbl.DELETE;
7294 -- Increment the pricing param index ..
7295 pp_index := pp_index + 1;
7296 END LOOP;
7297 -- Remember the pp_index count ... for calling the IIR !!
7298 l_tmp_pp_index := pp_index - 1;
7299 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7300 'No. of Item Pricing Params built for RC (l_tmp_pp_index ) ' || l_tmp_pp_index );
7301 ELSE
7302 -- Build the pricing param rec with line type as FREE_FORM1
7303 l_pricing_parameters_rec.residual_inflows := l_residual_strms_tbl;
7304 l_pricing_parameters_rec.cash_inflows := l_strm_ele_tbl;
7305 -- Build the pricing parameters table !!
7306 l_pricing_parameters_tbl(pp_index) := l_pricing_parameters_rec;
7307 l_pricing_parameters_tbl(pp_index).line_type := 'FREE_FORM1';
7308 -- Increment the pp_index ...
7309 pp_index := pp_index + 1;
7310 END IF;
7311 -- Initialize things common for various Pricing Methods
7312 -- Assigning the day count methods !
7313 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7314 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
7315 get_day_count_method(
7316 p_days_in_month => l_days_in_month,
7317 p_days_in_year => l_days_in_year,
7318 x_day_count_method => l_day_count_method,
7319 x_return_status => l_return_status );
7320 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7321 'After get_day_count_method ' || l_return_status);
7322 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7323 'l_day_count_method = ' || l_day_count_method);
7324 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7325 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7326 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7327 --Bug 5884825 PAGARG start
7328 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
7329 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
7330 p_token1 => 'PRODUCT_NAME',
7331 p_token1_value => l_product_name);
7332 --Bug 5884825 PAGARG end
7333 RAISE OKL_API.G_EXCEPTION_ERROR;
7334 END IF;
7335 IF l_hdr_rec.rate_template_id IS NOT NULL
7336 THEN
7337 -- Fetch the day convention from the Stream Generation Template ...
7338 -- only if the user has picked the SRT otherwise while building the cash flows
7339 -- itself, we would have fetched the day convention from the SGT.
7340 get_qq_sgt_day_convention(
7341 p_api_version => p_api_version,
7342 p_init_msg_list => p_init_msg_list,
7343 x_return_status => l_return_status,
7344 x_msg_count => x_msg_count,
7345 x_msg_data => x_msg_data,
7346 p_qq_id => p_qq_id,
7347 x_days_in_month => l_sgt_days_in_month,
7348 x_days_in_year => l_sgt_days_in_year);
7349 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7350 'After get_qq_sgt_day_convention ' || l_return_status );
7351 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7352 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7353 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7354 RAISE OKL_API.G_EXCEPTION_ERROR;
7355 END IF;
7356 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7357 'SGT Day convention: ' || l_days_in_month || ' / ' || l_days_in_year);
7358 -- Get the day convention ..
7359 get_day_count_method(
7360 p_days_in_month => l_sgt_days_in_month,
7361 p_days_in_year => l_sgt_days_in_year,
7362 x_day_count_method => l_sgt_day_count_method,
7363 x_return_status => l_return_status );
7364 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7365 '2/ After get_day_count_method ' || l_return_status);
7366 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7367 'l_sgt_day_count_method = ' || l_sgt_day_count_method);
7368 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7369 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7370 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7371 --Bug 5884825 PAGARG start
7372 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
7373 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
7374 p_token1 => 'PRODUCT_NAME',
7375 p_token1_value => l_product_name);
7376 --Bug 5884825 PAGARG end
7377 RAISE OKL_API.G_EXCEPTION_ERROR;
7378 END IF;
7379 ELSE
7380 -- The day convention returned by the get_qq_rc_cash_flows / get_qq_cash_flows
7381 -- will be from the SGT already, so just store them in the SGT day convention variables.
7382 l_sgt_days_in_month := l_days_in_month;
7383 l_sgt_days_in_year := l_days_in_year;
7384 l_sgt_day_count_method := l_day_count_method;
7385 END IF;
7386 --------------------------------------------------------------------------------
7387 -- Solving for Missing Parameter
7388 --------------------------------------------------------------------------------
7389 -- We now have all the parameters in the tables to pass to the compute_iir api ..
7390 IF l_hdr_rec.pricing_method = 'SF' AND
7391 (l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
7392 THEN
7393 l_hdr_rec.pricing_method := 'SFP';
7394 END IF;
7395 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7396 'Before compute_iir l_hdr_rec.pricing_method=' || l_hdr_rec.pricing_method || ' | l_eot_type_code = ' || l_eot_type_code);
7397 IF l_hdr_rec.pricing_method = 'SP' OR
7398 l_hdr_rec.pricing_method = 'SF' OR
7399 l_hdr_rec.pricing_method = 'SS' OR
7400 ( l_hdr_rec.pricing_method = 'TR' AND
7401 l_hdr_rec.target_rate_type = 'IIR') -- Target Rate and Interest Type is IIR
7402 THEN
7403 -- Compute iir !!
7404 compute_iir(
7405 p_api_version => p_api_version,
7406 p_init_msg_list => p_init_msg_list,
7407 x_return_status => l_return_status,
7408 x_msg_count => x_msg_count,
7409 x_msg_data => x_msg_data,
7410 p_start_date => l_hdr_rec.expected_start_date,
7411 p_day_count_method => l_day_count_method,
7412 p_pricing_method => l_hdr_rec.pricing_method,
7413 p_initial_guess => 0.1,
7414 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
7415 px_iir => l_iir,
7416 x_payment => l_miss_payment);
7417 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7418 'After compute_iir ' || l_return_status );
7419 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7420 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7421 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7422 RAISE OKL_API.G_EXCEPTION_ERROR;
7423 END IF;
7424 IF l_hdr_rec.pricing_method = 'SP' OR
7425 (l_hdr_rec.pricing_method = 'TR' AND
7426 l_hdr_rec.target_rate_type = 'IIR' )
7427 THEN
7428 IF l_miss_payment < 0
7429 THEN
7430 OKL_API.SET_MESSAGE (
7431 p_app_name => G_APP_NAME,
7432 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
7433 p_token1 => 'TYPE',
7434 p_token1_value => 'Payment',
7435 p_token2 => 'AMOUNT',
7436 p_token2_value => round(l_miss_payment,2) );
7437 RAISE okl_api.g_exception_error;
7438 END IF;
7439 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7440 ' SOLVED PAYMENT AMOUNT : ' || l_miss_payment );
7441 -- Populate back the missing payment amount in all the stream elements
7442 FOR t_index IN l_pricing_parameters_tbl(1).cash_inflows.FIRST ..
7443 l_pricing_parameters_tbl(1).cash_inflows.LAST
7444 LOOP
7445 l_pricing_parameters_tbl(1).cash_inflows(t_index).cf_amount := l_miss_payment;
7446 END LOOP; -- Loop on l_pricing_parameters_tbl
7447 ELSIF l_hdr_rec.pricing_method = 'SF'
7448 THEN
7449 -- Solve for Financed Amount
7450 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7451 ' SOLVED FOR FINANCED AMOUNT ' || l_pricing_parameters_tbl(1).financed_amount );
7452 ELSIF l_hdr_rec.pricing_method = 'SS'
7453 THEN
7454 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7455 'SOLVED SUBSIDY AMOUNT ' || l_pricing_parameters_tbl(1).subsidy );
7456 IF l_pricing_parameters_tbl(1).subsidy < 0
7457 THEN
7458 OKL_API.SET_MESSAGE (
7459 p_app_name => G_APP_NAME,
7460 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
7461 p_token1 => 'TYPE',
7462 p_token1_value => 'Subsidy',
7463 p_token2 => 'AMOUNT',
7464 p_token2_value => round(l_pricing_parameters_tbl(1).subsidy,2) );
7465 RAISE okl_api.g_exception_error;
7466 END IF;
7467 END IF; -- IF on pricing method
7468 ELSIF l_hdr_rec.pricing_method = 'SFP'
7469 THEN
7470 -- Before calling the compute_iir_sfp, the pricing param rec, should
7471 -- not be passed with any asset cost, and adjustments with either
7472 -- FIXED or PERCENTAGE OF ASSET COST !
7473 compute_iir_sfp(
7474 p_api_version => p_api_version,
7475 p_init_msg_list => p_init_msg_list,
7476 x_return_status => l_return_status,
7477 x_msg_count => x_msg_count,
7478 x_msg_data => x_msg_data,
7479 p_start_date => l_hdr_rec.expected_start_date,
7480 p_day_count_method => l_day_count_method,
7481 p_pricing_method => l_hdr_rec.pricing_method,
7482 p_initial_guess => 0.1,
7483 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
7484 px_iir => l_iir,
7485 x_closing_balance => l_closing_balance,
7486 x_residual_percent => l_residual_percent,
7487 x_residual_int_factor => l_residual_int_factor);
7488 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7489 'After compute_iir_sfp ' || l_return_status );
7490 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7491 'Closing Balance | Residual Percent | l_residual_int_factor ' );
7492 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7493 round(l_closing_balance, 4) || ' | ' || round( l_residual_percent, 4) || ' | ' || round(l_residual_int_factor,4) );
7494 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7495 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7496 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7497 RAISE OKL_API.G_EXCEPTION_ERROR;
7498 END IF;
7499 END IF;
7500 IF l_hdr_rec.pricing_method = 'SF' OR
7501 l_hdr_rec.pricing_method = 'SFP'
7502 THEN
7503 --Need to manipulate the financial adjustments which are of type percentage ..
7504 -- Find the Financed Amount ( C-S-D-T, considering only D, T, S which are of type FIXED. )
7505 l_net_financed_amount := l_pricing_parameters_tbl(1).financed_amount;
7506 l_tot_item_cat_amount := l_pricing_parameters_tbl(1).financed_amount;
7507 -- Now sum the percentages of the D, T, S
7508 l_net_percent := 0;
7509 l_net_adj_amt := 0;
7510 IF l_fin_adj_rec.down_payment_basis <> 'FIXED'
7511 THEN
7512 l_net_percent := l_net_percent + nvl(l_fin_adj_rec.down_payment_value, 0);
7513 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7514 ' ** Down Payment %age ' || l_fin_adj_rec.down_payment_value );
7515 ELSE
7516 l_net_adj_amt := l_net_adj_amt + nvl(l_pricing_parameters_tbl(1).down_payment,0);
7517 END IF;
7518 IF l_fin_adj_rec.tradein_basis <> 'FIXED'
7519 THEN
7520 l_net_percent := l_net_percent + nvl(l_fin_adj_rec.tradein_value, 0);
7521 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7522 ' ** Tradein %age ' || l_fin_adj_rec.tradein_value );
7523 ELSE
7524 l_net_adj_amt := l_net_adj_amt + nvl(l_pricing_parameters_tbl(1).trade_in,0);
7525 END IF;
7526 IF l_fin_adj_rec.subsidy_basis_tbl.COUNT > 0
7527 THEN
7528 FOR t IN l_fin_adj_rec.subsidy_basis_tbl.FIRST ..
7529 l_fin_adj_rec.subsidy_basis_tbl.LAST
7530 LOOP
7531 IF l_fin_adj_rec.subsidy_basis_tbl(t) <> 'FIXED'
7532 THEN
7533 l_net_percent := l_net_percent + nvl(l_fin_adj_rec.subsidy_value_tbl(t), 0);
7534 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7535 ' ** Subsidy('||t|| ') %age ' || l_fin_adj_rec.tradein_value );
7536 END IF;
7537 END LOOP;
7538 END IF; -- Subsidies exists
7539 l_net_adj_amt := l_net_adj_amt + nvl(l_pricing_parameters_tbl(1).subsidy,0);
7540 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7541 ' Down Payment | Trade in | Subsidy ' );
7542 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7543 round(l_pricing_parameters_tbl(1).down_payment,4) || ' | ' ||
7544 round(l_pricing_parameters_tbl(1).trade_in,4) || ' | ' ||
7545 round(l_pricing_parameters_tbl(1).subsidy,4) );
7546 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7547 ' Financed Amount ' || round(l_net_financed_amount,4) || ' Total Percentage of Financial Adjustments ' || round(l_net_percent,4)
7548 || ' Total Adjustment Amount (FIXED)= ' || round( l_net_adj_amt, 4));
7549 IF l_hdr_rec.pricing_method = 'SFP'
7550 THEN
7551 l_pricing_parameters_tbl(1).financed_amount :=
7552 ( (l_closing_balance + l_net_adj_amt) /
7553 ( 1- (l_net_percent/100) - (l_residual_percent/l_residual_int_factor) ) );
7554 ELSIF l_hdr_rec.pricing_method = 'SF'
7555 THEN
7556 -- Find the Asset Cost C = F+[S++D+T]/(1-[S'+D'+T']/100)
7557 -- S,D,T are fixed financial adjustment amounts
7558 l_pricing_parameters_tbl(1).financed_amount := l_net_financed_amount / ( 1- l_net_percent / 100 );
7559 END IF;
7560 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7561 ' !!!! Asset Cost should be ' || l_pricing_parameters_tbl(1).financed_amount );
7562 IF l_net_percent > 0 AND
7563 l_net_percent <= 100
7564 THEN
7565 IF l_fin_adj_rec.down_payment_basis <> 'FIXED'
7566 THEN
7567 l_pricing_parameters_tbl(1).down_payment :=
7568 l_pricing_parameters_tbl(1).financed_amount * l_fin_adj_rec.down_payment_value/ 100;
7569 END IF;
7570 IF l_fin_adj_rec.tradein_basis <> 'FIXED'
7571 THEN
7572 l_pricing_parameters_tbl(1).trade_in := l_pricing_parameters_tbl(1).financed_amount
7573 * l_fin_adj_rec.tradein_value / 100;
7574 END IF;
7575 IF l_fin_adj_rec.subsidy_basis_tbl.COUNT > 0
7576 THEN
7577 FOR t IN l_fin_adj_rec.subsidy_basis_tbl.FIRST ..
7578 l_fin_adj_rec.subsidy_basis_tbl.LAST
7579 LOOP
7580 IF l_fin_adj_rec.subsidy_basis_tbl(t) <> 'FIXED'
7581 THEN
7582 l_pricing_parameters_tbl(1).subsidy := l_pricing_parameters_tbl(1).subsidy +
7583 ( l_pricing_parameters_tbl(1).financed_amount * l_fin_adj_rec.subsidy_value_tbl(t));
7584 END IF;
7585 END LOOP;
7586 END IF; -- If subsidies exists
7587 END IF;
7588 IF l_hdr_rec.pricing_method = 'SFP'
7589 THEN
7590 -- Still the calculation need to be done ..
7591 -- After pricing the EOT has to be calculated interms of amounts
7592 -- for pricing to calculate the yields further.
7593 FOR t_in IN l_pricing_parameters_tbl(1).residual_inflows.FIRST ..
7594 l_pricing_parameters_tbl(1).residual_inflows.LAST
7595 LOOP
7596 l_pricing_parameters_tbl(1).residual_inflows(t_in).cf_amount :=
7597 l_pricing_parameters_tbl(1).residual_inflows(t_in).cf_amount *
7598 l_pricing_parameters_tbl(1).financed_amount;
7599 END LOOP;
7600 END IF;
7601 END IF; -- IF pricing_method ='SF'/'SFP'
7602 -- If pricing method is RC, calculate the total Rent Payment amount, which
7603 -- needs to be passed in the get_fee_srvc_cash_flows
7604 -- Get the Total Rent Payment Amount
7605 -- For this loop through all the pricing params with line_type as FREE_FORM1
7606 -- and sumup the streams being passed there !
7607 l_tot_rent_payment := 0;
7608 FOR a IN l_pricing_parameters_tbl.FIRST .. l_pricing_parameters_tbl.LAST
7609 LOOP
7610 IF l_pricing_parameters_tbl(a).line_type = 'FREE_FORM1'
7611 THEN
7612 FOR b IN l_pricing_parameters_tbl(a).cash_inflows.FIRST ..
7613 l_pricing_parameters_tbl(a).cash_inflows.LAST
7614 LOOP
7615 l_tot_rent_payment := l_tot_rent_payment + nvl(l_pricing_parameters_tbl(a).cash_inflows(b).cf_amount, 0);
7616 END LOOP;
7617 END IF;
7618 END LOOP;
7619 ------------------------------------
7620 -- Get the Fee or Service Parameters
7621 ------------------------------------
7622 get_fee_srvc_cash_flows(
7623 p_api_version => p_api_version,
7624 p_init_msg_list => p_init_msg_list,
7625 x_return_status => l_return_status,
7626 x_msg_count => x_msg_count,
7627 x_msg_data => x_msg_data,
7628 p_hdr_rec => l_hdr_rec,
7629 p_tot_item_cat_cost => l_tot_item_cat_amount,
7630 p_tot_rent_payment => l_tot_rent_payment,
7631 x_fee_srv_tbl => l_fee_srv_tbl);
7632 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7633 'After get_fee_srvc_cash_flows ' || l_return_status );
7634 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7635 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7636 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7637 RAISE OKL_API.G_EXCEPTION_ERROR;
7638 END IF;
7639 -- Now need to loop through the l_fee_srv_tbl, generate streams if needed
7640 -- and accumulate the streams in the l_pricing_parameters_tbl !!
7641 IF l_fee_srv_tbl.COUNT > 0
7642 THEN
7643 FOR t_index IN l_fee_srv_tbl.FIRST .. l_fee_srv_tbl.LAST
7644 LOOP
7645 -- Populate the line_type, payment_type and streams in the
7646 -- l_pricing_parameters_tbl
7647 l_pricing_parameters_tbl(pp_index).line_type := l_fee_srv_tbl(t_index).type;
7648 -- Populate either INCOME / EXPENSE as a value for the payment_type !
7649 IF l_fee_srv_tbl(t_index).type = G_QQ_FEE_EXPENSE
7650 THEN
7651 l_pricing_parameters_tbl(pp_index).payment_type := 'EXPENSE';
7652 ELSIF l_fee_srv_tbl(t_index).TYPE = G_QQ_FEE_PAYMENT
7653 THEN
7654 l_pricing_parameters_tbl(pp_index).payment_type := 'INCOME';
7655 END IF;
7656 -- Start date for the line will be the quote expected start date
7657 l_pricing_parameters_tbl(pp_index).line_start_date :=l_hdr_rec.expected_start_date;
7658 l_pricing_parameters_tbl(pp_index).financed_amount := 0;
7659 -- Generate the streams .. using the corresponding cash flows and levels
7660 l_strm_ele_tbl.DELETE;
7661 IF l_fee_srv_tbl(t_index).cash_flow_level_tbl IS NOT NULL AND
7662 l_fee_srv_tbl(t_index).cash_flow_level_tbl.COUNT > 0
7663 THEN
7664 -- Initialize the Strm Count to Zero
7665 gen_so_cf_strms(
7666 p_api_version => p_api_version,
7667 p_init_msg_list => p_init_msg_list,
7668 x_return_status => l_return_status,
7669 x_msg_count => x_msg_count,
7670 x_msg_data => x_msg_data,
7671 p_cash_flow_rec => l_fee_srv_tbl(t_index).cash_flow_rec,
7672 p_cf_details_tbl => l_fee_srv_tbl(t_index).cash_flow_level_tbl,
7673 x_cash_inflow_strms_tbl => l_strm_ele_tbl);
7674 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7675 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7676 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7677 RAISE OKL_API.G_EXCEPTION_ERROR;
7678 END IF;
7679 END IF;
7680 -- Get the line_end_date from the last stream element generated !
7681 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7682 'After gen_so_cf_strms for fees ' || l_return_status );
7683 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7684 'Streams generated ' || l_strm_ele_tbl.COUNT );
7685 IF l_strm_ele_tbl IS NOT NULL AND
7686 l_strm_ele_tbl.COUNT > 0
7687 THEN
7688 IF l_strm_ele_tbl(l_strm_ele_tbl.LAST).is_arrears = 'N'
7689 THEN
7690 l_pricing_parameters_tbl(pp_index).line_end_date :=
7691 l_strm_ele_tbl(l_strm_ele_tbl.LAST).cf_period_start_end_date;
7692 ELSE
7693 l_pricing_parameters_tbl(pp_index).line_end_date :=
7694 l_strm_ele_tbl(l_strm_ele_tbl.LAST).cf_date;
7695 END IF;
7696 END IF;
7697 -- Assign the generated streams to the Pricing Parameters cash inflows table !
7698 l_pricing_parameters_tbl(pp_index).cash_inflows := l_strm_ele_tbl;
7699 -- Increment the pp_index
7700 pp_index := pp_index + 1;
7701 END LOOP; -- Loop on the l_fee_srv_tbl
7702 END IF; -- IF l_fee_srv_tbl.COUNT > 0
7703 -- Solve for the missing parameter using the IRR method if pricing method is
7704 -- Target Rate and Target Rate type is IRR
7705 IF ( l_hdr_rec.pricing_method = 'TR' AND
7706 l_hdr_rec.target_rate_type = 'PIRR' )
7707 THEN
7708 -- Check whether the interest picked is IIR or not??
7709 compute_irr(
7710 p_api_version => p_api_version,
7711 p_init_msg_list => p_init_msg_list,
7712 x_return_status => l_return_status,
7713 x_msg_count => x_msg_count,
7714 x_msg_data => x_msg_data,
7715 p_start_date => l_hdr_rec.expected_start_date,
7716 p_day_count_method => l_sgt_day_count_method,
7717 p_currency_code => l_hdr_rec.currency_code,
7718 p_pricing_method => l_hdr_rec.pricing_method,
7719 p_initial_guess => 0.1,
7720 px_pricing_parameter_tbl => l_pricing_parameters_tbl,
7721 px_irr => l_irr,
7722 x_payment => l_miss_payment);
7723 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7724 'After compute_irr ' || l_return_status );
7725 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7726 'SOLVED FOR TARGET-RATE (PIRR) ' || l_miss_payment );
7727 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7728 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7729 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7730 RAISE OKL_API.G_EXCEPTION_ERROR;
7731 END IF;
7732 IF l_miss_payment < 0
7733 THEN
7734 OKL_API.SET_MESSAGE (
7735 p_app_name => G_APP_NAME,
7736 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
7737 p_token1 => 'TYPE',
7738 p_token1_value => 'Payment',
7739 p_token2 => 'AMOUNT',
7740 p_token2_value => round(l_miss_payment,2) );
7741 RAISE okl_api.g_exception_error;
7742 END IF;
7743 END IF; -- Pricing method IF
7744 -- In case of the Pricing Method is SP...
7745 -- populate back the missing amount into the Cash Inflow Levels and the Streams too..
7746 -- for further solving for Yields
7747 IF l_hdr_rec.pricing_method = 'SP' OR
7748 l_hdr_rec.pricing_method = 'TR'
7749 THEN
7750 FOR i in l_strm_ele_tbl.FIRST .. l_strm_ele_tbl.LAST
7751 LOOP
7752 l_strm_ele_tbl(i).cf_amount := l_miss_payment;
7753 END LOOP;
7754 -- Need to populate back the Cash flow details, which will be
7755 -- returned back to the wrapper API !!
7756 FOR i in l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
7757 LOOP
7758 l_cash_flow_det_tbl(i).amount := l_miss_payment;
7759 END LOOP;
7760 -- Need to populate back the Cash inflows with the solved Amount for the FREE_FORM1 lines
7761 FOR i_index IN l_pricing_parameters_tbl.FIRST ..
7762 l_pricing_parameters_tbl.LAST
7763 LOOP
7764 FOR j_index IN l_pricing_parameters_tbl(i_index).cash_inflows.FIRST ..
7765 l_pricing_parameters_tbl(i_index).cash_inflows.LAST
7766 LOOP
7767 IF l_pricing_parameters_tbl(i_index).line_type = 'FREE_FORM1'
7768 THEN
7769 l_pricing_parameters_tbl(i_index).cash_inflows(j_index).cf_amount := l_miss_payment;
7770 END IF;
7771 END LOOP;
7772 END LOOP;
7773 -- Commenting the below code becasue, when QQ is being priced for TR[IRR],
7774 -- User will give the Fee Expense/Fee Payment amount, Pricing should not actually change that amounts
7775 /*
7776 -- Need to populate back the Cash flows into all the streams table back ..
7777 IF l_hdr_rec.target_rate_type = 'PIRR' AND
7778 l_fee_srv_tbl.COUNT > 0
7779 THEN
7780 FOR i_index IN l_fee_srv_tbl.FIRST .. l_fee_srv_tbl.LAST
7781 LOOP
7782 FOR j_index IN l_fee_srv_tbl(i_index).cash_flow_level_tbl.FIRST ..
7783 l_fee_srv_tbl(i_index).cash_flow_level_tbl.LAST
7784 LOOP
7785 l_fee_srv_tbl(i_index).cash_flow_level_tbl(j_index).amount := l_miss_payment;
7786 END LOOP;
7787 END LOOP;
7788 END IF;
7789 */
7790 END IF;
7791 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7792 '--------------------------------------------------------------------------');
7793 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7794 ' -- Subsidized Yields calculation');
7795 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7796 '--------------------------------------------------------------------------');
7797 -- Get the Total Item Categories cost
7798 IF l_hdr_rec.pricing_method = 'SF' OR
7799 l_hdr_rec.pricing_method = 'SFP'
7800 THEN
7801 -- The total financed amount would have been solved the compute_iir api
7802 -- and has been returned in l_pricing_parameters_tbl(1).financed_amount
7803 l_tot_item_cat_amount := l_pricing_parameters_tbl(1).financed_amount;
7804 END IF;
7805 -- When the pricing method is 'RC', we would have directly come to here
7806 -- as Rate Card method pricing is very similiar to the SY pricing method.
7807 -- 'Coz we have already calculated the payment amounts based on the
7808 -- Lease Rate Factor levels
7809 IF l_hdr_rec.pricing_method = 'TR' AND
7810 l_hdr_rec.target_rate_type = 'IIR'
7811 THEN
7812 l_iir := l_hdr_rec.target_rate /100;
7813 ELSE
7814 -- Calculate IIR
7815 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7816 'Subsidized IIR Calculation ------------------' );
7817 -- We will be calling the compute_irr with just the item cat. information
7818 -- and its residual streams .. ignoring fees and fee payments
7819 IF l_hdr_rec.pricing_method = 'RC'
7820 THEN
7821 -- We need to pass the pricing params corresponding to only the
7822 -- item categories leaving the Fee and else !
7823 FOR t IN 1 .. l_tmp_pp_index
7824 LOOP
7825 l_tmp_prc_params_tbl(t) := l_pricing_parameters_tbl(t);
7826 END LOOP;
7827 ELSE
7828 l_tmp_prc_params_tbl(1) := l_pricing_parameters_tbl(1);
7829 END IF;
7830 compute_irr(
7831 p_api_version => p_api_version,
7832 p_init_msg_list => p_init_msg_list,
7833 x_return_status => l_return_status,
7834 x_msg_count => x_msg_count,
7835 x_msg_data => x_msg_data,
7836 p_start_date => l_hdr_rec.expected_start_date,
7837 p_day_count_method => l_day_count_method,
7838 p_currency_code => l_hdr_rec.currency_code,
7839 p_pricing_method => 'SY',
7840 p_initial_guess => 0.1,
7841 px_pricing_parameter_tbl => l_tmp_prc_params_tbl,
7842 px_irr => l_iir,
7843 x_payment => l_miss_payment);
7844 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7845 '1/ After compute_iir ' || l_return_status );
7846 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7847 'SOLVED FOR IIR ' || l_iir );
7848 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7849 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7850 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7851 RAISE OKL_API.G_EXCEPTION_ERROR;
7852 END IF;
7853 -- Store back the pricing params record in l_pricing_parameters_tbl
7854 IF l_hdr_rec.pricing_method = 'RC'
7855 THEN
7856 FOR t IN 1 .. l_tmp_pp_index
7857 LOOP
7858 l_pricing_parameters_tbl(t) := l_tmp_prc_params_tbl(t);
7859 END LOOP;
7860 ELSE
7861 l_pricing_parameters_tbl(1) := l_tmp_prc_params_tbl(1);
7862 END IF;
7863 END IF; -- IF l_hdr_rec.pricing_mthod = 'TR' and l_hdr_rec.target_rate_type = 'IIR'
7864 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7865 'Subsidized IRR Calculation ------------------' );
7866 IF l_hdr_rec.pricing_method = 'TR' AND
7867 l_hdr_rec.target_rate_type = 'PIRR'
7868 THEN
7869 l_irr := l_hdr_rec.target_rate / 100;
7870 ELSE
7871 -- Calculate the IRR !
7872 compute_irr(
7873 p_api_version => p_api_version,
7874 p_init_msg_list => p_init_msg_list,
7875 x_return_status => l_return_status,
7876 x_msg_count => x_msg_count,
7877 x_msg_data => x_msg_data,
7878 p_start_date => l_hdr_rec.expected_start_date,
7879 p_day_count_method => l_sgt_day_count_method,
7880 p_currency_code => l_hdr_rec.currency_code,
7881 p_pricing_method => 'SY',
7882 p_initial_guess => l_iir,
7883 px_pricing_parameter_tbl => l_pricing_parameters_tbl,
7884 px_irr => l_irr,
7885 x_payment => l_miss_payment);
7886 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7887 'After compute_irr ' || l_return_status );
7888 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7889 'px_irr ' || l_irr );
7890 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7891 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7892 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7893 RAISE OKL_API.G_EXCEPTION_ERROR;
7894 END IF;
7895 END IF; -- IF l_hdr_rec.pricing_method = 'TR' AND l_hdr_rec.target_rate_type = 'PIRR'
7896 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7897 'Subsidized Booking Yield Calculation ' );
7898 IF l_hdr_rec.pricing_method = 'RC'
7899 THEN
7900 -- Store the IIR @ QQ level as the Booking Yield
7901 l_bk_yield := l_iir;
7902 ELSE
7903 -- Compute the Booking Yield
7904 l_bk_yield := l_iir;
7905 /*
7906 compute_bk_yield(
7907 p_api_version => p_api_version,
7908 p_init_msg_list => p_init_msg_list,
7909 x_return_status => l_return_status,
7910 x_msg_count => x_msg_count,
7911 x_msg_data => x_msg_data,
7912 p_start_date => l_hdr_rec.expected_start_date,
7913 p_day_count_method => l_day_count_method,
7914 p_pricing_method => 'SY',
7915 p_initial_guess => l_iir,
7916 p_term => l_hdr_rec.term,
7917 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
7918 x_bk_yield => l_bk_yield,
7919 x_termination_tbl => x_termination_tbl,
7920 x_pre_tax_inc_tbl => x_pre_tax_inc_tbl);
7921 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7922 'After compute_bk_yield ' || l_return_status );
7923 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7924 'x_bk_yield ' || l_bk_yield );
7925 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7926 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7927 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7928 RAISE OKL_API.G_EXCEPTION_ERROR;
7929 END IF;
7930 */
7931 END IF;
7932 -- Need to store the Subsidized Yields into l_subsized_yileds_rec
7933 -- ISG doesnot calculate yet the after_tax_irr
7934 l_subsidized_yields_rec.pre_tax_irr := l_irr;
7935 l_subsidized_yields_rec.iir := l_iir;
7936 l_subsidized_yields_rec.bk_yield := l_bk_yield;
7937 -- Storing the l_pricing_parameters_tbl into l_pricing_parameters_tbl_cp
7938 -- which will be useful during returning back of the pricing params ..
7939 l_pricing_parameters_tbl_cp := l_pricing_parameters_tbl;
7940 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7941 'Computed Subsidized Yields successfully ' );
7942 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7943 'Pre_Tax_IRR | IIR | Boooking Yield ' );
7944 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7945 round( l_subsidized_yields_rec.pre_tax_irr , 4 ) || ' | '
7946 || round( l_subsidized_yields_rec.iir , 4 ) || ' | '
7947 ||round( l_subsidized_yields_rec.bk_yield, 4 ) );
7948 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7949 '-------------------------------------------------------------');
7950 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7951 ' -- Calculation of the Yields ');
7952 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
7953 '-------------------------------------------------------------');
7954 -- Dont consider any subsidy amount here !!
7955 FOR t_index IN l_pricing_parameters_tbl.FIRST .. l_pricing_parameters_tbl.LAST
7956 LOOP
7957 -- Remove the subsidy amount, normal yeilds calculation shouldnot consider
7958 -- subsidy amount as an inflow
7959 l_pricing_parameters_tbl(t_index).subsidy := 0;
7960 END LOOP;
7961 -- Calculate the IIR
7962 -- API being called is compute_irr but without passing any of the
7963 -- fees and fee payments info. from the QQ
7964 l_tmp_prc_params_tbl.DELETE;
7965 IF l_hdr_rec.pricing_method = 'RC'
7966 THEN
7967 -- We need to pass the pricing params corresponding to only the
7968 -- item categories leaving the Fee and else !
7969 FOR t IN 1 .. l_tmp_pp_index
7970 LOOP
7971 l_tmp_prc_params_tbl(t) := l_pricing_parameters_tbl(t);
7972 END LOOP;
7973 ELSE
7974 l_tmp_prc_params_tbl(1) := l_pricing_parameters_tbl(1);
7975 END IF;
7976 compute_irr(
7977 p_api_version => p_api_version,
7978 p_init_msg_list => p_init_msg_list,
7979 x_return_status => l_return_status,
7980 x_msg_count => x_msg_count,
7981 x_msg_data => x_msg_data,
7982 p_start_date => l_hdr_rec.expected_start_date,
7983 p_day_count_method => l_day_count_method,
7984 p_currency_code => l_hdr_rec.currency_code,
7985 p_pricing_method => 'SY',
7986 p_initial_guess => l_subsidized_yields_rec.iir,
7987 px_pricing_parameter_tbl => l_tmp_prc_params_tbl,
7988 px_irr => l_iir,
7989 x_payment => l_miss_payment);
7990 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7991 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7992 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
7993 RAISE OKL_API.G_EXCEPTION_ERROR;
7994 END IF;
7995 -- Store back the pricing params ..
7996 IF l_hdr_rec.pricing_method = 'RC'
7997 THEN
7998 FOR t IN 1 .. l_tmp_pp_index
7999 LOOP
8000 l_pricing_parameters_tbl(t) := l_tmp_prc_params_tbl(t);
8001 END LOOP;
8002 ELSE
8003 l_pricing_parameters_tbl(1) := l_tmp_prc_params_tbl(1);
8004 END IF;
8005 -- Calculate the IRR !
8006 compute_irr(
8007 p_api_version => p_api_version,
8008 p_init_msg_list => p_init_msg_list,
8009 x_return_status => l_return_status,
8010 x_msg_count => x_msg_count,
8011 x_msg_data => x_msg_data,
8012 p_start_date => l_hdr_rec.expected_start_date,
8013 p_day_count_method => l_sgt_day_count_method,
8014 p_currency_code => l_hdr_rec.currency_code,
8015 p_pricing_method => 'SY',
8016 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr,
8017 px_pricing_parameter_tbl => l_pricing_parameters_tbl,
8018 px_irr => l_irr,
8019 x_payment => l_miss_payment);
8020 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8021 'After compute_irr ' || l_return_status );
8022 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8023 'px_irr ' || l_irr );
8024 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8025 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8026 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8027 RAISE OKL_API.G_EXCEPTION_ERROR;
8028 END IF;
8029 IF l_hdr_rec.pricing_method = 'RC'
8030 THEN
8031 -- Store the IIR as the Booking Yield @ the QQ level
8032 l_bk_yield := l_iir;
8033 ELSE
8034 -- Compute the Booking Yield
8035 l_bk_yield := l_iir;
8036 /*
8037 compute_bk_yield(
8038 p_api_version => p_api_version,
8039 p_init_msg_list => p_init_msg_list,
8040 x_return_status => l_return_status,
8041 x_msg_count => x_msg_count,
8042 x_msg_data => x_msg_data,
8043 p_start_date => l_hdr_rec.expected_start_date,
8044 p_day_count_method => l_day_count_method,
8045 p_pricing_method => 'SY',
8046 p_initial_guess => l_subsidized_yields_rec.bk_yield,
8047 p_term => l_hdr_rec.term,
8048 px_pricing_parameter_rec => l_pricing_parameters_tbl(1),
8049 x_bk_yield => l_bk_yield,
8050 x_termination_tbl => x_termination_tbl,
8051 x_pre_tax_inc_tbl => x_pre_tax_inc_tbl);
8052 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'After compute_bk_yield ' || l_return_status );
8053 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S', 'x_bk_yield ' || l_bk_yield );
8054 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8055 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8056 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8057 RAISE OKL_API.G_EXCEPTION_ERROR;
8058 END IF;
8059 */
8060 END IF;
8061 -- ISG doesnot calculate the after_tax_irr yet
8062 l_yields_rec.pre_tax_irr := l_irr;
8063 l_yields_rec.iir := l_iir;
8064 l_yields_rec.bk_yield := l_bk_yield;
8065 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8066 '---------------------------------------------------' );
8067 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8068 'Yields ' );
8069 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8070 '---------------------------------------------------' );
8071 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8072 'Pre_Tax_IRR | IIR | Boooking Yield ' );
8073 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8074 round( l_yields_rec.pre_tax_irr , 4 ) || ' | ' || round( l_yields_rec.iir , 4 ) || ' | '
8075 ||round( l_yields_rec.bk_yield, 4 ) );
8076 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8077 '---------------------------------------------------' );
8078 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8079 'Subsidized Yields ' );
8080 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8081 '---------------------------------------------------' );
8082 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8083 'Pre_Tax_IRR | IIR | Boooking Yield ' );
8084 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8085 round( l_subsidized_yields_rec.pre_tax_irr , 4 ) || ' | '
8086 || round( l_subsidized_yields_rec.iir , 4 ) || ' | '
8087 ||round( l_subsidized_yields_rec.bk_yield, 4 ) );
8088 -- Need to calculate a quote API to update the Yields and Subsidized yields !
8089 -- Call the API which changes the status of the QQ !
8090 -- Actual logic Ends here
8091 x_yileds_rec := l_yields_rec;
8092 x_subsidized_yileds_rec := l_subsidized_yields_rec;
8093 -- Need to populate back the pricing results using the x_pricing_results_tbl ....
8094 i := 1;
8095 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8096 ' ************** PRICING ENGINE RETURN VALUES: ************** ' );
8097 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8098 'Line Type | Asset Cost | Down Payment | Trade In | Subsidy ' );
8099 IF l_hdr_rec.pricing_method = 'RC'
8100 THEN
8101 -- Loop through the l_item_cat_cf_tbl and then return the pricing results
8102 FOR t in l_item_cat_cf_tbl.FIRST .. l_item_cat_cf_tbl.LAST
8103 LOOP
8104 x_pricing_results_tbl(i).line_type := 'FREE_FORM1';
8105 x_pricing_results_tbl(i).line_id := l_item_cat_cf_tbl(t).line_id;
8106 x_pricing_results_tbl(i).item_category_id := l_item_cat_cf_tbl(t).item_category_id;
8107 x_pricing_results_tbl(i).financed_amount := l_item_cat_cf_tbl(t).financed_amount;
8108 x_pricing_results_tbl(i).trade_in := l_item_cat_cf_tbl(t).trade_in;
8109 x_pricing_results_tbl(i).down_payment := l_item_cat_cf_tbl(t).down_payment;
8110 x_pricing_results_tbl(i).subsidy := l_item_cat_cf_tbl(t).subsidy;
8111 x_pricing_results_tbl(i).cash_flow_rec := l_item_cat_cf_tbl(t).cash_flow_rec;
8112 x_pricing_results_tbl(i).cash_flow_level_tbl := l_item_cat_cf_tbl(t).cash_flow_level_tbl;
8113 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8114 x_pricing_results_tbl(1).line_type || ' | ' ||
8115 round(x_pricing_results_tbl(i).financed_amount, 4) || ' | ' ||
8116 round(x_pricing_results_tbl(i).down_payment, 4) || ' | ' ||
8117 round(x_pricing_results_tbl(i).trade_in, 4) || ' | ' ||
8118 round(x_pricing_results_tbl(i).subsidy, 4) ) ;
8119 IF x_pricing_results_tbl(i).cash_flow_level_tbl.COUNT > 0 AND
8120 x_pricing_results_tbl(i).cash_flow_level_tbl IS NOT NULL
8121 THEN
8122 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8123 ' Cash Flow Level details ' );
8124 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8125 ' Rate | Start Date | Frequency | Arrears Y/N | | Stub Days | Stub Amount | Periods | Periodic Amount ' );
8126 FOR t_in IN x_pricing_results_tbl(i).cash_flow_level_tbl.FIRST ..
8127 x_pricing_results_tbl(i).cash_flow_level_tbl.LAST
8128 LOOP
8129 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8130 ' ' || x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).rate || ' | ' ||
8131 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).START_DATE || ' | ' ||
8132 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).fqy_code || ' | ' ||
8133 x_pricing_results_tbl(i).cash_flow_rec.due_arrears_yn || ' | ' ||
8134 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_days || ' | ' ||
8135 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_amount || ' | ' ||
8136 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).number_of_periods || ' | ' ||
8137 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).amount );
8138 END LOOP;
8139 END IF;
8140 -- Increment i
8141 i := i + 1;
8142 END LOOP;
8143 ELSE
8144 -- The first pricing param will be the FREE_FORM1 line only ..
8145 -- in case of the pricing method is not RC.
8146 x_pricing_results_tbl(i).line_type := l_pricing_parameters_tbl_cp(1).line_type;
8147 x_pricing_results_tbl(i).financed_amount := l_pricing_parameters_tbl_cp(1).financed_amount;
8148 x_pricing_results_tbl(i).trade_in := l_pricing_parameters_tbl_cp(1).trade_in;
8149 x_pricing_results_tbl(i).down_payment := l_pricing_parameters_tbl_cp(1).down_payment;
8150 x_pricing_results_tbl(i).subsidy := l_pricing_parameters_tbl_cp(1).subsidy;
8151 x_pricing_results_tbl(i).cash_flow_rec := l_cash_flow_rec;
8152 x_pricing_results_tbl(i).cash_flow_level_tbl := l_cash_flow_det_tbl;
8153 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8154 x_pricing_results_tbl(1).line_type || ' | ' ||
8155 round(x_pricing_results_tbl(1).financed_amount, 4) || ' | ' ||
8156 round(x_pricing_results_tbl(1).down_payment, 4) || ' | ' ||
8157 round(x_pricing_results_tbl(1).trade_in, 4) || ' | ' ||
8158 round(x_pricing_results_tbl(1).subsidy, 4) ) ;
8159 IF x_pricing_results_tbl(i).cash_flow_level_tbl.COUNT > 0 AND
8160 x_pricing_results_tbl(i).cash_flow_level_tbl IS NOT NULL
8161 THEN
8162 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8163 ' Cash Flow Level details ' );
8164 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8165 ' Rate | Start Date | Frequency | Arrears Y/N | | Stub Days | Stub Amount | Periods | Periodic Amount ' );
8166 FOR t_in IN x_pricing_results_tbl(i).cash_flow_level_tbl.FIRST ..
8167 x_pricing_results_tbl(i).cash_flow_level_tbl.LAST
8168 LOOP
8169 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8170 ' ' || x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).rate || ' | ' ||
8171 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).START_DATE || ' | ' ||
8172 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).fqy_code || ' | ' ||
8173 x_pricing_results_tbl(i).cash_flow_rec.due_arrears_yn || ' | ' ||
8174 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_days || ' | ' ||
8175 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_amount || ' | ' ||
8176 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).number_of_periods || ' | ' ||
8177 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).amount );
8178 END LOOP;
8179 END IF;
8180 --Increment i ..
8181 i := i + 1;
8182 END IF;
8183 -- Need to return back the expense and fee payment cash flows !
8184 IF l_fee_srv_tbl.COUNT > 0
8185 THEN
8186 FOR t IN l_fee_srv_tbl.FIRST .. l_fee_srv_tbl.LAST
8187 LOOP
8188 x_pricing_results_tbl(i).line_type := l_fee_srv_tbl(t).type;
8189 x_pricing_results_tbl(i).financed_amount := NULL;
8190 x_pricing_results_tbl(i).trade_in := NULL;
8191 x_pricing_results_tbl(i).down_payment := NULL;
8192 x_pricing_results_tbl(i).subsidy := NULL;
8193 x_pricing_results_tbl(i).cash_flow_rec := l_fee_srv_tbl(t).cash_flow_rec;
8194 x_pricing_results_tbl(i).cash_flow_level_tbl := l_fee_srv_tbl(t).cash_flow_level_tbl;
8195 IF x_pricing_results_tbl(i).cash_flow_level_tbl.COUNT > 0 AND
8196 x_pricing_results_tbl(i).cash_flow_level_tbl IS NOT NULL
8197 THEN
8198 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8199 ' Cash Flow Level details for LINE_TYPE ' || x_pricing_results_tbl(i).line_type );
8200 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8201 ' Rate | Start Date | Frequency | Arrears Y/N | | Stub Days | Stub Amount | Periods | Periodic Amount ' );
8202 FOR t_in IN x_pricing_results_tbl(i).cash_flow_level_tbl.FIRST ..
8203 x_pricing_results_tbl(i).cash_flow_level_tbl.LAST
8204 LOOP
8205 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8206 ' ' || x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).rate || ' | ' ||
8207 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).START_DATE || ' | ' ||
8208 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).fqy_code || ' | ' ||
8209 x_pricing_results_tbl(i).cash_flow_rec.due_arrears_yn || ' | ' ||
8210 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_days || ' | ' ||
8211 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).stub_amount || ' | ' ||
8212 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).number_of_periods || ' | ' ||
8213 x_pricing_results_tbl(i).cash_flow_level_tbl(t_in).amount );
8214 END LOOP;
8215 END IF;
8216 -- Increment i !
8217 i := i + 1;
8218 END LOOP;
8219 END IF;
8220 x_return_status := l_return_status;
8221 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
8222 x_msg_data => x_msg_data);
8223 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8224 'end debug OKLRPIUB.pls call ' || LOWER(l_api_name) );
8225 EXCEPTION
8226 WHEN OKL_API.G_EXCEPTION_ERROR THEN
8227 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8228 p_api_name => l_api_name,
8229 p_pkg_name => G_PKG_NAME,
8230 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
8231 x_msg_count => x_msg_count,
8232 x_msg_data => x_msg_data,
8233 p_api_type => g_api_type);
8234 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
8235 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8236 p_api_name => l_api_name,
8237 p_pkg_name => G_PKG_NAME,
8238 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
8239 x_msg_count => x_msg_count,
8240 x_msg_data => x_msg_data,
8241 p_api_type => g_api_type);
8242 WHEN OTHERS THEN
8243 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8244 p_api_name => l_api_name,
8245 p_pkg_name => G_PKG_NAME,
8246 p_exc_name => 'OTHERS',
8247 x_msg_count => x_msg_count,
8248 x_msg_data => x_msg_data,
8249 p_api_type => g_api_type);
8250 END price_quick_quote;
8251
8252 PROCEDURE distribute_fin_amount_lq(
8253 p_api_version IN NUMBER,
8254 p_init_msg_list IN VARCHAR2,
8255 x_return_status OUT NOCOPY VARCHAR2,
8256 x_msg_count OUT NOCOPY NUMBER,
8257 x_msg_data OUT NOCOPY VARCHAR2,
8258 p_lq_id IN NUMBER,
8259 p_tot_fin_amount IN NUMBER)
8260 IS
8261 -- Local Variables
8262 l_api_version CONSTANT NUMBER DEFAULT 1.0;
8263 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'distribute_fin_amount_lq';
8264 l_return_status VARCHAR2(1);
8265 l_module CONSTANT fnd_log_messages.module%TYPE :=
8266 'LEASE.ACCOUNTING.PRICING.OKL_PRICING_UTILS_PVT.distribute_fin_amount_lq';
8267 l_debug_enabled VARCHAR2(10);
8268 is_debug_procedure_on BOOLEAN;
8269 is_debug_statement_on BOOLEAN;
8270 -- Cursor to fetch the Lease Quote Header details
8271 CURSOR quote_csr(qteid NUMBER)
8272 IS
8273 SELECT qte.pricing_method pricing_method,
8274 qte.rate_template_id rate_template_id,
8275 qte.structured_pricing structured_pricing,
8276 qte.line_level_pricing line_level_pricing,
8277 qte.target_arrears_yn target_arrears
8278 FROM OKL_LEASE_QUOTES_B qte
8279 WHERE qte.id = qteid;
8280 quote_rec quote_csr%ROWTYPE;
8281 -- Cursor to fetch the Assets Details for a Lease Quote
8282 -- and SRT attached to the Asset ( if any .. )
8283 CURSOR assets_csr(qteid NUMBER)
8284 IS
8285 SELECT ast.id ast_id,
8286 ast.asset_number asset_number,
8287 ast.oec oec,
8288 ast.oec_percentage oec_percentage,
8289 ast.structured_pricing structured_pricing,
8290 ast.rate_template_id rate_template_id,
8291 ast.target_arrears target_arrears
8292 FROM okl_assets_b ast,
8293 okl_lease_quotes_b qte
8294 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
8295 ast.parent_object_id = qte.id AND
8296 qte.id = qteid;
8297 CURSOR c_asset_comp_csr( p_asset_id NUMBER) IS
8298 SELECT
8299 id
8300 ,primary_component
8301 ,unit_cost
8302 ,number_of_units
8303 FROM okl_asset_components_v
8304 WHERE asset_id = p_asset_id
8305 AND primary_component = 'YES';
8306
8307 -- Local Variables Declaration !
8308 l_overridden BOOLEAN;
8309 tot_oec_percentage NUMBER;
8310 i NUMBER;
8311 lq_level_fin_amt NUMBER;
8312 l_asset_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_tbl_type;
8313 l_component_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_component_tbl_type;
8314 l_cf_hdr_rec OKL_LEASE_QUOTE_ASSET_PVT.cashflow_hdr_rec_type;
8315 l_cf_level_tbl OKL_LEASE_QUOTE_ASSET_PVT.cashflow_level_tbl_type;
8316 BEGIN
8317 l_return_status := OKL_API.G_RET_STS_SUCCESS;
8318 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
8319 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
8320 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8321 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
8322 -- check for logging on STATEMENT level
8323 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
8324 l_return_status := OKL_API.START_ACTIVITY(
8325 p_api_name => l_api_name,
8326 p_pkg_name => G_PKG_NAME,
8327 p_init_msg_list => p_init_msg_list,
8328 l_api_version => l_api_version,
8329 p_api_version => p_api_version,
8330 p_api_type => g_api_type,
8331 x_return_status => x_return_status);
8332 --Check if activity started successfully
8333 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8334 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8335 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8336 RAISE OKL_API.G_EXCEPTION_ERROR;
8337 END IF;
8338 -- Loop thu all the assets
8339 -- store the non-overriding assets id into assets_tbl
8340 -- sum the oec_percentage
8341 --end loop
8342 OPEN quote_csr( qteId => p_lq_id );
8343 FETCH quote_csr INTO quote_rec;
8344 CLOSE quote_csr;
8345
8346 tot_oec_percentage := 0;
8347 i := 1;
8348 FOR asset_rec IN assets_csr(qteid => p_lq_id )
8349 LOOP
8350 l_overridden := is_asset_overriding(
8351 p_qte_id => p_lq_id,
8352 p_ast_id => asset_rec.ast_id,
8353 p_lq_line_level_pricing => quote_rec.line_level_pricing,
8354 p_lq_srt_id => quote_rec.rate_template_id,
8355 p_ast_srt_id => asset_rec.rate_template_id,
8356 p_lq_struct_pricing => quote_rec.structured_pricing,
8357 p_ast_struct_pricing => asset_rec.structured_pricing,
8358 p_lq_arrears_yn => quote_rec.target_arrears,
8359 p_ast_arrears_yn => asset_rec.target_arrears,
8360 x_return_status => l_return_status);
8361 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8362 'After is_asset_overriding assets_rec.id =' || asset_rec.ast_id);
8363 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8364 ' l_return_status =' || l_return_status );
8365 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8366 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8367 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8368 RAISE OKL_API.G_EXCEPTION_ERROR;
8369 END IF;
8370 IF l_overridden = FALSE
8371 THEN
8372 -- Asset is following the Payment Structure defined at Lease quote ..
8373 tot_oec_percentage := tot_oec_percentage + nvl(asset_rec.oec_percentage,0);
8374 l_asset_tbl(i).id := asset_rec.ast_id;
8375 l_asset_tbl(i).oec_percentage := asset_rec.oec_percentage;
8376 -- Increment the index
8377 i := i + 1;
8378 END IF;
8379 END LOOP;
8380 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8381 'Sum(OEC %age) for non-overiding assets = ' || ROUND( tot_oec_percentage, 4));
8382 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8383 'assets_tbl = ' || l_asset_tbl.COUNT );
8384 IF l_asset_tbl.COUNT > 0
8385 THEN
8386 lq_level_fin_amt := p_tot_fin_amount * 100 / ( tot_oec_percentage );
8387 -- Loop through the assets_tbl and update the OEC of each asset !
8388 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8389 'Districution of Assets OEC ' );
8390 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8391 'Asset ID | Financed Amount ');
8392 FOR t IN l_asset_tbl.FIRST .. l_asset_tbl.LAST
8393 LOOP
8394 l_asset_tbl(t).oec := lq_level_fin_amt * l_asset_tbl(t).oec_percentage / 100;
8395 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8396 l_asset_tbl(t).id || ' | ' || l_asset_tbl(t).oec );
8397 l_component_tbl.DELETE;
8398 FOR t_rec IN c_asset_comp_csr( p_asset_id => l_asset_tbl(t).id )
8399 LOOP
8400 l_component_tbl(1).id := t_rec.id;
8401 l_component_tbl(1).unit_cost := l_asset_tbl(t).oec / t_rec.number_of_units;
8402 l_component_tbl(1).record_mode := 'update';
8403 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8404 'Updated l_component_tbl(1).unit_cost = ' || l_component_tbl(1).unit_cost );
8405 END LOOP;
8406 -- Call the update api to store back the calculated OEC of the Asset!
8407 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8408 'Before OKL_LEASE_QUOTE_ASSET_PVT.update_asset ');
8409 -- Instead we need to use the OKL_LEASE_QUOTE_ASSET_PVT.update_asset
8410 OKL_LEASE_QUOTE_ASSET_PVT.update_asset (
8411 p_api_version => p_api_version,
8412 p_init_msg_list => p_init_msg_list,
8413 p_transaction_control => 'T',
8414 p_asset_rec => l_asset_tbl(t),
8415 p_component_tbl => l_component_tbl,
8416 p_cf_hdr_rec => l_cf_hdr_rec,
8417 p_cf_level_tbl => l_cf_level_tbl,
8418 x_return_status => l_return_status,
8419 x_msg_count => x_msg_count,
8420 x_msg_data => x_msg_data);
8421 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8422 'After OKL_LEASE_QUOTE_ASSET_PVT.update_asset ' || l_return_status );
8423 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8424 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8425 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8426 RAISE OKL_API.G_EXCEPTION_ERROR;
8427 END IF;
8428 END LOOP;
8429 END IF;
8430 -- Logic ends here !
8431 x_return_status := l_return_status;
8432 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
8433 x_msg_data => x_msg_data);
8434 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8435 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
8436 EXCEPTION
8437 WHEN OKL_API.G_EXCEPTION_ERROR THEN
8438 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8439 p_api_name => l_api_name,
8440 p_pkg_name => G_PKG_NAME,
8441 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
8442 x_msg_count => x_msg_count,
8443 x_msg_data => x_msg_data,
8444 p_api_type => g_api_type);
8445 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
8446 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8447 p_api_name => l_api_name,
8448 p_pkg_name => G_PKG_NAME,
8449 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
8450 x_msg_count => x_msg_count,
8451 x_msg_data => x_msg_data,
8452 p_api_type => g_api_type);
8453 WHEN OTHERS THEN
8454 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
8455 p_api_name => l_api_name,
8456 p_pkg_name => G_PKG_NAME,
8457 p_exc_name => 'OTHERS',
8458 x_msg_count => x_msg_count,
8459 x_msg_data => x_msg_data,
8460 p_api_type => g_api_type);
8461 END distribute_fin_amount_lq;
8462
8463 --------------------------------------------------------------------------------
8464 -- Start of Commnets
8465 -- Procedure Name : price_standard_quote_asset
8466 -- Description : This API would have been called once for each asset
8467 -- which has overridden the Quote Level Pricing Structure !
8468 -- Business Rules :
8469 -- Parameters :
8470 -- Version : 1.0
8471 -- History : rgooty 22-May-2005 - created
8472 -- 1/ Added params p_price_at_lq_level
8473 -- When passed TRUE for p_price_at_lq_level, this api, will
8474 -- price the Asset, with the payment strucutre defined at the LQ level.
8475 -- Such senario, will be happening when the pricing_method is SP, and
8476 -- after we calculated the IIR at quote level, again, we will want to
8477 -- calculate the payments at each individual asset levels.
8478 -- p_target_rate will be passed as the IIR at the LQ Level.
8479 -- When p_price_at_lq_level is FALSE, then the Asset will be assumed
8480 -- to be overriding the payment structure defined at the LQ level.
8481 -- Hence, the Asset Level Cash flow Details will be fetched/defined ( incase of SRT )
8482 -- and the asset will be priced based on such information.
8483 -- 2/ Added, x_pricing_parameter_rec as an output parameter, because
8484 -- the price_standard_quote api can use the already built streams for this asset
8485 -- directly instead of it generating them again.
8486 -- End of Commnets
8487 --------------------------------------------------------------------------------
8488 PROCEDURE price_standard_quote_asset(
8489 x_return_status OUT NOCOPY VARCHAR2,
8490 x_msg_count OUT NOCOPY NUMBER,
8491 x_msg_data OUT NOCOPY VARCHAR2,
8492 p_api_version IN NUMBER,
8493 p_init_msg_list IN VARCHAR2,
8494 p_qte_id IN NUMBER,
8495 p_ast_id IN NUMBER, -- could be fee id.
8496 p_price_at_lq_level IN BOOLEAN,
8497 p_target_rate IN NUMBER,
8498 x_pricing_parameter_rec IN OUT NOCOPY pricing_parameter_rec_type)
8499 IS
8500 l_api_version CONSTANT NUMBER DEFAULT 1.0;
8501 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'price_standard_quote_asset';
8502 l_return_status VARCHAR2(1);
8503 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
8504 || G_PKG_NAME || '.' || UPPER(l_api_name);
8505
8506 l_debug_enabled VARCHAR2(10);
8507 is_debug_procedure_on BOOLEAN;
8508 is_debug_statement_on BOOLEAN;
8509
8510 CURSOR subsidy_adj_csr( subId NUMBER)
8511 IS
8512 SELECT amount
8513 FROM okl_subsidies_b
8514 WHERE id = subId;
8515
8516 subsidy_adj_rec subsidy_adj_csr%ROWTYPE;
8517
8518 -- Cursor to fetch the Lease Quote Header details
8519 CURSOR quote_csr(qteid NUMBER)
8520 IS
8521 SELECT qte.pricing_method pricing_method,
8522 qte.rate_template_id rate_template_id,
8523 qte.expected_start_date expected_start_date,
8524 qte.expected_delivery_date expected_delivery_date,
8525 qte.term term,
8526 qte.lease_rate_factor,
8527 qte.structured_pricing structured_pricing,
8528 qte.line_level_pricing line_level_pricing,
8529 qte.rate_card_id,
8530 qte.id,
8531 qte.parent_object_code,
8532 qte.target_frequency target_frequency,
8533 qte.target_arrears_yn target_arrears,
8534 qte.product_id,
8535 qte.sub_iir -- Yield used while calculating the payments @ Asset Level
8536 FROM OKL_LEASE_QUOTES_B qte
8537 WHERE qte.id = qteid;
8538 quote_rec quote_csr%ROWTYPE;
8539
8540 --Bug 5884825 PAGARG start
8541 --Cursor to fetch product name
8542 CURSOR product_name_csr(qteid NUMBER)
8543 IS
8544 SELECT PDT.NAME PRODUCTNAME
8545 FROM OKL_LEASE_QUOTES_B QTE
8546 , OKL_PRODUCTS PDT
8547 WHERE QTE.PRODUCT_ID = PDT.ID
8548 AND QTE.ID = QTEID;
8549 --Bug 5884825 PAGARG end
8550
8551 -- Local Variables Declaration
8552 l_product_name okl_products.NAME%TYPE;--Bug 5884825 PAGARG
8553 l_lrs_details lrs_details_rec_type;
8554 l_lrs_factor lrs_factor_rec_type;
8555 l_lrs_levels lrs_levels_tbl_type;
8556 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
8557 l_adj_factor NUMBER;
8558 l_months_per_period NUMBER;
8559 l_months_after NUMBER;
8560 cf_index NUMBER; -- Using as an index for Cash flow levels
8561 --Bug 5121548 dpsingh start
8562 --Cursor to fetch the Fees name for a Lease Quote
8563 CURSOR fees_csr(qteid NUMBER,
8564 fee_id NUMBER)
8565 IS
8566 SELECT stytl.name
8567 FROM okl_fees_b fee,
8568 okl_strm_type_tl stytl
8569 WHERE fee.parent_object_code = 'LEASEQUOTE'
8570 AND fee.parent_object_id = qteid
8571 AND fee.id = fee_id
8572 AND fee.STREAM_TYPE_ID = stytl.id
8573 AND stytl.LANGUAGE = USERENV('LANG');
8574 --Bug 5121548 dpsingh end
8575
8576 -- Cursor to fetch the Assets Details for a Lease Quote
8577 -- and SRT attached to the Asset ( if any .. )
8578 CURSOR assets_csr(qteid NUMBER,
8579 ast_fee_id NUMBER)
8580 IS
8581 SELECT ast.asset_number,
8582 ast.id ast_id,
8583 TO_NUMBER(NULL) fee_id,
8584 ast.rate_card_id,
8585 ast.rate_template_id rate_template_id,
8586 ast.structured_pricing,
8587 'FREE_FORM1' fee_type,
8588 TO_NUMBER(NULL) fee_amount,
8589 ast.lease_rate_factor lease_rate_factor,
8590 ast.asset_number name,
8591 ast.target_frequency target_frequency,
8592 ast.target_arrears target_arrears
8593 FROM okl_assets_b ast,
8594 okl_lease_quotes_b qte
8595 WHERE ast.parent_object_code = 'LEASEQUOTE'
8596 AND ast.parent_object_id = qte.id
8597 AND qte.id = qteid
8598 AND ast.id = ast_fee_id
8599 UNION
8600 SELECT NULL asset_number,
8601 TO_NUMBER(NULL) ast_id,
8602 fee.id fee_id,
8603 fee.rate_card_id,
8604 fee.rate_template_id,
8605 fee.structured_pricing,
8606 fee.fee_type,
8607 fee.fee_amount,
8608 fee.lease_rate_factor lease_rate_factor,
8609 fee.fee_type || ' FEE' name,
8610 fee.target_frequency target_frequency,
8611 fee.target_arrears target_arrears
8612 FROM okl_fees_b fee,
8613 okl_lease_quotes_b qte
8614 WHERE fee.parent_object_code = 'LEASEQUOTE'
8615 AND fee.parent_object_id = qte.id
8616 AND qte.id = qteid
8617 AND fee.id = ast_fee_id;
8618 assets_rec assets_csr%ROWTYPE;
8619 -- Cursor to fetch the Asset Level Details
8620 CURSOR asset_adj_csr(qteid NUMBER,
8621 astid NUMBER)
8622 IS
8623 SELECT ast.asset_number,
8624 ast.install_site_id,
8625 ast.rate_card_id,
8626 ast.rate_template_id,
8627 ast.oec,
8628 nvl(nvl(ast.end_of_term_value, ast.end_of_term_value_default),0) end_of_term_value,
8629 ast.oec_percentage,
8630 cmp.unit_cost,
8631 cmp.number_of_units,
8632 cmp.primary_component
8633 FROM okl_assets_b ast,
8634 okl_lease_quotes_b qte,
8635 okl_asset_components_b cmp
8636 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
8637 ast.parent_object_id = qte.id AND
8638 qte.id = qteid AND
8639 ast.id = astid AND
8640 cmp.primary_component = 'YES' AND
8641 cmp.asset_id = ast.id;
8642 -- Cursor to fetch the Asset Level Details
8643 CURSOR asset_cost_adj_csr(qteid NUMBER,
8644 astid NUMBER)
8645 IS
8646 SELECT adj.adjustment_source_type,
8647 adj.adjustment_source_id,
8648 adj.basis,
8649 -- Start : DJANASWA : Bug# 6347118
8650 nvl(adj.value,adj.default_subsidy_amount) value
8651 -- End : DJANASWA : Bug# 6347118
8652 FROM okl_assets_b ast,
8653 okl_lease_quotes_b qte,
8654 okl_cost_adjustments_b adj
8655 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
8656 ast.parent_object_id = qte.id AND
8657 qte.id = qteid AND
8658 ast.id = astid AND
8659 adj.parent_object_id = ast.id;
8660 -- Cursor to fetch the Customer Details
8661 CURSOR get_cust_details_csr( p_lq_id NUMBER )
8662 IS
8663 SELECT lopp.id parent_id
8664 ,lopp.prospect_id prospect_id
8665 ,lopp.cust_acct_id cust_acct_id
8666 ,lopp.sales_territory_id sales_territory_id
8667 ,lopp.currency_code currency_code
8668 FROM okl_lease_quotes_b lq,
8669 okl_lease_opportunities_b lopp
8670 WHERE parent_object_code = 'LEASEOPP'
8671 AND parent_object_id = lopp.id
8672 AND lq.id = p_lq_id;
8673 --Cursor to fetch the Parent Object Details
8674 CURSOR get_cust_details_csr_lapp( p_lq_id NUMBER )
8675 IS
8676 SELECT lapp.id parent_id
8677 ,lapp.prospect_id prospect_id
8678 ,lapp.cust_acct_id cust_acct_id
8679 ,lapp.sales_territory_id sales_territory_id
8680 ,lapp.currency_code currency_code
8681 FROM okl_lease_quotes_b lq,
8682 okl_lease_applications_b lapp
8683 WHERE parent_object_code = 'LEASEAPP'
8684 AND parent_object_id = lapp.id
8685 AND lq.id = p_lq_id;
8686 -- Cursor to fetch the Asset components details
8687 CURSOR c_asset_comp_csr( p_asset_id NUMBER) IS
8688 SELECT
8689 id
8690 ,primary_component
8691 ,unit_cost
8692 ,number_of_units
8693 FROM okl_asset_components_v
8694 WHERE asset_id = p_asset_id
8695 AND primary_component = 'YES';
8696
8697 CURSOR check_cfo_exists_csr(
8698 p_oty_code IN VARCHAR2,
8699 p_source_table IN VARCHAR2,
8700 p_source_id IN VARCHAR2 )
8701 IS
8702 SELECT 'YES' cfo_exists,
8703 cfo.id cfo_id,
8704 caf.id caf_id,
8705 caf.sty_id sty_id
8706 FROM OKL_CASH_FLOW_OBJECTS cfo,
8707 OKL_CASH_FLOWS caf
8708 WHERE OTY_CODE = p_oty_code
8709 AND SOURCE_TABLE = p_source_table
8710 AND SOURCE_ID = p_source_id
8711 AND caf.cfo_id = cfo.id;
8712 check_cfo_exists_rec check_cfo_exists_csr%ROWTYPE;
8713 -- Cursor to fetch the Stream Type
8714 CURSOR c_strm_type (
8715 pdtId NUMBER,
8716 expStartDate DATE,
8717 strm_purpose VARCHAR) IS
8718 SELECT STRM.STY_ID PAYMENT_TYPE_ID,
8719 STRM.STY_NAME PAYMENT_TYPE,
8720 STRM.START_DATE,
8721 STRM.END_DATE,
8722 STRM.STY_PURPOSE
8723 FROM OKL_STRM_TMPT_PRIMARY_UV STRM
8724 WHERE STY_PURPOSE = strm_purpose
8725 AND START_DATE <= expStartDate
8726 AND NVL(END_DATE, expStartDate) >= expStartDate
8727 AND STRM.PDT_ID = pdtId;
8728
8729 -- Cursor to fetch the Stream Type for FINANCED/ROLLOVER Fee Payment in case of TR pricing method
8730 CURSOR c_fee_pmnt_strm_type_csr (
8731 pdtId NUMBER,
8732 expStartDate DATE,
8733 strm_purpose VARCHAR)
8734 IS
8735 SELECT STRM.STY_ID PAYMENT_TYPE_ID,
8736 STRM.STY_NAME PAYMENT_TYPE,
8737 STRM.START_DATE,
8738 STRM.END_DATE,
8739 STRM.STY_PURPOSE
8740 FROM OKL_STRM_TMPT_PRIMARY_UV STRM
8741 WHERE STY_PURPOSE = strm_purpose
8742 AND START_DATE <= expStartDate
8743 AND NVL(END_DATE, expStartDate ) >= expStartDate
8744 AND NVL(STRM.CAPITALIZE_YN, 'N') = 'N'
8745 AND STRM.BILLABLE_YN = 'Y'
8746 AND STRM.PDT_ID = pdtId;
8747
8748 -- Cursor to fetch EOT Type
8749 CURSOR get_eot_type( p_lq_id NUMBER )
8750 IS
8751 SELECT lq.id
8752 ,lq.reference_number
8753 ,eot.end_of_term_name
8754 ,eot.eot_type_code eot_type_code
8755 ,eot.end_of_term_id end_of_term_id
8756 ,eotversion.end_of_term_ver_id
8757 FROM OKL_LEASE_QUOTES_B lq,
8758 okl_fe_eo_term_vers eotversion,
8759 okl_fe_eo_terms_all_b eot
8760 WHERE lq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
8761 AND eot.end_of_term_id = eotversion.end_of_term_id
8762 AND lq.id = p_lq_id;
8763 l_eot_type_code VARCHAR2(30);
8764 -- Cursor to handle the CAPITALIZED Fee amount for each Asset
8765 CURSOR get_asset_cap_fee_amt(p_source_type VARCHAR2,
8766 p_source_id OKL_LINE_RELATIONSHIPS_B.source_line_ID%TYPE,
8767 p_related_line_type OKL_LINE_RELATIONSHIPS_B.related_line_type%TYPE)
8768 IS
8769 SELECT SUM(amount) capitalized_amount
8770 FROM okl_line_relationships_v lre
8771 WHERE source_line_type = p_source_type
8772 AND related_line_type = 'CAPITALIZED'
8773 AND source_line_id = p_source_id;
8774
8775 -- Local Variables Declarations !
8776 l_day_count_method VARCHAR2(30);
8777 l_days_in_month VARCHAR2(30);
8778 l_days_in_year VARCHAR2(30);
8779 l_currency VARCHAR2(30);
8780 l_srt_details okl_pricing_utils_pvt.srt_details_rec_type;
8781 l_ast_srt_details okl_pricing_utils_pvt.srt_details_rec_type;
8782 lx_pricing_parameter_rec okl_pricing_utils_pvt.pricing_parameter_rec_type;
8783 x_iir NUMBER;
8784 l_initial_guess NUMBER := 0.1;
8785 x_payment NUMBER;
8786 -- Cash flow and Cash flow level variables
8787 l_cash_flow_rec so_cash_flows_rec_type;
8788 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
8789 l_cash_inflows okl_pricing_utils_pvt.cash_inflows_tbl_type;
8790 l_residual_inflows okl_pricing_utils_pvt.cash_inflows_tbl_type;
8791 cfl_index BINARY_INTEGER;
8792 res_index BINARY_INTEGER;
8793 l_eot_date DATE; -- Effective To of the quote
8794 l_cf_dpp NUMBER;
8795 l_cf_ppy NUMBER;
8796 l_pricing_method VARCHAR2(30);
8797 l_target_rate NUMBER := p_target_rate;
8798 l_adj_mat_cat_rec adj_mat_cat_rec;
8799 -- Variables used for storing back the pricing results !
8800 lx_asset_rec okl_ass_pvt.assv_rec_type;
8801 lx_fee_rec okl_fee_pvt.feev_rec_type;
8802 l_ass_adj_tbl okl_lease_quote_asset_pvt.asset_adjustment_tbl_type;
8803 l_cf_source VARCHAR2(30);
8804 l_fee_yn VARCHAR2(1) := 'N';
8805 l_cashflow_header_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
8806 l_cashflow_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
8807 l_asset_rec OKL_LEASE_QUOTE_ASSET_PVT.asset_rec_type;
8808 l_component_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_component_tbl_type;
8809 l_cf_hdr_rec OKL_LEASE_QUOTE_ASSET_PVT.cashflow_hdr_rec_type;
8810 l_cf_level_tbl OKL_LEASE_QUOTE_ASSET_PVT.cashflow_level_tbl_type;
8811 l_cfo_exists VARCHAR2(30);
8812 l_eot_percentage NUMBER;
8813 l_eot_amount NUMBER;
8814 l_rate_card_id NUMBER;
8815 l_lease_rate_factor NUMBER;
8816 l_asset_follows_lq_pricing VARCHAR2(30);
8817 l_rc_pricing VARCHAR2(30);
8818 l_target_frequency VARCHAR2(30);
8819 l_target_arrears_yn VARCHAR2(30);
8820 l_sty_id NUMBER;
8821 l_srt_id NUMBER;
8822 l_adj_type VARCHAR2(30);
8823 l_quote_type_code OKL_LEASE_QUOTES_B.PARENT_OBJECT_CODE%TYPE;
8824 l_missing_pmnts BOOLEAN;
8825 l_asset_number VARCHAR2(15);
8826 l_fee_name VARCHAR2(150);
8827 BEGIN
8828 l_return_status := OKL_API.G_RET_STS_SUCCESS;
8829 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
8830 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
8831 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
8832 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
8833 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
8834 l_return_status := OKL_API.START_ACTIVITY(
8835 p_api_name => l_api_name,
8836 p_pkg_name => G_PKG_NAME,
8837 p_init_msg_list => p_init_msg_list,
8838 l_api_version => l_api_version,
8839 p_api_version => p_api_version,
8840 p_api_type => g_api_type,
8841 x_return_status => l_return_status);
8842 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8843 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8844 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8845 RAISE OKL_API.G_EXCEPTION_ERROR;
8846 END IF;
8847
8848 --Bug 5884825 PAGARG start
8849 OPEN product_name_csr(p_qte_id);
8850 FETCH product_name_csr INTO l_product_name;
8851 CLOSE product_name_csr;
8852 --Bug 5884825 PAGARG end
8853
8854 -- Fetch the Lease Quote Header Details !
8855 OPEN quote_csr(p_qte_id);
8856 FETCH quote_csr INTO quote_rec;
8857 IF (quote_csr%NOTFOUND) THEN
8858 RAISE okl_api.g_exception_unexpected_error;
8859 END IF;
8860 CLOSE quote_csr;
8861 --Populate l_quote_type_code appropriately
8862 IF quote_rec.parent_object_code = 'LEASEAPP' THEN
8863 l_quote_type_code := 'LA';
8864 ELSE
8865 l_quote_type_code := 'LQ';
8866 END IF;
8867 l_pricing_method := quote_rec.pricing_method;
8868 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8869 'Fetched the Lease Quote Details ' || p_qte_id);
8870 -- Derieve the End of Term Date of the Lease Quote
8871 okl_stream_generator_pvt.add_months_new(
8872 p_start_date => quote_rec.expected_start_date,
8873 p_months_after => quote_rec.term,
8874 x_date => l_eot_date,
8875 x_return_status => l_return_status);
8876 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8877 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8878 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
8879 RAISE OKL_API.G_EXCEPTION_ERROR;
8880 END IF;
8881 l_eot_date := l_eot_date - 1;
8882 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8883 'Effective To of the LQ ' || l_eot_date );
8884 -- Retrieve the Payment Structure or build the Cash flow or Cash flow Level objects
8885 lx_pricing_parameter_rec.financed_amount := 0;
8886 lx_pricing_parameter_rec.down_payment := 0;
8887 lx_pricing_parameter_rec.trade_in := 0;
8888 lx_pricing_parameter_rec.subsidy := 0;
8889 -- Retrieve the Asset level information !
8890 FOR assets_rec IN assets_csr(p_qte_id, p_ast_id) -- could be fee id (ROLLOVER or FINANCED)
8891 LOOP
8892 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8893 'Fetching the Asset Details ' );
8894 --Bug 5121548 dpsingh start
8895 l_asset_number := assets_rec.asset_number;
8896 --Bug 5121548 dpsingh end
8897 IF ( assets_rec.fee_type <> 'FREE_FORM1' OR assets_rec.ast_id IS NULL )
8898 THEN
8899 l_fee_yn := 'Y';
8900 ELSE
8901 l_fee_yn := 'N';
8902 END IF;
8903 -- Know the type of the EOT
8904 FOR t_rec IN get_eot_type( p_lq_id => p_qte_id )
8905 LOOP
8906 l_eot_type_code := t_rec.eot_type_code;
8907 END LOOP;
8908 -- Populate the Adjustment Matrix Criteria Record.
8909 l_adj_mat_cat_rec.target_eff_from := quote_rec.expected_start_date;
8910 l_adj_mat_cat_rec.term := quote_rec.term;
8911 IF quote_rec.parent_object_code = 'LEASEOPP'
8912 THEN
8913 -- Fetch from the Lease Opportunity
8914 FOR t_rec IN get_cust_details_csr( p_lq_id => p_qte_id )
8915 LOOP
8916 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
8917 l_adj_mat_cat_rec.customer_credit_class :=
8918 okl_lease_app_pvt.get_credit_classfication(
8919 p_party_id => t_rec.prospect_id,
8920 p_cust_acct_id => t_rec.cust_acct_id,
8921 p_site_use_id => -99);
8922 END LOOP;
8923 ELSE
8924 -- Fetch from the Lease Application
8925 FOR t_rec IN get_cust_details_csr_lapp( p_lq_id => p_qte_id )
8926 LOOP
8927 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
8928 l_adj_mat_cat_rec.customer_credit_class :=
8929 okl_lease_app_pvt.get_credit_classfication(
8930 p_party_id => t_rec.prospect_id,
8931 p_cust_acct_id => t_rec.cust_acct_id,
8932 p_site_use_id => -99);
8933 END LOOP;
8934 END IF;
8935 l_adj_mat_cat_rec.deal_size := NULL;
8936 IF assets_rec.ast_id IS NOT NULL
8937 THEN
8938 l_cf_source := G_CF_SOURCE_LQ_ASS;
8939 lx_pricing_parameter_rec.line_type := 'FREE_FORM1';
8940 ELSE
8941 l_cf_source := G_CF_SOURCE_LQ_FEE;
8942 lx_pricing_parameter_rec.payment_type := 'INCOME';
8943 lx_pricing_parameter_rec.line_type := assets_rec.fee_type;
8944 END IF;
8945 IF quote_rec.pricing_method <> 'RC'
8946 THEN
8947 IF p_price_at_lq_level = FALSE OR p_price_at_lq_level IS NULL
8948 THEN
8949 -- get_lq_cash_flows will fetch the Cash flows or Cash flow levels during Structured
8950 -- pricing (or) builds the CF and CF Levels in case of SRT and return.
8951 -- Very similiar API to the get_qq_cash_flows-2
8952 -- User p_cf_source as G_CF_SOURCE_LQ_ASS, as now we will be pricing the asset
8953 -- with the payment structure defined at the Asset Level itself !
8954 l_srt_id := assets_rec.rate_template_id;
8955 get_lq_cash_flows(
8956 p_api_version => p_api_version,
8957 p_init_msg_list => p_init_msg_list,
8958 x_return_status => l_return_status,
8959 x_msg_count => x_msg_count,
8960 x_msg_data => x_msg_data,
8961 p_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
8962 p_lq_srt_id => assets_rec.rate_template_id,
8963 p_cf_source => l_cf_source,
8964 p_adj_mat_cat_rec => l_adj_mat_cat_rec,
8965 p_pricing_method => quote_rec.pricing_method,
8966 x_days_in_month => l_days_in_month,
8967 x_days_in_year => l_days_in_year,
8968 x_cash_flow_rec => l_cash_flow_rec,
8969 x_cash_flow_det_tbl => l_cash_flow_det_tbl);
8970 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8971 'Fetched asset cash flows at Asset level l_return_status = ' || l_return_status);
8972 ELSE
8973 -- Fetching the Cash Flows Assosiated at the Lesae Quote Level
8974 l_cf_source := G_CF_SOURCE_LQ;
8975 -- Let the initial iir be p_target_rate
8976 l_initial_guess := p_target_rate;
8977 -- Fetch/Retrieve the Cash flows n levels
8978 get_lq_cash_flows(
8979 p_api_version => p_api_version,
8980 p_init_msg_list => p_init_msg_list,
8981 x_return_status => l_return_status,
8982 x_msg_count => x_msg_count,
8983 x_msg_data => x_msg_data,
8984 p_id => p_qte_id,
8985 p_lq_srt_id => quote_rec.rate_template_id,
8986 p_cf_source => l_cf_source,
8987 p_adj_mat_cat_rec => l_adj_mat_cat_rec,
8988 p_pricing_method => quote_rec.pricing_method,
8989 x_days_in_month => l_days_in_month,
8990 x_days_in_year => l_days_in_year,
8991 x_cash_flow_rec => l_cash_flow_rec,
8992 x_cash_flow_det_tbl => l_cash_flow_det_tbl);
8993 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8994 'Fetched asset cash flows @LQ level l_return_status = ' || l_return_status);
8995 END IF; -- If on get_lq_cash_flows
8996 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
8997 quote_rec.pricing_method || 'After lq_cash_flows ' || l_return_status);
8998 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
8999 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9000 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9001 RAISE OKL_API.G_EXCEPTION_ERROR;
9002 END IF;
9003 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9004 'No. of Cash Flow Levels ' || l_cash_flow_det_tbl.COUNT );
9005 IF l_cash_flow_det_tbl IS NULL OR
9006 l_cash_flow_det_tbl.COUNT <= 0
9007 THEN
9008 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9009 'No Cash flow and Cash flow Levels obtained ! ' );
9010 OKL_API.SET_MESSAGE (
9011 p_app_name => G_APP_NAME,
9012 p_msg_name => 'OKL_LLA_PMT_SELECT');
9013 RAISE OKL_API.G_EXCEPTION_ERROR;
9014 END IF;
9015 l_missing_pmnts := FALSE;
9016 -- When the pricing method is SM, an overridden asset may have a missing payment
9017 -- or not. If no missing payment is present, rates will be present for all CFL levels
9018 -- else, rate wont be present.
9019 IF quote_rec.pricing_method = 'SM'
9020 THEN
9021 FOR t_in IN l_cash_flow_det_tbl.FIRST .. l_cash_flow_det_tbl.LAST
9022 LOOP
9023 IF ( l_cash_flow_det_tbl(t_in).stub_days > 0 AND
9024 l_cash_flow_det_tbl(t_in).stub_amount IS NULL ) OR
9025 ( l_cash_flow_det_tbl(t_in).number_of_periods > 0 AND
9026 l_cash_flow_det_tbl(t_in).amount IS NULL )
9027 THEN
9028 l_missing_pmnts := TRUE;
9029 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9030 '***** Need to solve for the Missing Payments *********' );
9031 END IF;
9032 END LOOP;
9033 END IF;
9034 -- Populate app. values for l_days_in_month and l_days_in_year !
9035 get_day_count_method(
9036 p_days_in_month => l_days_in_month,
9037 p_days_in_year => l_days_in_year,
9038 x_day_count_method => l_day_count_method,
9039 x_return_status => l_return_status );
9040 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9041 'After get_day_count_method ' || l_return_status);
9042 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9043 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9044 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9045 --Bug 5884825 PAGARG start
9046 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9047 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
9048 p_token1 => 'PRODUCT_NAME',
9049 p_token1_value => l_product_name);
9050 --Bug 5884825 PAGARG end
9051 RAISE OKL_API.G_EXCEPTION_ERROR;
9052 END IF;
9053 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9054 'l_days_in_month= ' || l_days_in_month || ' | l_days_in_year = ' || l_days_in_year);
9055 -- Get the DPP and PPY inorder to populate for the Residuals Table
9056 get_dpp_ppy(
9057 p_frequency => l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code,
9058 x_dpp => l_cf_dpp,
9059 x_ppy => l_cf_ppy,
9060 x_return_status => l_return_status );
9061 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9062 'After get_dpp_ppy ' || l_return_status );
9063 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9064 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9065 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9066 RAISE OKL_API.G_EXCEPTION_ERROR;
9067 END IF;
9068 END IF; -- IF quote_rec.pricing_method <> 'RC'
9069 -- Retrieve the Cost adjustments defined for the Asset ! None for fees
9070 IF assets_rec.ast_id IS NOT NULL
9071 THEN
9072 FOR asset_cost_adj_rec IN asset_cost_adj_csr(p_qte_id, nvl(assets_rec.ast_id, -9999) )
9073 LOOP
9074 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE AND
9075 quote_rec.pricing_method <> 'SD'
9076 THEN
9077 lx_pricing_parameter_rec.down_payment := lx_pricing_parameter_rec.down_payment
9078 + asset_cost_adj_rec.value;
9079 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE AND
9080 quote_rec.pricing_method <> 'SS'
9081 THEN
9082 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
9083 THEN
9084 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
9085 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
9086 CLOSE subsidy_adj_csr;
9087 -- Bug 6622178 : Start
9088 -- Consider all subsidies for the asset
9089 lx_pricing_parameter_rec.subsidy := lx_pricing_parameter_rec.subsidy + NVL(subsidy_adj_rec.amount,0);
9090 ELSE
9091 lx_pricing_parameter_rec.subsidy := lx_pricing_parameter_rec.subsidy + NVL(asset_cost_adj_rec.value,0);
9092 -- Bug 6622178 : End
9093 END IF;
9094 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE AND
9095 quote_rec.pricing_method <> 'SI'
9096 THEN
9097 lx_pricing_parameter_rec.trade_in := lx_pricing_parameter_rec.trade_in
9098 + asset_cost_adj_rec.value;
9099 END IF;
9100 END LOOP;
9101 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9102 'After Retrieving the Asset Cost Adjustments ');
9103 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9104 'Down Payment| Trade In | Subsidy ' );
9105 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9106 lx_pricing_parameter_rec.down_payment || ' | ' ||
9107 lx_pricing_parameter_rec.trade_in || ' | ' ||
9108 lx_pricing_parameter_rec.subsidy );
9109 END IF; -- IF assets_rec.ast_id IS NOT NULL
9110 -- Generate the Streams for this Asset !
9111 -- Retrieve the Financed amount and the End of Term amount !
9112 res_index := 1;
9113 l_eot_amount := 0;
9114 IF ( assets_rec.ast_id IS NOT NULL)
9115 THEN
9116 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9117 'Asset/Fee ID = ' || assets_rec.ast_id );
9118 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
9119 LOOP
9120 IF l_pricing_method <> 'SF' OR ( quote_rec.pricing_method = 'SF' AND p_price_at_lq_level )
9121 THEN
9122 lx_pricing_parameter_rec.financed_amount := lx_pricing_parameter_rec.financed_amount
9123 + nvl(asset_adj_rec.oec,0);
9124 END IF;
9125 -- Calculate the Capitalized Fee for this Asset
9126 FOR t_rec IN get_asset_cap_fee_amt(
9127 p_source_type => 'ASSET',
9128 p_source_id => assets_rec.ast_id,
9129 p_related_line_type => 'CAPITALIZED')
9130 LOOP
9131 lx_pricing_parameter_rec.cap_fee_amount := nvl(t_rec.capitalized_amount, 0);
9132 END LOOP;
9133 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9134 'Unit Cost=' || asset_adj_rec.unit_cost || ' No. of Units ' || asset_adj_rec.number_of_units);
9135 l_residual_inflows(res_index).line_number := res_index;
9136 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' ) AND
9137 ( l_pricing_method <> 'SF' OR ( quote_rec.pricing_method = 'SF' AND p_price_at_lq_level ) )
9138 THEN
9139 -- Formula: EOT amount = OEC * residual_percentage
9140 -- The above formulat is applicable, a/ When EOT is PERCENT/RESIDUAL_PERCENT
9141 -- b/ When solving for an overridden asset, its financed amount.
9142 -- c/ When Qt. level pricing method is SF, but you are here actually for derieving
9143 -- the payment structures for non-overridden assets when pricing method is SF
9144 l_residual_inflows(res_index).cf_amount :=
9145 (asset_adj_rec.end_of_term_value/100) * nvl(asset_adj_rec.unit_cost * asset_adj_rec.number_of_units,0);
9146 l_eot_percentage := asset_adj_rec.end_of_term_value;
9147 ELSIF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' ) AND
9148 ( l_pricing_method = 'SF' )
9149 THEN
9150 -- EOT is given in terms of percentage .. store the percentage
9151 -- NOTE: For overriden assets, OEC percentage doesnot matter. As they are being priced seperately
9152 l_residual_inflows(res_index).cf_amount := (asset_adj_rec.end_of_term_value/100);
9153 ELSE
9154 -- EOT is an amount so directly store it ..
9155 l_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
9156 END IF;
9157 -- Store the End of Term Value
9158 l_eot_amount := l_eot_amount + l_residual_inflows(res_index).cf_amount;
9159 l_residual_inflows(res_index).cf_date := l_eot_date;
9160 l_residual_inflows(res_index).cf_miss_pay := 'N';
9161 l_residual_inflows(res_index).is_stub := 'N';
9162 l_residual_inflows(res_index).is_arrears := 'Y';
9163 l_residual_inflows(res_index).cf_dpp := l_cf_dpp;
9164 l_residual_inflows(res_index).cf_ppy := l_cf_ppy;
9165 -- Increment the res_index
9166 res_index := res_index + 1;
9167 END LOOP;
9168 ELSE -- ELSE IT IS A FEE
9169 lx_pricing_parameter_rec.financed_amount := assets_rec.fee_amount;
9170 END IF;
9171 IF l_pricing_method = 'RC' AND l_fee_yn = 'N'
9172 THEN
9173 -- Calculate the EOT Percentage Amount
9174 IF ( l_eot_type_code <> 'PERCENT' AND l_eot_type_code <> 'RESIDUAL_PERCENT' )
9175 THEN
9176 l_eot_percentage := nvl(l_eot_amount,0) / lx_pricing_parameter_rec.financed_amount * 100;
9177 END IF;
9178 l_asset_follows_lq_pricing := 'Y';
9179 l_rc_pricing := 'Y';
9180 -- Prioritize Configuration line ones first
9181 IF nvl(quote_rec.line_level_pricing, 'N') = 'Y'
9182 THEN
9183 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9184 '******* Line Level Pricing is enabled at Quote *******' );
9185 -- Line level pricing has been enabled
9186 -- Store the Lease Rate Factor and Rate Template of the of the Configuration lines
9187 IF nvl(assets_rec.structured_pricing, 'N') = 'Y'
9188 THEN
9189 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9190 '******* Structured Pricing picked @ Asset ******* ' || assets_rec.structured_pricing );
9191 l_lease_rate_factor := assets_rec.lease_rate_factor;
9192 l_asset_follows_lq_pricing := 'N';
9193 l_rc_pricing := 'N';
9194 -- May need to store the Frequency/Arrears flag even here
9195 l_target_frequency := assets_rec.target_frequency;
9196 l_target_arrears_yn := assets_rec.target_arrears;
9197 ELSIF assets_rec.rate_card_id IS NOT NULL
9198 THEN
9199 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9200 '******* Rate Card picked @ Asset ******* ' || assets_rec.rate_card_id );
9201 l_rate_card_id := assets_rec.rate_card_id;
9202 l_asset_follows_lq_pricing := 'N';
9203 l_rc_pricing := 'Y';
9204 END IF;
9205 END IF;
9206 IF NVL(quote_rec.line_level_pricing, 'N') = 'N' OR
9207 l_asset_follows_lq_pricing = 'Y'
9208 THEN
9209 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9210 '******* Either Line Level Pricing is NULL/N or Asset follws rate @ Quote *******' ||
9211 quote_rec.line_level_pricing || ' | ' || l_asset_follows_lq_pricing );
9212 -- If Line level pricing is not picked or
9213 -- the configuration line is not overriding the pricing params
9214 -- picked at the lease quote level, use the data at the lease quote level itself.
9215 IF nvl(quote_rec.structured_pricing, 'N') = 'Y'
9216 THEN
9217 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9218 '******* Structured Pricing Enabled @ Quote *******' || quote_rec.structured_pricing );
9219 l_lease_rate_factor := quote_rec.lease_rate_factor;
9220 l_rc_pricing := 'N';
9221 -- May need to store the Frequency/Arrears flag even here
9222 l_target_frequency := quote_rec.target_frequency;
9223 l_target_arrears_yn := quote_rec.target_arrears;
9224 ELSIF quote_rec.rate_card_id IS NOT NULL
9225 THEN
9226 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9227 '******* Rate Card Picked @ Quote *******' || quote_rec.rate_card_id );
9228 l_rate_card_id := quote_rec.rate_card_id;
9229 l_rc_pricing := 'Y';
9230 END IF;
9231 END IF;
9232 ELSIF l_pricing_method = 'RC' AND l_fee_yn = 'Y'
9233 THEN
9234 -- Handling seperately for config fee FINANCED/ROLLOVER
9235 l_eot_percentage := 0;
9236 l_asset_follows_lq_pricing := 'N';
9237 IF nvl(assets_rec.structured_pricing, 'N') = 'Y'
9238 THEN
9239 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9240 '******* Structured Pricing picked @ Config FEE level = ' || assets_rec.structured_pricing );
9241 l_lease_rate_factor := assets_rec.lease_rate_factor;
9242 l_asset_follows_lq_pricing := 'N';
9243 l_rc_pricing := 'N';
9244 -- May need to store the Frequency/Arrears flag even here
9245 l_target_frequency := assets_rec.target_frequency;
9246 l_target_arrears_yn := assets_rec.target_arrears;
9247 ELSIF assets_rec.rate_card_id IS NOT NULL
9248 THEN
9249 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9250 '******* Rate Card picked @ config Fee Level = ' || assets_rec.rate_card_id );
9251 l_rate_card_id := assets_rec.rate_card_id;
9252 l_rc_pricing := 'Y';
9253 END IF;
9254 END IF;
9255 IF l_pricing_method = 'RC' AND
9256 l_rc_pricing = 'Y'
9257 THEN
9258 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9259 'Pricing using a Rate Card with ID ' || l_rate_card_id );
9260 get_lease_rate_factors(
9261 p_api_version => p_api_version,
9262 p_init_msg_list => p_init_msg_list,
9263 x_return_status => l_return_status,
9264 x_msg_count => x_msg_count,
9265 x_msg_data => x_msg_data,
9266 p_lrt_id => l_rate_card_id,
9267 p_start_date => quote_rec.expected_start_date,
9268 p_term_in_months => quote_rec.term,
9269 p_eot_percentage => l_eot_percentage,
9270 x_lrs_details => l_lrs_details,
9271 x_lrs_factor => l_lrs_factor,
9272 x_lrs_levels => l_lrs_levels);
9273 -- If unable to find the Lease Rate Factor levels throw the error ..
9274 IF l_return_status <> OKL_API.G_RET_STS_SUCCESS
9275 THEN
9276 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9277 'Couldnot found the Lease Rate Factor levels for configuration line ' || assets_rec.name );
9278 -- Show the message and then return back throwing an error!
9279 OKL_API.set_message(
9280 p_app_name => G_APP_NAME,
9281 p_msg_name => 'OKL_LP_NO_LRS_LEVELS_FOUND',
9282 p_token1 => 'ITEMCAT',
9283 p_token1_value => assets_rec.name,
9284 p_token2 => 'ITEMTERM',
9285 p_token2_value => quote_rec.term,
9286 p_token3 => 'ITEMEOTPERCENT',
9287 p_token3_value => ROUND(l_eot_percentage,4) );
9288 RAISE OKL_API.G_EXCEPTION_ERROR;
9289 END IF;
9290 -- Apply the adjustment matrix if needed!
9291 l_adj_factor := 0;
9292 IF l_lrs_details.adj_mat_version_id IS NOT NULL
9293 THEN
9294 l_ac_rec_type.src_id := l_lrs_details.adj_mat_version_id; -- Pricing adjustment matrix ID
9295 l_ac_rec_type.source_name := NULL; -- NOT Mandatory Pricing Adjustment Matrix Name !
9296 l_ac_rec_type.target_id := quote_rec.ID ; -- Quote ID
9297 l_ac_rec_type.src_type := 'PAM'; -- Lookup Code
9298 l_ac_rec_type.target_type := 'QUOTE'; -- Same for both Quick Quote and Standard Quote
9299 l_ac_rec_type.target_eff_from := quote_rec.expected_start_date; -- Quote effective From
9300 l_ac_rec_type.term := quote_rec.term; -- Remaining four will be from teh business object like QQ / LQ
9301 l_ac_rec_type.territory := l_adj_mat_cat_rec.territory;
9302 l_ac_rec_type.deal_size := lx_pricing_parameter_rec.financed_amount; -- Not sure how to pass this value
9303 l_ac_rec_type.customer_credit_class := l_adj_mat_cat_rec.customer_credit_class; -- Not sure how to pass this even ..
9304 -- Fetching the deal_size ..
9305 -- Calling the API to get the adjustment factor ..
9306 okl_ec_evaluate_pvt.get_adjustment_factor(
9307 p_api_version => p_api_version,
9308 p_init_msg_list => p_init_msg_list,
9309 x_return_status => x_return_status,
9310 x_msg_count => x_msg_count,
9311 x_msg_data => x_msg_data,
9312 p_okl_ac_rec => l_ac_rec_type,
9313 x_adjustment_factor => l_adj_factor );
9314 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9315 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9316 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9317 RAISE OKL_API.G_EXCEPTION_ERROR;
9318 END IF;
9319 END IF;
9320 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9321 'Adjustment Factor ' || l_adj_factor );
9322 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
9323 p_frequency => l_lrs_details.frq_code,
9324 x_return_status => l_return_status);
9325 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9326 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9327 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9328 RAISE OKL_API.G_EXCEPTION_ERROR;
9329 END IF;
9330 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9331 'Months/Period ' || l_months_per_period );
9332 l_cash_flow_rec.due_arrears_yn := l_lrs_details.arrears_yn;
9333 --Populating the Cash Flow Levels
9334 l_months_after := 0;
9335 cf_index := 1;
9336 FOR i in l_lrs_levels.FIRST .. l_lrs_levels.LAST
9337 LOOP
9338 l_cash_flow_det_tbl(cf_index).fqy_code := l_lrs_details.frq_code;
9339 l_cash_flow_det_tbl(cf_index).number_of_periods := l_lrs_levels(i).periods;
9340 -- FORMULA: Periodic Amt = (Rate Factor + Adj. Factor ) * ( C - NVL( S+D+T, 0) )
9341 l_cash_flow_det_tbl(cf_index).amount :=
9342 ( l_lrs_levels(cf_index).lease_rate_factor + NVL(l_adj_factor,0) ) *
9343 ( lx_pricing_parameter_rec.financed_amount - NVL(lx_pricing_parameter_rec.subsidy +
9344 lx_pricing_parameter_rec.down_payment + lx_pricing_parameter_rec.trade_in,0 ) );
9345 l_cash_flow_det_tbl(cf_index).is_stub := 'N';
9346 -- Need to populate the start date per line .. !!
9347 okl_stream_generator_pvt.add_months_new(
9348 p_start_date => quote_rec.expected_start_date,
9349 p_months_after => l_months_after,
9350 x_date => l_cash_flow_det_tbl(cf_index).start_date,
9351 x_return_status => l_return_status);
9352 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9353 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9354 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9355 RAISE OKL_API.G_EXCEPTION_ERROR;
9356 END IF;
9357 -- Add to the l_months_after
9358 l_months_after := l_months_after + ( l_lrs_levels(i).periods * l_months_per_period );
9359 -- Increment the index
9360 cf_index := cf_index + 1;
9361 END LOOP;
9362 ELSIF l_pricing_method = 'RC' AND
9363 l_rc_pricing = 'N'
9364 THEN
9365 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9366 '!!!!! STRUCTURED PRICING IN RATE CARD PRICING !!!!!! ' );
9367 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9368 'lease rate factor | Frequency | Arrears ' );
9369 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9370 l_lease_rate_factor || ' | ' || l_target_frequency || ' | ' || l_target_arrears_yn );
9371 l_months_per_period := okl_stream_generator_pvt.get_months_factor(
9372 p_frequency => l_target_frequency,
9373 x_return_status => l_return_status);
9374 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9375 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9376 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9377 RAISE OKL_API.G_EXCEPTION_ERROR;
9378 END IF;
9379 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9380 'Months/Period ' || l_months_per_period );
9381 l_cash_flow_rec.due_arrears_yn := l_target_arrears_yn;
9382 --Populating the Cash Flow Levels
9383 l_months_after := 0;
9384 l_cash_flow_det_tbl(1).fqy_code := l_target_frequency;
9385 l_cash_flow_det_tbl(1).number_of_periods := quote_rec.term/l_months_per_period;
9386 -- Need to check whether the periods is a whole number or not
9387 IF trunc(l_cash_flow_det_tbl(1).number_of_periods) <>
9388 l_cash_flow_det_tbl(1).number_of_periods
9389 THEN
9390 -- Throw the message saying that Periods have to be whole number
9391 OKL_API.SET_MESSAGE (
9392 p_app_name => G_APP_NAME,
9393 p_msg_name => 'OKL_LEVEL_PERIOD_FRACTION');
9394 RAISE OKL_API.G_EXCEPTION_ERROR;
9395 END IF;
9396 -- FORMULA: Periodic Amt = User Entered Rate Factor * ( C - NVL( S+D+T, 0) )
9397 l_cash_flow_det_tbl(1).amount := l_lease_rate_factor *
9398 ( lx_pricing_parameter_rec.financed_amount - NVL(lx_pricing_parameter_rec.subsidy +
9399 lx_pricing_parameter_rec.down_payment + lx_pricing_parameter_rec.trade_in,0 ) );
9400 l_cash_flow_det_tbl(1).is_stub := 'N';
9401 l_cash_flow_det_tbl(1).start_date := quote_rec.expected_start_date;
9402 END IF;
9403 -- Generate the Streams based on the Cash flows obtained above
9404 IF l_cash_flow_det_tbl IS NOT NULL AND
9405 l_cash_flow_det_tbl.COUNT > 0
9406 THEN
9407 -- Initialize the Strm Count to Zero
9408 gen_so_cf_strms(
9409 p_api_version => p_api_version,
9410 p_init_msg_list => p_init_msg_list,
9411 x_return_status => l_return_status,
9412 x_msg_count => x_msg_count,
9413 x_msg_data => x_msg_data,
9414 p_cash_flow_rec => l_cash_flow_rec,
9415 p_cf_details_tbl => l_cash_flow_det_tbl,
9416 x_cash_inflow_strms_tbl => l_cash_inflows);
9417 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9418 'After gen_so_cf_strms ' || l_return_status);
9419 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9420 'Number of Stream Elements generated ' || l_cash_inflows.COUNT);
9421 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9422 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9423 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9424 RAISE OKL_API.G_EXCEPTION_ERROR;
9425 END IF;
9426 ELSE
9427 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9428 'No Cash flow and Cash flow Levels obtained ! ' );
9429 OKL_API.SET_MESSAGE (
9430 p_app_name => G_APP_NAME,
9431 p_msg_name => 'OKL_LLA_PMT_SELECT');
9432 RAISE OKL_API.G_EXCEPTION_ERROR;
9433 END IF; -- IF l_cash_flow_det_tbl.COUNT > 0
9434 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9435 'After building the Residual Table Count ' || l_residual_inflows.COUNT );
9436 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9437 'Financed Amount = ' || lx_pricing_parameter_rec.financed_amount);
9438 lx_pricing_parameter_rec.cash_inflows := l_cash_inflows;
9439 lx_pricing_parameter_rec.residual_inflows := l_residual_inflows;
9440 IF quote_rec.pricing_method = 'RC'
9441 THEN
9442 -- Get the DPP and PPY inorder to populate for the Residuals Table
9443 get_dpp_ppy(
9444 p_frequency => l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code,
9445 x_dpp => l_cf_dpp,
9446 x_ppy => l_cf_ppy,
9447 x_return_status => l_return_status );
9448 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9449 'After get_dpp_ppy ' || l_return_status );
9450 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9451 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9452 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9453 RAISE OKL_API.G_EXCEPTION_ERROR;
9454 END IF;
9455 IF lx_pricing_parameter_rec.residual_inflows.COUNT > 0
9456 THEN
9457 FOR r_in IN lx_pricing_parameter_rec.residual_inflows.FIRST ..
9458 lx_pricing_parameter_rec.residual_inflows.LAST
9459 LOOP
9460 lx_pricing_parameter_rec.residual_inflows(r_in).cf_dpp := l_cf_dpp;
9461 lx_pricing_parameter_rec.residual_inflows(r_in).cf_ppy := l_cf_ppy;
9462 END LOOP;
9463 END IF;
9464 END IF;
9465 IF quote_rec.pricing_method = 'TR' AND l_fee_yn = 'Y'
9466 THEN
9467 FOR t_in IN lx_pricing_parameter_rec.cash_inflows.FIRST ..
9468 lx_pricing_parameter_rec.cash_inflows.LAST
9469 LOOP
9470 -- For each cash flow level use the SUB_IIR rate solved
9471 lx_pricing_parameter_rec.cash_inflows(t_in).cf_rate := p_target_rate ;
9472 END LOOP;
9473 END IF;
9474 -- End: Fix for SY pricing method @ Asset Level
9475 IF quote_rec.pricing_method = 'SM' AND l_missing_pmnts = FALSE
9476 THEN
9477 -- Nothing to be solved for
9478 NULL;
9479 ELSE
9480 IF ( ( l_fee_yn = 'Y' ) AND ( l_pricing_method IN ( 'SP', 'SM', 'TR' ) ) ) OR
9481 ( ( l_fee_yn = 'N' ) AND ( l_pricing_method NOT IN ( 'SY', 'RC' ) ) )
9482 THEN
9483 -- call compute_iir for payment
9484 -- For fees, when the pricing method is SP/SM/TR, then only we solve for the payment amount
9485 -- For Assets, when pricing method is SY/RC, therez nothing to solve
9486 IF l_pricing_method = 'SF' AND
9487 ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
9488 THEN
9489 l_pricing_method := 'SFP';
9490 END IF;
9491 compute_iir(
9492 p_api_version => p_api_version,
9493 p_init_msg_list => p_init_msg_list,
9494 x_return_status => l_return_status,
9495 x_msg_count => x_msg_count,
9496 x_msg_data => x_msg_data,
9497 p_start_date => quote_rec.expected_start_date,
9498 p_day_count_method => l_day_count_method,
9499 p_pricing_method => l_pricing_method,
9500 p_initial_guess => l_initial_guess,
9501 px_pricing_parameter_rec => lx_pricing_parameter_rec,
9502 px_iir => x_iir,
9503 x_payment => x_payment);
9504 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9505 'After compute_iir l_return_status = ' || l_return_status || 'Solved Payment Amount ' || x_payment);
9506 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9507 'Financed Amount | Down Payment | Subsidy | Trade in ');
9508 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9509 ROUND(lx_pricing_parameter_rec.financed_amount, 4) || ' | ' || ROUND(lx_pricing_parameter_rec.down_payment, 4) || ' | ' ||
9510 ROUND(lx_pricing_parameter_rec.subsidy, 4) || ' | ' || ROUND(lx_pricing_parameter_rec.trade_in, 4) );
9511 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
9512 RAISE okl_api.g_exception_unexpected_error;
9513 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
9514 RAISE okl_api.g_exception_error;
9515 END IF;
9516 IF l_pricing_method IN ( 'SP', 'SM', 'TR' ) AND
9517 x_payment < 0
9518 THEN
9519 --Bug 5121548 dpsingh start
9520 IF l_fee_yn = 'Y'
9521 THEN
9522 OPEN fees_csr(p_qte_id,p_ast_id);
9523 FETCH fees_csr into l_fee_name;
9524 CLOSE fees_csr;
9525 OKL_API.SET_MESSAGE (
9526 p_app_name => G_APP_NAME,
9527 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT_FEE',
9528 p_token1 => 'TYPE',
9529 p_token1_value => 'Payment',
9530 p_token2 => 'AMOUNT',
9531 p_token2_value => round(x_payment,2),
9532 p_token3 => 'NAME',
9533 p_token3_value => l_fee_name);
9534 ELSE
9535 OKL_API.SET_MESSAGE (
9536 p_app_name => G_APP_NAME,
9537 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT_ASSET',
9538 p_token1 => 'TYPE',
9539 p_token1_value => 'Payment',
9540 p_token2 => 'AMOUNT',
9541 p_token2_value => round(x_payment,2),
9542 p_token3 => 'NAME',
9543 p_token3_value => l_asset_number);
9544 END IF;
9545 --Bug 5121548 dpsingh end
9546 RAISE okl_api.g_exception_error;
9547 END IF;
9548 IF l_pricing_method = 'SFP'
9549 THEN
9550 l_pricing_method := 'SF'; -- Revert back the pricing method to 'SF'
9551 -- Change the residual amount
9552 IF lx_pricing_parameter_rec.residual_inflows IS NOT NULL AND
9553 lx_pricing_parameter_rec.residual_inflows.COUNT > 0
9554 THEN
9555 FOR t_in IN lx_pricing_parameter_rec.residual_inflows.FIRST ..
9556 lx_pricing_parameter_rec.residual_inflows.LAST
9557 LOOP
9558 lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount :=
9559 lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount *
9560 lx_pricing_parameter_rec.financed_amount;
9561 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9562 'lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount = ' ||
9563 round(lx_pricing_parameter_rec.residual_inflows(t_in).cf_amount, 4) );
9564 END LOOP;
9565 END IF; -- Count on Residual Table
9566 END IF; -- IF l_pricing_method = 'SFP'
9567 END IF;
9568 END IF;
9569 END LOOP; -- For loop on assets_csr
9570 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9571 ' quote_rec.pricing_method = ' || quote_rec.pricing_method ||
9572 'assets_rec.rate_template_id = ' || assets_rec.rate_template_id );
9573 IF quote_rec.pricing_method = 'SP' OR
9574 quote_rec.pricing_method = 'RC' OR
9575 ( quote_rec.pricing_method = 'SM' AND l_missing_pmnts )OR
9576 (p_price_at_lq_level AND quote_rec.pricing_method IN ( 'SY', 'TR', 'SF') ) OR
9577 l_srt_id IS NOT NULL -- When the lines uses the SRT
9578 THEN
9579 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9580 'Creating/Updating the Cash Flow Object !!' );
9581 -- Check whether CFO already exists or not, if so, update
9582 -- else create new
9583 l_cfo_exists := 'NO';
9584 IF l_fee_yn = 'Y'
9585 THEN
9586 l_cashflow_header_rec.parent_object_code := 'QUOTED_FEE';
9587 FOR t_rec IN check_cfo_exists_csr(
9588 p_oty_code => 'QUOTED_FEE',
9589 p_source_table => 'OKL_FEES_B',
9590 p_source_id => p_ast_id)
9591 LOOP
9592 l_cfo_exists := t_rec.cfo_exists;
9593 l_sty_id := t_rec.sty_id;
9594 END LOOP;
9595 ELSE
9596 l_cashflow_header_rec.parent_object_code := 'QUOTED_ASSET';
9597 FOR t_rec IN check_cfo_exists_csr(
9598 p_oty_code => 'QUOTED_ASSET',
9599 p_source_table => 'OKL_ASSETS_B',
9600 p_source_id => p_ast_id)
9601 LOOP
9602 l_cfo_exists := t_rec.cfo_exists;
9603 l_sty_id := t_rec.sty_id;
9604 END LOOP;
9605 END IF;
9606 -- IF cash flows exists delete the existing ones and create afresh ..
9607 IF l_cfo_exists = 'YES'
9608 THEN
9609 -- Delete the Cash Flow Levels which may be already created by Pricing ..
9610 okl_lease_quote_cashflow_pvt.delete_cashflows (
9611 p_api_version => p_api_version,
9612 p_init_msg_list => p_init_msg_list,
9613 p_transaction_control => NULL,
9614 p_source_object_code => l_cashflow_header_rec.parent_object_code,
9615 p_source_object_id => p_ast_id,
9616 x_return_status => l_return_status,
9617 x_msg_count => x_msg_count,
9618 x_msg_data => x_msg_data);
9619 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9620 ' ----- After deleting the Cash flows for the asset ' || l_return_status );
9621 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
9622 RAISE okl_api.g_exception_unexpected_error;
9623 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
9624 RAISE okl_api.g_exception_error;
9625 END IF;
9626 ELSE
9627 FOR t_rec IN c_strm_type (
9628 pdtId => quote_rec.product_id,
9629 expStartDate => quote_rec.expected_start_date,
9630 strm_purpose => 'RENT')
9631 LOOP
9632 l_sty_id := t_rec.payment_type_id;
9633 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9634 'Fetched stream type id from the cursor' || l_sty_id );
9635 END LOOP;
9636 END IF;
9637 -- Create cash flows in case of user using the SRT
9638 l_cashflow_header_rec.parent_object_id := p_ast_id;
9639 l_cashflow_header_rec.type_code := 'INFLOW';
9640 l_cashflow_header_rec.status_code := l_cash_flow_rec.sts_code;
9641 IF p_price_at_lq_level = TRUE
9642 THEN
9643 -- You will reach this code only when you are actually Solving for Payment
9644 -- or Missing Payment for the Assets, which follow the payment strucutre
9645 -- at the lease quote, and you want to find out the payment at each and every
9646 -- Non-overriding Fee/Asset.
9647 -- Pricing solves the payment amount for all the non-overriding assets and
9648 -- store the WORK statused cash flow levels.
9649 l_cashflow_header_rec.status_code := 'WORK';
9650 END IF;
9651 l_cashflow_header_rec.arrears_flag := l_cash_flow_rec.due_arrears_yn;
9652 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9653 'Stream type id using for creation of cash flows ' || l_sty_id );
9654 IF l_sty_id IS NULL AND
9655 l_fee_yn = 'N'
9656 THEN
9657 -- When pricing option is SRT, you may come here ..
9658 FOR t_rec IN c_strm_type (
9659 pdtId => quote_rec.product_id,
9660 expStartDate => quote_rec.expected_start_date,
9661 strm_purpose => 'RENT')
9662 LOOP
9663 l_sty_id := t_rec.payment_type_id;
9664 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9665 'Fetched stream type id from the cursor' || l_sty_id );
9666 END LOOP;
9667 END IF;
9668 IF l_cash_flow_rec.sty_id IS NOT NULL
9669 THEN
9670 l_cashflow_header_rec.stream_type_id := l_cash_flow_rec.sty_id;
9671 ELSE
9672 l_cashflow_header_rec.stream_type_id := l_sty_id;
9673 END IF;
9674 -- Exception for Stream Type id is: TR pricing method, Fees=Yes,
9675 IF l_fee_yn = 'Y' and quote_rec.pricing_method = 'TR'
9676 THEN
9677 FOR t_rec IN c_fee_pmnt_strm_type_csr ( pdtId => quote_rec.product_id,
9678 expStartDate => quote_rec.expected_start_date, strm_purpose => 'FEE_PAYMENT')
9679 LOOP
9680 l_cashflow_header_rec.stream_type_id := t_rec.payment_type_id;
9681 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9682 'Fetched fee pmnt cursor id from the cursor' || l_sty_id );
9683 EXIT;
9684 END LOOP;
9685 END IF;
9686 l_cashflow_header_rec.frequency_code := l_cash_flow_det_tbl(l_cash_flow_det_tbl.FIRST).fqy_code;
9687 l_cashflow_header_rec.quote_type_code := l_quote_type_code;
9688 l_cashflow_header_rec.quote_id := p_qte_id;
9689 FOR i in l_cash_flow_det_tbl.FIRST..l_cash_flow_det_tbl.LAST
9690 LOOP
9691 l_cashflow_level_tbl(i).start_date := l_cash_flow_det_tbl(i).start_date;
9692 IF p_price_at_lq_level AND quote_rec.pricing_method IN ('SY', 'TR', 'SF')
9693 THEN
9694 l_cashflow_level_tbl(i).rate := quote_rec.sub_iir;
9695 ELSE
9696 l_cashflow_level_tbl(i).rate := l_cash_flow_det_tbl(i).rate;
9697 END IF;
9698 l_cashflow_level_tbl(i).stub_amount := l_cash_flow_det_tbl(i).stub_amount;
9699 l_cashflow_level_tbl(i).stub_days := l_cash_flow_det_tbl(i).stub_days;
9700 l_cashflow_level_tbl(i).periods := l_cash_flow_det_tbl(i).number_of_periods;
9701 l_cashflow_level_tbl(i).periodic_amount := l_cash_flow_det_tbl(i).amount;
9702 IF quote_rec.pricing_method = 'RC'
9703 THEN
9704 l_cashflow_level_tbl(i).periodic_amount := l_cash_flow_det_tbl(i).amount;
9705 ELSIF quote_rec.pricing_method = 'SP' OR
9706 ( p_price_at_lq_level AND quote_rec.pricing_method IN ('SY', 'TR', 'SF'))
9707 THEN
9708 -- Pricing would have solved the periodic/stub amount for all cash flow levels
9709 IF l_cash_flow_det_tbl(i).stub_days > 0
9710 THEN
9711 l_cashflow_level_tbl(i).stub_amount := x_payment;
9712 ELSIF l_cash_flow_det_tbl(i).number_of_periods > 0
9713 THEN
9714 l_cashflow_level_tbl(i).periodic_amount := x_payment;
9715 END IF;
9716 ELSIF quote_rec.pricing_method = 'SM'
9717 THEN
9718 -- Pricing would have solved the periodic/stub amount for only the cash flow
9719 -- level which misses it ..
9720 IF l_cash_flow_det_tbl(i).stub_days > 0 AND l_cash_flow_det_tbl(i).stub_amount IS NULL
9721 THEN
9722 l_cashflow_level_tbl(i).stub_amount := x_payment;
9723 l_cashflow_level_tbl(i).missing_pmt_flag := 'Y';
9724 ELSIF l_cash_flow_det_tbl(i).number_of_periods > 0 AND l_cash_flow_det_tbl(i).amount IS NULL
9725 THEN
9726 l_cashflow_level_tbl(i).periodic_amount := x_payment;
9727 l_cashflow_level_tbl(i).missing_pmt_flag := 'Y';
9728 END IF;
9729 END IF;
9730 l_cashflow_level_tbl(i).record_mode := 'CREATE';
9731 END LOOP;
9732 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9733 'Before calling create_cash_flow ' );
9734 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
9735 p_api_version => p_api_version,
9736 p_init_msg_list => p_init_msg_list,
9737 p_transaction_control => NULL,
9738 p_cashflow_header_rec => l_cashflow_header_rec,
9739 p_cashflow_level_tbl => l_cashflow_level_tbl,
9740 x_return_status => l_return_status,
9741 x_msg_count => x_msg_count,
9742 x_msg_data => x_msg_data);
9743 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9744 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9745 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9746 RAISE OKL_API.G_EXCEPTION_ERROR;
9747 END IF;
9748 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9749 'After calling create_cash_flow ' || l_return_status);
9750 END IF;
9751 -- When the pricing method is SP/SM update the pricing rec with the
9752 -- solved payment amount back
9753 IF quote_rec.pricing_method IN ( 'SP', 'TR' ) OR
9754 ( quote_rec.pricing_method = 'SM' AND l_missing_pmnts )
9755 THEN
9756 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9757 'Updating the Cash inflows back with the solved payment amount ' || x_payment);
9758 FOR t_in IN lx_pricing_parameter_rec.cash_inflows.FIRST ..
9759 lx_pricing_parameter_rec.cash_inflows.LAST
9760 LOOP
9761 IF lx_pricing_parameter_rec.cash_inflows(t_in).cf_miss_pay = 'Y' OR
9762 quote_rec.pricing_method IN ( 'SP', 'TR' )
9763 THEN
9764 lx_pricing_parameter_rec.cash_inflows(t_in).cf_amount := x_payment;
9765 END IF;
9766 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9767 lx_pricing_parameter_rec.cash_inflows(t_in).cf_date || ' | ' ||
9768 lx_pricing_parameter_rec.cash_inflows(t_in).cf_miss_pay || ' | ' ||
9769 lx_pricing_parameter_rec.cash_inflows(t_in).cf_amount );
9770 END LOOP;
9771 END IF;
9772 IF quote_rec.pricing_method = 'SF' AND
9773 p_price_at_lq_level = FALSE
9774 THEN
9775 lx_asset_rec.id := p_ast_id;
9776 IF (l_fee_yn = 'N')
9777 THEN
9778 -- Need to change here to call the okl_lease_quote_asset_pvt.update_asset
9779 l_asset_rec.id := p_ast_id;
9780 l_asset_rec.oec := lx_pricing_parameter_rec.financed_amount;
9781 FOR t_rec IN c_asset_comp_csr( p_asset_id => p_ast_id )
9782 LOOP
9783 l_component_tbl(1).id := t_rec.id;
9784 l_component_tbl(1).unit_cost := l_asset_rec.oec / t_rec.number_of_units;
9785 l_component_tbl(1).record_mode := 'update';
9786 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9787 'Updated l_component_tbl(1).unit_cost = ' || l_component_tbl(1).unit_cost );
9788 END LOOP;
9789 -- Call the update api to store back the calculated OEC of the Asset!
9790 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9791 'Before OKL_LEASE_QUOTE_ASSET_PVT.update_asset ');
9792 -- Instead we need to use the OKL_LEASE_QUOTE_ASSET_PVT.update_asset
9793 OKL_LEASE_QUOTE_ASSET_PVT.update_asset (
9794 p_api_version => p_api_version,
9795 p_init_msg_list => p_init_msg_list,
9796 p_transaction_control => 'T',
9797 p_asset_rec => l_asset_rec,
9798 p_component_tbl => l_component_tbl,
9799 p_cf_hdr_rec => l_cf_hdr_rec,
9800 p_cf_level_tbl => l_cf_level_tbl,
9801 x_return_status => l_return_status,
9802 x_msg_count => x_msg_count,
9803 x_msg_data => x_msg_data);
9804 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9805 'After OKL_LEASE_QUOTE_ASSET_PVT.update_asset ' || l_return_status );
9806 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
9807 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9808 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
9809 RAISE OKL_API.G_EXCEPTION_ERROR;
9810 END IF;
9811 ELSE
9812 -- Do Nothing
9813 NULL;
9814 END IF;
9815 ELSIF (quote_rec.pricing_method = 'SD' OR
9816 quote_rec.pricing_method = 'SI' OR
9817 quote_rec.pricing_method = 'SS') AND (l_fee_yn = 'N')
9818 THEN
9819 ----------------------------------------------------------------------------------
9820 -- Create an Asset Cost Adjustment for the Solved Down Payment/Trade-in/Subsidy !!
9821 ----------------------------------------------------------------------------------
9822 -- Need to populate the following !!
9823 l_ass_adj_tbl.DELETE;
9824 l_ass_adj_tbl(1).parent_object_code := 'ASSET';
9825 l_ass_adj_tbl(1).parent_object_id := p_ast_id;
9826 l_ass_adj_tbl(1).basis := 'FIXED';
9827 IF quote_rec.pricing_method = 'SI'
9828 THEN
9829 l_ass_adj_tbl(1).adjustment_source_type := 'TRADEIN';
9830 l_ass_adj_tbl(1).VALUE := lx_pricing_parameter_rec.trade_in;
9831 l_adj_type := 'Trade-in';
9832 ELSIF quote_rec.pricing_method = 'SD'
9833 THEN
9834 l_ass_adj_tbl(1).adjustment_source_type := 'DOWN_PAYMENT';
9835 l_ass_adj_tbl(1).VALUE := lx_pricing_parameter_rec.down_payment;
9836 l_adj_type := 'Down Payment';
9837 ELSIF quote_rec.pricing_method = 'SS'
9838 THEN
9839 l_ass_adj_tbl(1).adjustment_source_type := 'SUBSIDY';
9840 l_ass_adj_tbl(1).VALUE := lx_pricing_parameter_rec.subsidy;
9841 l_adj_type := 'Subsidy';
9842 END IF;
9843 IF l_ass_adj_tbl(1).VALUE < 0 THEN
9844 --Bug 5121548 dpsingh start
9845 OKL_API.SET_MESSAGE (
9846 p_app_name => G_APP_NAME,
9847 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT_ASSET',
9848 p_token1 => 'TYPE',
9849 p_token1_value => l_adj_type,
9850 p_token2 => 'AMOUNT',
9851 p_token2_value => round(l_ass_adj_tbl(1).VALUE, 2),
9852 p_token3 => 'NAME',
9853 p_token3_value => l_asset_number);
9854 --Bug 5121548 dpsingh end
9855 RAISE okl_api.g_exception_error;
9856 END IF;
9857 okl_lease_quote_asset_pvt.create_adjustment(
9858 p_api_version => p_api_version,
9859 p_init_msg_list => p_init_msg_list,
9860 p_transaction_control => FND_API.G_TRUE,
9861 p_asset_adj_tbl => l_ass_adj_tbl,
9862 x_return_status => l_return_status,
9863 x_msg_count => x_msg_count,
9864 x_msg_data => x_msg_data );
9865 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
9866 'After okl_lease_quote.asset.create_adjustment ' || l_return_status);
9867 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
9868 RAISE okl_api.g_exception_unexpected_error;
9869 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
9870 RAISE okl_api.g_exception_error;
9871 END IF;
9872 END IF; -- IF quote_rec.pricing_method .....
9873 -- Actual logic Ends here
9874 x_pricing_parameter_rec := lx_pricing_parameter_rec;
9875 x_return_status := l_return_status;
9876 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
9877 x_msg_data => x_msg_data);
9878 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
9879 'end debug OKLRPIUB.pls call ' || LOWER(l_api_name) );
9880 EXCEPTION
9881 WHEN OKL_API.G_EXCEPTION_ERROR THEN
9882 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
9883 p_api_name => l_api_name,
9884 p_pkg_name => G_PKG_NAME,
9885 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
9886 x_msg_count => x_msg_count,
9887 x_msg_data => x_msg_data,
9888 p_api_type => g_api_type);
9889 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
9890 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
9891 p_api_name => l_api_name,
9892 p_pkg_name => G_PKG_NAME,
9893 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
9894 x_msg_count => x_msg_count,
9895 x_msg_data => x_msg_data,
9896 p_api_type => g_api_type);
9897 WHEN OTHERS THEN
9898 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
9899 p_api_name => l_api_name,
9900 p_pkg_name => G_PKG_NAME,
9901 p_exc_name => 'OTHERS',
9902 x_msg_count => x_msg_count,
9903 x_msg_data => x_msg_data,
9904 p_api_type => g_api_type);
9905 END price_standard_quote_asset;
9906 --------------------------------------------------------------------------------
9907 -- Start of Commnets
9908 -- Procedure Name : is_asset_overriding
9909 -- Description :
9910 -- Business Rules :
9911 -- Parameters :
9912 -- Version : 1.0
9913 -- History : rgooty 5-Aug-2005 - created
9914 -- This is the API, which will return TRUE, if an Asset in a Lease Quote has overridden
9915 -- the Payment option defined at the quote level, otherwise if it has to follow the payment
9916 -- option at the quote level, return false !
9917 -- End of Commnets
9918 --------------------------------------------------------------------------------
9919 FUNCTION is_asset_overriding( p_qte_id IN NUMBER,
9920 p_ast_id IN NUMBER,
9921 p_lq_line_level_pricing IN VARCHAR2,
9922 p_lq_srt_id IN NUMBER,
9923 p_ast_srt_id IN NUMBER,
9924 p_lq_struct_pricing IN VARCHAR2,
9925 p_ast_struct_pricing IN VARCHAR2,
9926 p_lq_arrears_yn IN VARCHAR2,
9927 p_ast_arrears_yn IN VARCHAR2,
9928 x_return_status OUT NOCOPY VARCHAR2)
9929 RETURN BOOLEAN
9930 AS
9931 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'is_asset_overriding';
9932 l_return_status VARCHAR2(1);
9933 l_ret_value BOOLEAN;
9934 BEGIN
9935
9936 l_return_status := OKL_API.G_RET_STS_SUCCESS;
9937 l_ret_value := FALSE;
9938 IF p_lq_line_level_pricing = 'Y' AND
9939 p_lq_struct_pricing IS NULL AND
9940 p_lq_srt_id IS NULL
9941 THEN
9942 -- User opted for Line level override, havent picked Structured Pricing at Quote level
9943 -- and havent picked SRT too at quote level. This means all assets are overriding
9944 l_ret_value := TRUE;
9945 ELSIF p_lq_line_level_pricing IS NULL OR
9946 p_lq_line_level_pricing = 'N'
9947 THEN
9948 l_ret_value := FALSE;
9949 ELSIF p_lq_struct_pricing = 'Y' AND
9950 p_ast_struct_pricing = 'Y'
9951 THEN
9952 -- Case 1: Two scenarios possible here !
9953 -- Lq has a structured payment structure and Asset follows another structured payment structure
9954 IF p_lq_line_level_pricing = 'Y'
9955 THEN
9956 l_ret_value := TRUE;
9957 ELSE
9958 l_ret_value := FALSE;
9959 END IF;
9960 ELSIF p_lq_struct_pricing = 'Y' AND
9961 ( p_ast_struct_pricing = 'N' OR p_ast_srt_id IS NOT NULL )
9962 THEN
9963 -- Case 2: LQ with Structured Pricing and Asset linked to SRT
9964 l_ret_value := TRUE;
9965 ELSIF p_ast_struct_pricing = 'Y' AND
9966 ( p_lq_struct_pricing = 'N' OR p_lq_srt_id IS NOT NULL )
9967 THEN
9968 -- Case 3: LQ linked to SRT and Asset following Strucured Pricing
9969 l_ret_value := TRUE;
9970 ELSIF p_lq_srt_id IS NOT NULL AND
9971 p_ast_srt_id IS NOT NULL AND
9972 p_lq_srt_id <> p_ast_srt_id
9973 THEN
9974 -- Case 4: User picked the SRT at the quote level and at the Asset level
9975 -- also, user picked another SRT !
9976 l_ret_value := TRUE;
9977 ELSIF p_lq_srt_id IS NOT NULL AND
9978 p_ast_srt_id IS NOT NULL AND
9979 p_lq_srt_id = p_ast_srt_id AND
9980 nvl(p_lq_arrears_yn, 'N') <> nvl(p_ast_arrears_yn, 'N')
9981 THEN
9982 -- Case 5: User picked the same SRT at Quote and Asset level,
9983 -- but varied Advance/Arrears
9984 l_ret_value := TRUE;
9985 ELSIF p_lq_srt_id IS NOT NULL AND
9986 p_ast_srt_id IS NOT NULL AND
9987 p_lq_line_level_pricing = 'Y'
9988 THEN
9989 -- Case 6: User picked the same SRT at Quote and Asset level.
9990 -- Returning TRUE in this case also, as User picked the same SRT explicitly
9991 -- but enabling the Line Level Override.
9992 l_ret_value := TRUE;
9993 END IF;
9994 x_return_status := l_return_status;
9995 return l_ret_value;
9996 EXCEPTION
9997 WHEN OKL_API.G_EXCEPTION_ERROR
9998 THEN
9999 x_return_status := G_RET_STS_ERROR;
10000 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR
10001 THEN
10002 x_return_status := G_RET_STS_UNEXP_ERROR;
10003 WHEN OTHERS
10004 THEN
10005 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
10006 p_msg_name => G_DB_ERROR,
10007 p_token1 => G_PROG_NAME_TOKEN,
10008 p_token1_value => l_api_name,
10009 p_token2 => G_SQLCODE_TOKEN,
10010 p_token2_value => sqlcode,
10011 p_token3 => G_SQLERRM_TOKEN,
10012 p_token3_value => sqlerrm);
10013 x_return_status := G_RET_STS_UNEXP_ERROR;
10014 END is_asset_overriding;
10015
10016 --------------------------------------------------------------------------------
10017 -- Start of Commnets
10018 -- Procedure Name : Price_Standard_Quote
10019 -- Description :
10020 -- Business Rules :
10021 -- Parameters :
10022 -- Version : 1.0
10023 -- History : ssiruvol 22-May-2005 - created
10024 -- End of Commnets
10025 --------------------------------------------------------------------------------
10026 PROCEDURE get_lq_fee_cash_flows(
10027 p_api_version IN NUMBER,
10028 p_init_msg_list IN VARCHAR2,
10029 x_return_status OUT NOCOPY VARCHAR2,
10030 x_msg_count OUT NOCOPY NUMBER,
10031 x_msg_data OUT NOCOPY VARCHAR2,
10032 p_fee_type IN VARCHAR2,
10033 p_lq_id IN NUMBER,
10034 p_fee_id IN NUMBER,
10035 x_outflow_caf_rec OUT NOCOPY so_cash_flows_rec_type,
10036 x_outflow_cfl_tbl OUT NOCOPY so_cash_flow_details_tbl_type,
10037 x_inflow_caf_rec OUT NOCOPY so_cash_flows_rec_type,
10038 x_inflow_cfl_tbl OUT NOCOPY so_cash_flow_details_tbl_type)
10039 IS
10040 -- Cursor to fetch the Lease Quotes Cash Flow Details
10041 CURSOR lq_cash_flows_csr(
10042 p_id NUMBER,
10043 p_cf_source VARCHAR2,
10044 p_cft_code VARCHAR2)
10045 IS
10046 SELECT cf.id caf_id
10047 ,dnz_khr_id khr_id
10048 ,dnz_qte_id qte_id
10049 ,cfo_id cfo_id
10050 ,sts_code sts_code
10051 ,sty_id sty_id
10052 ,cft_code cft_code
10053 ,due_arrears_yn due_arrears_yn
10054 ,start_date start_date
10055 ,number_of_advance_periods number_of_advance_periods
10056 ,cfo.oty_code oty_code
10057 FROM OKL_CASH_FLOWS cf,
10058 OKL_CASH_FLOW_OBJECTS cfo
10059 WHERE cf.cfo_id = cfo.id
10060 AND cfo.source_table = p_cf_source
10061 AND cfo.source_id = p_id
10062 AND cf .cft_code = p_cft_code ;
10063 -- Cursor to fetch the Cash Flow Details
10064 CURSOR cash_flow_levels_csr( p_caf_id NUMBER )
10065 IS
10066 SELECT id cfl_id
10067 ,caf_id
10068 ,fqy_code
10069 ,rate -- No rate is defined at Cash Flows Level.. Need to confirm
10070 ,stub_days
10071 ,stub_amount
10072 ,number_of_periods
10073 ,amount
10074 ,start_date
10075 FROM OKL_CASH_FLOW_LEVELS
10076 WHERE caf_id = p_caf_id
10077 ORDER BY start_date;
10078
10079 l_api_version CONSTANT NUMBER DEFAULT 1.0;
10080 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_lq_fee_cash_flows';
10081 l_return_status VARCHAR2(1);
10082 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
10083 || G_PKG_NAME || '.' || UPPER(l_api_name);
10084
10085 l_debug_enabled VARCHAR2(10);
10086 is_debug_procedure_on BOOLEAN;
10087 is_debug_statement_on BOOLEAN;
10088 cfl_index NUMBER;
10089 BEGIN
10090 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10091 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
10092 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
10093 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10094 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
10095 -- check for logging on STATEMENT level
10096 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
10097 l_return_status := OKL_API.START_ACTIVITY(
10098 p_api_name => l_api_name,
10099 p_pkg_name => G_PKG_NAME,
10100 p_init_msg_list => p_init_msg_list,
10101 l_api_version => l_api_version,
10102 p_api_version => p_api_version,
10103 p_api_type => g_api_type,
10104 x_return_status => x_return_status);
10105 --Check if activity started successfully
10106 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10107 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10108 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10109 RAISE OKL_API.G_EXCEPTION_ERROR;
10110 END IF;
10111 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10112 -- Expense Fees/Miscellaneous Fees will have OUTFLOW_SCHEDULE oty_code cash flows
10113 IF p_fee_type IN ( 'EXPENSE', 'MISCELLANEOUS' )
10114 THEN
10115 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10116 '!!!!! Fetching the Expense Cash flows for fee type ' || p_fee_type );
10117 FOR t_rec IN lq_cash_flows_csr(
10118 p_id => p_fee_id,
10119 p_cf_source => 'OKL_FEES_B',
10120 p_cft_code => 'OUTFLOW_SCHEDULE')
10121 LOOP
10122 x_outflow_caf_rec.caf_id := t_rec.caf_id;
10123 x_outflow_caf_rec.khr_id := t_rec.khr_id;
10124 x_outflow_caf_rec.khr_id := t_rec.khr_id;
10125 x_outflow_caf_rec.qte_id := t_rec.qte_id;
10126 x_outflow_caf_rec.cfo_id := t_rec.cfo_id;
10127 x_outflow_caf_rec.sts_code := t_rec.sts_code;
10128 x_outflow_caf_rec.sty_id := t_rec.sty_id;
10129 x_outflow_caf_rec.cft_code := t_rec.cft_code;
10130 x_outflow_caf_rec.due_arrears_yn := t_rec.due_arrears_yn;
10131 x_outflow_caf_rec.start_date := t_rec.start_date;
10132 x_outflow_caf_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
10133 -- Use l_retun_status as a flag
10134 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10135 END LOOP;
10136 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
10137 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
10138 THEN
10139 cfl_index := 1;
10140 -- Cash Flows exists. So, fetch the Cash Flow Levels
10141 FOR t_rec in cash_flow_levels_csr( x_outflow_caf_rec.caf_id )
10142 LOOP
10143 x_outflow_cfl_tbl(cfl_index).cfl_id := t_rec.cfl_id;
10144 x_outflow_cfl_tbl(cfl_index).caf_id := t_rec.caf_id;
10145 x_outflow_cfl_tbl(cfl_index).fqy_code := t_rec.fqy_code;
10146 x_outflow_cfl_tbl(cfl_index).rate := t_rec.rate;
10147 x_outflow_cfl_tbl(cfl_index).stub_days := t_rec.stub_days;
10148 x_outflow_cfl_tbl(cfl_index).stub_amount := t_rec.stub_amount;
10149 x_outflow_cfl_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
10150 x_outflow_cfl_tbl(cfl_index).amount := t_rec.amount;
10151 x_outflow_cfl_tbl(cfl_index).start_date := t_rec.start_date;
10152 x_outflow_cfl_tbl(cfl_index).locked_amt := 'Y';
10153 -- Remember the flag whether its a stub payment or not
10154 IF t_rec.stub_days IS NOT NULL and t_rec.stub_amount IS NOT NULL
10155 THEN
10156 -- Stub Payment
10157 x_outflow_cfl_tbl(cfl_index).is_stub := 'Y';
10158 ELSE
10159 -- Regular Periodic Payment
10160 x_outflow_cfl_tbl(cfl_index).is_stub := 'N';
10161 END IF;
10162 -- Use l_retun_status as a flag
10163 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10164 -- Increment i
10165 cfl_index := cfl_index + 1;
10166 END LOOP;
10167 ELSE
10168 -- Show an error saying that no cash flow levels found
10169 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10170 '!!!!! No Cash flow levels obtained for the fee type ' || p_fee_type );
10171 OKL_API.SET_MESSAGE (
10172 p_app_name => G_APP_NAME,
10173 p_msg_name => 'OKL_AM_NO_PYMT_INFO');
10174 RAISE OKL_API.G_EXCEPTION_ERROR;
10175 END IF;
10176 END IF; -- If p_fee_type = 'EXPENSE'/'MISCELLANEOUS'
10177 -- Income Fees/Security Deposit will have PAYMENT_SCHEDULE cash flows
10178 -- Miscellaneous Fees may have an inflow PAYMENT_SCHEDULE ( Not Mandatory for Payment )
10179 IF p_fee_type IN ( 'INCOME', 'SECDEPOSIT', 'MISCELLANEOUS' )
10180 THEN
10181 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10182 '!!!!! Fetching the Income Cash flows for fee type ' || p_fee_type );
10183 l_return_status := OKL_API.G_RET_STS_ERROR;
10184 FOR t_rec IN lq_cash_flows_csr(
10185 p_id => p_fee_id,
10186 p_cf_source => 'OKL_FEES_B',
10187 p_cft_code => 'PAYMENT_SCHEDULE')
10188 LOOP
10189 x_inflow_caf_rec.caf_id := t_rec.caf_id;
10190 x_inflow_caf_rec.khr_id := t_rec.khr_id;
10191 x_inflow_caf_rec.khr_id := t_rec.khr_id;
10192 x_inflow_caf_rec.qte_id := t_rec.qte_id;
10193 x_inflow_caf_rec.cfo_id := t_rec.cfo_id;
10194 x_inflow_caf_rec.sts_code := t_rec.sts_code;
10195 x_inflow_caf_rec.sty_id := t_rec.sty_id;
10196 x_inflow_caf_rec.cft_code := t_rec.cft_code;
10197 x_inflow_caf_rec.due_arrears_yn := t_rec.due_arrears_yn;
10198 x_inflow_caf_rec.start_date := t_rec.start_date;
10199 x_inflow_caf_rec.number_of_advance_periods := t_rec.number_of_advance_periods;
10200 -- Use l_retun_status as a flag
10201 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10202 END LOOP;
10203 -- Fetch the Cash Flow Levels information only if the Cash Flow is present..
10204 IF l_return_status = OKL_API.G_RET_STS_SUCCESS
10205 THEN
10206 cfl_index := 1;
10207 -- Cash Flows exists. So, fetch the Cash Flow Levels
10208 FOR t_rec in cash_flow_levels_csr( x_inflow_caf_rec.caf_id )
10209 LOOP
10210 x_inflow_cfl_tbl(cfl_index).cfl_id := t_rec.cfl_id;
10211 x_inflow_cfl_tbl(cfl_index).caf_id := t_rec.caf_id;
10212 x_inflow_cfl_tbl(cfl_index).fqy_code := t_rec.fqy_code;
10213 x_inflow_cfl_tbl(cfl_index).rate := t_rec.rate;
10214 x_inflow_cfl_tbl(cfl_index).stub_days := t_rec.stub_days;
10215 x_inflow_cfl_tbl(cfl_index).stub_amount := t_rec.stub_amount;
10216 x_inflow_cfl_tbl(cfl_index).number_of_periods := t_rec.number_of_periods;
10217 x_inflow_cfl_tbl(cfl_index).amount := t_rec.amount;
10218 x_inflow_cfl_tbl(cfl_index).start_date := t_rec.start_date;
10219 x_inflow_cfl_tbl(cfl_index).locked_amt := 'Y';
10220 -- Remember the flag whether its a stub payment or not
10221 IF t_rec.stub_days IS NOT NULL and t_rec.stub_amount IS NOT NULL
10222 THEN
10223 -- Stub Payment
10224 x_inflow_cfl_tbl(cfl_index).is_stub := 'Y';
10225 ELSE
10226 -- Regular Periodic Payment
10227 x_inflow_cfl_tbl(cfl_index).is_stub := 'N';
10228 END IF;
10229 -- Use l_retun_status as a flag
10230 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10231 -- Increment i
10232 cfl_index := cfl_index + 1;
10233 END LOOP;
10234 ELSE
10235 -- Show an error saying that no cash flow levels found
10236 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10237 '!!!!! No Cash flow levels obtained for the fee type ' || p_fee_type );
10238 IF p_fee_type <> 'MISCELLANEOUS'
10239 THEN
10240 OKL_API.SET_MESSAGE (
10241 p_app_name => G_APP_NAME,
10242 p_msg_name => 'OKL_LLA_PMT_SELECT');
10243 RAISE OKL_API.G_EXCEPTION_ERROR;
10244 END IF;
10245 END IF;
10246 END IF; -- If p_fee_type = 'INCOME'/'SECDEPOSIT'/'MISCELLANEOUS'
10247 -- Setting up the return variables
10248 x_return_status := l_return_status;
10249 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
10250 x_msg_data => x_msg_data);
10251 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10252 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
10253 EXCEPTION
10254 WHEN OKL_API.G_EXCEPTION_ERROR THEN
10255 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10256 p_api_name => l_api_name,
10257 p_pkg_name => G_PKG_NAME,
10258 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
10259 x_msg_count => x_msg_count,
10260 x_msg_data => x_msg_data,
10261 p_api_type => g_api_type);
10262 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
10263 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10264 p_api_name => l_api_name,
10265 p_pkg_name => G_PKG_NAME,
10266 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
10267 x_msg_count => x_msg_count,
10268 x_msg_data => x_msg_data,
10269 p_api_type => g_api_type);
10270 WHEN OTHERS THEN
10271 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10272 p_api_name => l_api_name,
10273 p_pkg_name => G_PKG_NAME,
10274 p_exc_name => 'OTHERS',
10275 x_msg_count => x_msg_count,
10276 x_msg_data => x_msg_data,
10277 p_api_type => g_api_type);
10278 END get_lq_fee_cash_flows;
10279 --------------------------------------------------------------------------------
10280 -- Start of Commnets
10281 -- Procedure Name : solve_pmnts_at_lq
10282 -- Description :
10283 -- Business Rules :
10284 -- Parameters :
10285 -- Version : 1.0
10286 -- History : rgooty 6-Mar-20006 Created.
10287 -- End of Commnets
10288 --------------------------------------------------------------------------------
10289 PROCEDURE solve_pmnts_at_lq(
10290 p_api_version IN NUMBER,
10291 p_init_msg_list IN VARCHAR2,
10292 x_return_status OUT NOCOPY VARCHAR2,
10293 x_msg_count OUT NOCOPY NUMBER,
10294 x_msg_data OUT NOCOPY VARCHAR2,
10295 p_id IN NUMBER,
10296 x_caf_rec OUT NOCOPY OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type,
10297 x_cfl_tbl OUT NOCOPY OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type,
10298 x_solved OUT NOCOPY VARCHAR2)
10299 IS
10300 -- Cursor to fetch all the Assets in a Lease Quote
10301 CURSOR all_assets_csr( p_qte_id IN okl_lease_quotes_b.id%TYPE)
10302 IS
10303 SELECT ast.id ast_id,
10304 ast.asset_number ast_number
10305 FROM okl_assets_b ast,
10306 okl_lease_quotes_b qte
10307 WHERE ast.parent_object_code = 'LEASEQUOTE'
10308 AND ast.parent_object_id = qte.id
10309 AND qte.id = p_qte_id;
10310 all_assets_rec all_assets_csr%ROWTYPE;
10311 -- Cursor to fetch the payment structure defined/derieved of an asset
10312 CURSOR ast_payments_csr( p_ast_id OKL_ASSETS_B.ID%TYPE,
10313 p_qte_id OKL_LEASE_QUOTES_B.ID%TYPE)
10314 IS
10315 SELECT cfl.fqy_code frequency,
10316 caf.due_arrears_yn adv_arrears,
10317 caf.sty_id sty_id,
10318 cfl.start_date,
10319 cfl.rate,
10320 cfl.stub_days,
10321 cfl.stub_amount,
10322 cfl.number_of_periods periods,
10323 cfl.amount periodic_amount
10324 FROM okl_assets_b ast,
10325 okl_cash_flow_objects cfo,
10326 okl_cash_flows caf,
10327 okl_cash_flow_levels cfl,
10328 okl_strm_type_b sty
10329 WHERE ast.id = p_ast_id
10330 AND ast.parent_object_id = p_qte_id
10331 AND cfo.source_id = ast.id
10332 AND caf.cfo_id = cfo.id
10333 AND cfl.caf_id = caf.id
10334 AND cfo.source_table = 'OKL_ASSETS_B'
10335 AND cfo.oty_code = 'QUOTED_ASSET'
10336 AND caf.sts_code IN ( 'CURRENT', 'WORK')
10337 AND caf.sty_id = sty.id
10338 AND sty.stream_type_purpose = 'RENT'
10339 ORDER BY cfl.start_date;
10340 ast_payments_rec ast_payments_csr%ROWTYPE;
10341 -- Local Variables Declaration
10342 l_api_version CONSTANT NUMBER DEFAULT 1.0;
10343 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'solve_pmnts_at_lq';
10344 l_return_status VARCHAR2(1);
10345 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
10346 || G_PKG_NAME || '.' || UPPER(l_api_name);
10347
10348 l_debug_enabled VARCHAR2(10);
10349 is_debug_procedure_on BOOLEAN;
10350 is_debug_statement_on BOOLEAN;
10351 i NUMBER;
10352 l_first BOOLEAN;
10353 l_caf_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
10354 l_cfl_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
10355 l_solved VARCHAR2(30);
10356 BEGIN
10357 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10358 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
10359 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
10360 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10361 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
10362 -- check for logging on STATEMENT level
10363 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
10364 l_return_status := OKL_API.START_ACTIVITY(
10365 p_api_name => l_api_name,
10366 p_pkg_name => G_PKG_NAME,
10367 p_init_msg_list => p_init_msg_list,
10368 l_api_version => l_api_version,
10369 p_api_version => p_api_version,
10370 p_api_type => g_api_type,
10371 x_return_status => x_return_status);
10372 --Check if activity started successfully
10373 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10374 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10375 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10376 RAISE OKL_API.G_EXCEPTION_ERROR;
10377 END IF;
10378 -- Actual logic starts here
10379 l_first := TRUE;
10380 l_solved := 'YES';
10381 FOR ast_rec IN all_assets_csr( p_qte_id => p_id)
10382 LOOP
10383 i := 1;
10384 IF l_first
10385 THEN
10386 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10387 ' FIRST ONE : Frequency | Adv/Arrears | Rate | Days | Amount | Periods | Periodic Amount ' );
10388 FOR cfl_rec IN ast_payments_csr( p_ast_id => ast_rec.ast_id,
10389 p_qte_id => p_id)
10390 LOOP
10391 -- Store them in the Cash flows and Cash Flow Levels
10392 l_caf_rec.frequency_code := cfl_rec.frequency;
10393 l_caf_rec.arrears_flag := cfl_rec.adv_arrears;
10394 l_caf_rec.stream_type_id := cfl_rec.sty_id;
10395 l_cfl_tbl(i).record_mode := 'CREATE';
10396 l_cfl_tbl(i).start_date := cfl_rec.start_date;
10397 l_cfl_tbl(i).rate := cfl_rec.rate;
10398 l_cfl_tbl(i).stub_days := cfl_rec.stub_days;
10399 l_cfl_tbl(i).stub_amount := cfl_rec.stub_amount;
10400 l_cfl_tbl(i).periods := cfl_rec.periods;
10401 l_cfl_tbl(i).periodic_amount := cfl_rec.periodic_amount;
10402 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10403 cfl_rec.frequency || ' | ' || cfl_rec.adv_arrears || ' | ' || cfl_rec.rate || ' | ' ||
10404 cfl_rec.stub_days || ' | ' || cfl_rec.stub_amount || ' | ' ||
10405 cfl_rec.periods || ' | ' || cfl_rec.periodic_amount );
10406 i := i + 1;
10407 l_first := FALSE;
10408 END LOOP;
10409 ELSE
10410 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10411 ' Frequency | Adv/Arrears | Rate | Days | Amount | Periods | Periodic Amount ' );
10412 FOR cfl_rec IN ast_payments_csr( p_ast_id => ast_rec.ast_id,
10413 p_qte_id => p_id)
10414 LOOP
10415 -- Compare with the previous cash flow levels
10416 IF l_cfl_tbl.EXISTS(i) AND (
10417 l_caf_rec.frequency_code = cfl_rec.frequency AND
10418 nvl(l_caf_rec.arrears_flag,'N') = nvl(cfl_rec.adv_arrears, 'N') AND
10419 l_cfl_tbl(i).start_date = cfl_rec.start_date AND
10420 nvl(l_cfl_tbl(i).stub_days,-1) = nvl(cfl_rec.stub_days, -1) AND
10421 nvl(l_cfl_tbl(i).periods, -1) = nvl(cfl_rec.periods, -1) )
10422 THEN
10423 l_cfl_tbl(i).stub_amount := l_cfl_tbl(i).stub_amount + cfl_rec.stub_amount;
10424 l_cfl_tbl(i).periodic_amount := l_cfl_tbl(i).periodic_amount + cfl_rec.periodic_amount;
10425 ELSE
10426 l_solved := 'NO';
10427 EXIT;
10428 END IF;
10429 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10430 cfl_rec.frequency || ' | ' || cfl_rec.adv_arrears || ' | ' || cfl_rec.rate || ' | ' ||
10431 l_cfl_tbl(i).stub_days || ' | ' || cfl_rec.stub_amount || ' | ' ||
10432 cfl_rec.periods || ' | ' || cfl_rec.periodic_amount );
10433 i := i + 1;
10434 END LOOP; -- Loop on the ast_payments_csr
10435 END IF; -- IF l_first
10436 EXIT WHEN l_solved = 'NO';
10437 END LOOP; -- Loop on the Assets
10438 x_caf_rec := l_caf_rec;
10439 x_cfl_tbl := l_cfl_tbl;
10440 x_solved := l_solved;
10441 x_return_status := l_return_status;
10442 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
10443 x_msg_data => x_msg_data);
10444 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10445 'end debug OKLRPIUB.pls call ' || LOWER(l_api_version) );
10446 EXCEPTION
10447 WHEN OKL_API.G_EXCEPTION_ERROR THEN
10448 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10449 p_api_name => l_api_name,
10450 p_pkg_name => G_PKG_NAME,
10451 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
10452 x_msg_count => x_msg_count,
10453 x_msg_data => x_msg_data,
10454 p_api_type => g_api_type);
10455 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
10456 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10457 p_api_name => l_api_name,
10458 p_pkg_name => G_PKG_NAME,
10459 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
10460 x_msg_count => x_msg_count,
10461 x_msg_data => x_msg_data,
10462 p_api_type => g_api_type);
10463 WHEN OTHERS THEN
10464 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
10465 p_api_name => l_api_name,
10466 p_pkg_name => G_PKG_NAME,
10467 p_exc_name => 'OTHERS',
10468 x_msg_count => x_msg_count,
10469 x_msg_data => x_msg_data,
10470 p_api_type => g_api_type);
10471 END solve_pmnts_at_lq;
10472
10473 --------------------------------------------------------------------------------
10474 -- Start of Commnets
10475 -- Procedure Name : Price_Standard_Quote
10476 -- Description :
10477 -- Business Rules :
10478 -- Parameters :
10479 -- Version : 1.0
10480 -- History : ssiruvol 22-May-2005 - created
10481 -- End of Commnets
10482 --------------------------------------------------------------------------------
10483 PROCEDURE price_standard_quote(x_return_status OUT NOCOPY VARCHAR2,
10484 x_msg_count OUT NOCOPY NUMBER,
10485 x_msg_data OUT NOCOPY VARCHAR2,
10486 p_api_version IN NUMBER,
10487 p_init_msg_list IN VARCHAR2,
10488 p_qte_id IN NUMBER)
10489 IS
10490 l_api_version CONSTANT NUMBER DEFAULT 1.0;
10491 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'price_standard_quote';
10492 l_return_status VARCHAR2(1);
10493 l_module CONSTANT fnd_log_messages.module%TYPE := 'LEASE.ACCOUNTING.PRICING.'
10494 || G_PKG_NAME || '.' || UPPER(l_api_name);
10495
10496 l_debug_enabled VARCHAR2(10);
10497 is_debug_procedure_on BOOLEAN;
10498 is_debug_statement_on BOOLEAN;
10499 -- Cursors declaration !
10500 -- Cursor to fetch the Lease Quote Header details
10501 CURSOR quote_csr(qteid NUMBER)
10502 IS
10503 SELECT qte.term term,
10504 qte.pricing_method,
10505 qte.rate_template_id,
10506 qte.expected_start_date,
10507 qte.expected_delivery_date,
10508 qte.structured_pricing structured_pricing,
10509 qte.line_level_pricing line_level_pricing,
10510 qte.target_rate_type target_rate_type,
10511 qte.target_frequency target_frequency,
10512 qte.target_arrears_yn target_arrears,
10513 qte.target_rate target_rate,
10514 qte.target_periods target_periods,
10515 qte.lease_rate_factor,
10516 qte.rate_card_id,
10517 qte.id,
10518 qte.parent_object_code,
10519 qte.parent_object_id,
10520 qte.object_version_number,
10521 qte.reference_number,
10522 qte.product_id
10523 FROM okl_lease_quotes_b qte
10524 WHERE qte.id = qteid;
10525 quote_rec quote_csr%ROWTYPE;
10526
10527 CURSOR c_strm_type ( qteID NUMBER, expStartDate DATE) IS
10528 SELECT STRM.STY_ID PAYMENT_TYPE_ID,
10529 STRM.STY_NAME PAYMENT_TYPE,
10530 STRM.START_DATE,
10531 STRM.END_DATE,
10532 STRM.STY_PURPOSE
10533 FROM OKL_STRM_TMPT_PRIMARY_UV STRM,
10534 OKL_LEASE_QUOTES_B QUOTE
10535 WHERE STY_PURPOSE = 'RENT'
10536 AND START_DATE <= expStartDate
10537 AND NVL(END_DATE, expStartDate) >= expStartDate
10538 AND STRM.PDT_ID = QUOTE.PRODUCT_ID
10539 AND QUOTE.ID = qteID;
10540
10541 r_strm_type c_strm_type%ROWTYPE;
10542
10543 l_lrs_details lrs_details_rec_type;
10544 l_lrs_factor lrs_factor_rec_type;
10545 l_lrs_levels lrs_levels_tbl_type;
10546
10547 l_ac_rec_type OKL_EC_EVALUATE_PVT.okl_ac_rec_type;
10548 l_adj_factor NUMBER;
10549 l_months_per_period NUMBER;
10550 l_months_after NUMBER;
10551 cf_index NUMBER; -- Using as an index for Cash flow levels
10552 -- Cursor to fetch all the Asset and Rollover and Financed fee Details included in the Lease Quote
10553 CURSOR assets_csr(qteid NUMBER)
10554 IS
10555 SELECT ast.asset_number,
10556 ast.id ast_id,
10557 TO_NUMBER(NULL) fee_id,
10558 ast.rate_card_id,
10559 ast.rate_template_id rate_template_id,
10560 ast.structured_pricing,
10561 'FREE_FORM1' fee_type,
10562 TO_NUMBER(NULL) fee_amount,
10563 qte.expected_start_date line_start_date,
10564 qte.expected_delivery_date line_end_date,
10565 ast.lease_rate_factor lease_rate_factor,
10566 ast.target_arrears target_arrears,
10567 ast.oec_percentage oec_percentage
10568 FROM okl_assets_b ast,
10569 okl_lease_quotes_b qte
10570 WHERE ast.parent_object_code = 'LEASEQUOTE'
10571 AND ast.parent_object_id = qte.id
10572 AND qte.id = qteid
10573 UNION
10574 SELECT NULL asset_number,
10575 TO_NUMBER(NULL) ast_id,
10576 fee.id fee_id,
10577 fee.rate_card_id,
10578 fee.rate_template_id,
10579 fee.structured_pricing,
10580 fee.fee_type,
10581 fee.fee_amount,
10582 fee.effective_from line_start_date,
10583 fee.effective_to line_end_date,
10584 fee.lease_rate_factor lease_rate_factor,
10585 fee.target_arrears target_arrears,
10586 NULL oec_percentage
10587 FROM okl_fees_b fee,
10588 okl_lease_quotes_b qte
10589 WHERE fee.parent_object_code = 'LEASEQUOTE'
10590 AND fee.parent_object_id = qte.id
10591 AND qte.id = qteid;
10592 assets_rec assets_csr%ROWTYPE;
10593
10594 -- Cursor to fetch the Asset Component Details
10595 CURSOR asset_adj_csr(qteid NUMBER,
10596 astid NUMBER)
10597 IS
10598 SELECT ast.asset_number,
10599 ast.install_site_id,
10600 ast.rate_card_id,
10601 ast.rate_template_id,
10602 ast.oec,
10603 nvl(nvl(ast.end_of_term_value, ast.end_of_term_value_default),0) end_of_term_value,
10604 ast.oec_percentage,
10605 cmp.unit_cost,
10606 cmp.number_of_units,
10607 cmp.primary_component
10608 FROM okl_assets_b ast,
10609 okl_lease_quotes_b qte,
10610 okl_asset_components_b cmp
10611 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
10612 ast.parent_object_id = qte.id AND
10613 qte.id = qteid AND
10614 ast.id = astid AND
10615 cmp.primary_component = 'YES' AND
10616 cmp.asset_id = ast.id;
10617 -- Cursor to fetch the Asset Cost Adjustment Details
10618 CURSOR asset_cost_adj_csr(qteid NUMBER,
10619 astid NUMBER)
10620 IS
10621 SELECT adj.adjustment_source_type,
10622 adj.adjustment_source_id,
10623 adj.basis,
10624 -- Start : DJANASWA : Bug# 6347118
10625 nvl(adj.value,adj.default_subsidy_amount) value
10626 -- End : DJANASWA : Bug# 6347118
10627 FROM okl_assets_b ast,
10628 okl_lease_quotes_b qte,
10629 okl_cost_adjustments_b adj
10630 WHERE ast.parent_object_code = 'LEASEQUOTE' AND
10631 ast.parent_object_id = qte.id AND
10632 qte.id = qteid AND
10633 ast.id = astid AND
10634 adj.parent_object_id = ast.id;
10635
10636 Cursor subsidy_adj_csr( subId NUMBER)
10637 IS
10638 -- Bug 6622178 : Start
10639 -- Fetch the Subsidy Calculation Basis
10640 Select amount, SUBSIDY_CALC_BASIS
10641 -- Bug 6622178 : End
10642 From okl_subsidies_b
10643 where id = subId;
10644 subsidy_adj_rec subsidy_adj_csr%ROWTYPE;
10645 -- Cursor to fetch the Territory ID, Customer Credit Class
10646 CURSOR get_cust_details_csr( p_lq_id NUMBER )
10647 IS
10648 SELECT lopp.id parent_id
10649 ,lopp.prospect_id prospect_id
10650 ,lopp.cust_acct_id cust_acct_id
10651 ,lopp.sales_territory_id sales_territory_id
10652 ,lopp.currency_code currency_code
10653 FROM okl_lease_quotes_b lq,
10654 okl_lease_opportunities_b lopp
10655 WHERE parent_object_code = 'LEASEOPP'
10656 AND parent_object_id = lopp.id
10657 AND lq.id = p_lq_id;
10658
10659 CURSOR get_cust_details_csr_lapp( p_lq_id NUMBER )
10660 IS
10661 SELECT lapp.id parent_id
10662 ,lapp.prospect_id prospect_id
10663 ,lapp.cust_acct_id cust_acct_id
10664 ,lapp.sales_territory_id sales_territory_id
10665 ,lapp.currency_code currency_code
10666 FROM okl_lease_quotes_b lq,
10667 okl_lease_applications_b lapp
10668 WHERE parent_object_code = 'LEASEAPP'
10669 AND parent_object_id = lapp.id
10670 AND lq.id = p_lq_id;
10671 -- Cursor for checking whether the CFO Exists or not
10672 CURSOR check_cfo_exists_csr(
10673 p_oty_code IN VARCHAR2,
10674 p_source_table IN VARCHAR2,
10675 p_source_id IN VARCHAR2,
10676 p_sts_code IN VARCHAR2 )
10677 IS
10678 SELECT 'YES' cfo_exists,
10679 cfo.id cfo_id,
10680 caf.id caf_id
10681 FROM OKL_CASH_FLOW_OBJECTS cfo,
10682 OKL_CASH_FLOWS caf
10683 WHERE OTY_CODE = p_oty_code
10684 AND SOURCE_TABLE = p_source_table
10685 AND SOURCE_ID = p_source_id
10686 AND caf.cfo_id = cfo.id;
10687 check_cfo_exists_rec check_cfo_exists_csr%ROWTYPE;
10688 -- Cursor to fetch EOT Type
10689 CURSOR get_eot_type( p_lq_id NUMBER )
10690 IS
10691 SELECT lq.id
10692 ,lq.reference_number
10693 ,eot.end_of_term_name
10694 ,eot.eot_type_code eot_type_code
10695 ,eot.end_of_term_id end_of_term_id
10696 ,eotversion.end_of_term_ver_id
10697 FROM OKL_LEASE_QUOTES_B lq,
10698 okl_fe_eo_term_vers eotversion,
10699 okl_fe_eo_terms_all_b eot
10700 WHERE lq.END_OF_TERM_OPTION_ID = eotversion.end_of_term_ver_id
10701 AND eot.end_of_term_id = eotversion.end_of_term_id
10702 AND lq.id = p_lq_id;
10703 l_eot_type_code VARCHAR2(30);
10704 -- Cursor to handle the CAPITALIZED Fee amount for each Asset
10705 CURSOR get_asset_cap_fee_amt(p_source_type VARCHAR2,
10706 p_source_id OKL_LINE_RELATIONSHIPS_B.source_line_ID%TYPE,
10707 p_related_line_type OKL_LINE_RELATIONSHIPS_B.related_line_type%TYPE)
10708 IS
10709 SELECT SUM(amount) capitalized_amount
10710 FROM okl_line_relationships_v lre
10711 WHERE source_line_type = p_source_type
10712 AND related_line_type = 'CAPITALIZED'
10713 AND source_line_id = p_source_id;
10714
10715 --Bug 5884825 PAGARG start
10716 CURSOR product_name_csr(qteid NUMBER)
10717 IS
10718 SELECT PDT.NAME PRODUCTNAME
10719 FROM OKL_LEASE_QUOTES_B QTE
10720 , OKL_PRODUCTS PDT
10721 WHERE QTE.PRODUCT_ID = PDT.ID
10722 AND QTE.ID = qteid;
10723 --Bug 5884825 PAGARG end
10724
10725 l_product_name okl_products.NAME%TYPE;--Bug 5884825 PAGARG
10726 l_day_count_method VARCHAR2(30);
10727 l_days_in_month VARCHAR2(30);
10728 l_days_in_year VARCHAR2(30);
10729 l_currency VARCHAR2(30);
10730 l_srt_details OKL_PRICING_UTILS_PVT.srt_details_rec_type;
10731 l_ast_srt_details OKL_PRICING_UTILS_PVT.srt_details_rec_type;
10732 x_iir NUMBER;
10733 l_initial_guess NUMBER := 0.1;
10734 x_payment NUMBER;
10735 l_lq_cash_flow_rec OKL_PRICING_UTILS_PVT.so_cash_flows_rec_type; -- Quote Level Cash Flow Object
10736 l_lq_cash_flow_det_tbl OKL_PRICING_UTILS_PVT.so_cash_flow_details_tbl_type; -- Quote Level Cash Flow levels
10737 l_lq_cash_inflows OKL_PRICING_UTILS_PVT.cash_inflows_tbl_type; -- Lease Quote level Streams
10738 l_lq_pricing_parameter_rec OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
10739 l_tmp_pricing_parameter_rec OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
10740 l_pricing_parameter_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
10741 l_pp_non_sub_iir_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
10742 l_pp_non_sub_irr_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
10743 l_pp_lq_fee_srv_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
10744 l_lq_residual_inflows OKL_PRICING_UTILS_PVT.cash_inflows_tbl_type;
10745 l_overridden BOOLEAN;
10746 l_non_overiding_assets_tbl OKL_STREAMS_UTIL.NumberTabTyp;
10747 l_noa_pp_tbl OKL_PRICING_UTILS_PVT.pricing_parameter_tbl_type;
10748 lnoa_index BINARY_INTEGER;
10749 ppfs_index BINARY_INTEGER;
10750 l_eot_date DATE;
10751 l_cf_dpp NUMBER;
10752 l_cf_ppy NUMBER;
10753 res_index BINARY_INTEGER;
10754 pp_index BINARY_INTEGER;
10755 l_yields_rec yields_rec;
10756 l_subsidized_yields_rec yields_rec;
10757 l_iir_noa_dts NUMBER; -- IIR @ LQ level for Non-overriding assets considering
10758 -- Downpayment/Subsidy/Trade-In
10759 l_iir_noa NUMBER; -- IIR @ LQ level for Non-overriding assets with out
10760 -- considering Downpayment/Subsidy/Trade-In
10761 l_lq_pp_noa_dts OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
10762 l_lq_pp_noa OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
10763 l_iir_temp NUMBER;
10764 l_adj_mat_cat_rec adj_mat_cat_rec;
10765 l_ass_adj_tbl OKL_LEASE_QUOTE_ASSET_PVT.asset_adjustment_tbl_type;
10766 l_cash_flow_rec so_cash_flows_rec_type;
10767 l_cash_flow_det_tbl so_cash_flow_details_tbl_type;
10768 l_cash_inflows OKL_PRICING_UTILS_PVT.cash_inflows_tbl_type;
10769 l_lease_qte_rec OKL_LEASE_QUOTE_PVT.lease_qte_rec_type;
10770 x_lease_qte_rec OKL_LEASE_QUOTE_PVT.lease_qte_rec_type;
10771 l_lq_payment_header_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
10772 l_lq_payment_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
10773 l_cfo_exists_at_lq VARCHAR2(30);
10774 l_cfo_exists_at_noa VARCHAR2(30);
10775 l_tot_noa_oec NUMBER;
10776 l_noa_cash_flow_rec OKL_PRICING_UTILS_PVT.so_cash_flows_rec_type;
10777 l_noa_cash_flow_det_tbl OKL_PRICING_UTILS_PVT.so_cash_flow_details_tbl_type;
10778 l_noa_payment_header_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
10779 l_noa_payment_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
10780 l_fee_outflow_caf_rec so_cash_flows_rec_type;
10781 l_fee_outflow_cfl_tbl so_cash_flow_details_tbl_type;
10782 l_fee_inflow_caf_rec so_cash_flows_rec_type;
10783 l_fee_inflow_cfl_tbl so_cash_flow_details_tbl_type;
10784 l_adj_type VARCHAR2(30);
10785 l_pricing_method OKL_LEASE_QUOTES_B.PRICING_METHOD%TYPE;
10786 l_sp_for_assets BOOLEAN;
10787 l_an_ass_follow_lq BOOLEAN;
10788 l_lq_details_prc_rec OKL_PRICING_UTILS_PVT.pricing_parameter_rec_type;
10789 l_rent_sty_id OKL_STRM_TYPE_B.ID%TYPE;
10790 l_asset_caf_rec OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_header_rec_type;
10791 l_asset_cfl_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
10792 l_ast_level_fin_amt NUMBER;
10793 l_lq_level_fin_amt NUMBER;
10794 l_quote_type_code OKL_LEASE_QUOTES_B.PARENT_OBJECT_CODE%TYPE;
10795 l_solved VARCHAR2(30);
10796 l_tmp_amount NUMBER;
10797 l_lq_con_cash_inflows cash_inflows_tbl_type;
10798 l_iir NUMBER;
10799 l_miss_payment NUMBER;
10800 l_rnd_sum_assets_pmnts_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
10801 l_rnd_lq_payment_level_tbl OKL_LEASE_QUOTE_CASHFLOW_PVT.cashflow_level_tbl_type;
10802 l_sum_of_noa_oec_percent NUMBER;
10803 -- Bug 6622178 : Start
10804 l_disp_sf_msg BOOLEAN;
10805 -- Bug 6622178 : End
10806 BEGIN
10807 l_return_status := OKL_API.G_RET_STS_SUCCESS;
10808 l_debug_enabled := OKL_DEBUG_PUB.check_log_enabled;
10809 is_debug_procedure_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_PROCEDURE);
10810 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
10811 'begin debug OKLRPIUB.pls call '|| lower(l_api_name));
10812 is_debug_statement_on := OKL_DEBUG_PUB.check_log_on(l_module,FND_LOG.LEVEL_STATEMENT);
10813 l_return_status := OKL_API.START_ACTIVITY(
10814 p_api_name => l_api_name,
10815 p_pkg_name => G_PKG_NAME,
10816 p_init_msg_list => p_init_msg_list,
10817 l_api_version => l_api_version,
10818 p_api_version => p_api_version,
10819 p_api_type => g_api_type,
10820 x_return_status => l_return_status);
10821 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10822 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10823 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10824 RAISE OKL_API.G_EXCEPTION_ERROR;
10825 END IF;
10826
10827 --Bug 5884825 PAGARG start
10828 OPEN product_name_csr(p_qte_id);
10829 FETCH product_name_csr INTO l_product_name;
10830 CLOSE product_name_csr;
10831 --Bug 5884825 PAGARG end
10832
10833 -- Fetch the Lease Quote Header Details !
10834 OPEN quote_csr(p_qte_id);
10835 FETCH quote_csr INTO quote_rec;
10836 IF (quote_csr%NOTFOUND) THEN
10837 RAISE okl_api.g_exception_unexpected_error;
10838 END IF;
10839 CLOSE quote_csr;
10840 IF quote_rec.parent_object_code = 'LEASEAPP' THEN
10841 l_quote_type_code := 'LA';
10842 ELSE
10843 l_quote_type_code := 'LQ';
10844 END IF;
10845 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10846 '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ');
10847 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10848 '!!!!!!!!!!!!Pricing of ' || quote_rec.reference_number || '!!!!!!!!!!!! ');
10849 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10850 '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ');
10851 -- Derieve the End of Term Date of the Lease Quote
10852 okl_stream_generator_pvt.add_months_new(
10853 p_start_date => quote_rec.expected_start_date,
10854 p_months_after => quote_rec.term,
10855 x_date => l_eot_date,
10856 x_return_status => l_return_status);
10857 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10858 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10859 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10860 RAISE OKL_API.G_EXCEPTION_ERROR;
10861 END IF;
10862 l_eot_date := l_eot_date - 1;
10863 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10864 'Effective To of the LQ ' || l_eot_date );
10865 -- Populate the l_adj_mat_cat_rec !
10866 -- Here instead of straightly assuming that user will only pick the SRT at the
10867 -- Quote level, we should be writing an API, which will build the cash flows and cash flow levels
10868 -- if the user has picked the SRT, or otherwise the API will fetch directly from
10869 -- the Cash flows in case of User picked the Structured Pricing option ...
10870 l_adj_mat_cat_rec.target_eff_from := quote_rec.expected_start_date;
10871 l_adj_mat_cat_rec.term := quote_rec.term;
10872 IF quote_rec.parent_object_code = 'LEASEOPP'
10873 THEN
10874 -- Fetch from the Lease Opportunity
10875 FOR t_rec IN get_cust_details_csr( p_lq_id => p_qte_id )
10876 LOOP
10877 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
10878 l_adj_mat_cat_rec.customer_credit_class :=
10879 okl_lease_app_pvt.get_credit_classfication(
10880 p_party_id => t_rec.prospect_id,
10881 p_cust_acct_id => t_rec.cust_acct_id,
10882 p_site_use_id => -99);
10883 -- Store the currency now
10884 l_currency := t_rec.currency_code;
10885 END LOOP;
10886 ELSE
10887 -- Fetch from the Lease Application
10888 FOR t_rec IN get_cust_details_csr_lapp( p_lq_id => p_qte_id )
10889 LOOP
10890 l_adj_mat_cat_rec.territory := t_rec.sales_territory_id;
10891 l_adj_mat_cat_rec.customer_credit_class :=
10892 okl_lease_app_pvt.get_credit_classfication(
10893 p_party_id => t_rec.prospect_id,
10894 p_cust_acct_id => t_rec.cust_acct_id,
10895 p_site_use_id => -99);
10896 -- Store the currency now
10897 l_currency := t_rec.currency_code;
10898 END LOOP;
10899 END IF;
10900 l_adj_mat_cat_rec.deal_size := NULL; -- Dont know how to get these value !
10901 -- Know the type of the EOT
10902 FOR t_rec IN get_eot_type( p_lq_id => p_qte_id )
10903 LOOP
10904 l_eot_type_code := t_rec.eot_type_code;
10905 END LOOP;
10906 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10907 '****Currency Code = ' || l_currency || '****EOT Type ' || l_eot_type_code);
10908 IF quote_rec.pricing_method <> 'RC'
10909 THEN
10910 get_lq_cash_flows(
10911 p_api_version => p_api_version,
10912 p_init_msg_list => p_init_msg_list,
10913 x_return_status => l_return_status,
10914 x_msg_count => x_msg_count,
10915 x_msg_data => x_msg_data,
10916 p_id => p_qte_id,
10917 p_lq_srt_id => quote_rec.rate_template_id,
10918 p_cf_source => G_CF_SOURCE_LQ, -- Fetch SRT / Strucutured Pricing details at Lease Quote Level
10919 p_adj_mat_cat_rec => l_adj_mat_cat_rec,
10920 p_pricing_method => quote_rec.pricing_method,
10921 x_days_in_month => l_days_in_month,
10922 x_days_in_year => l_days_in_year,
10923 x_cash_flow_rec => l_lq_cash_flow_rec,
10924 x_cash_flow_det_tbl => l_lq_cash_flow_det_tbl);
10925 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10926 'After get_lq_cash_flows ' || l_return_status);
10927 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10928 'No. of Cash Flow Levels ' || l_lq_cash_flow_det_tbl.COUNT );
10929 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10930 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10931 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
10932 RAISE OKL_API.G_EXCEPTION_ERROR;
10933 END IF;
10934 l_cfo_exists_at_lq := 'NO';
10935 FOR t_rec IN check_cfo_exists_csr(
10936 p_oty_code => 'LEASE_QUOTE',
10937 p_source_table => 'OKL_LEASE_QUOTES_B',
10938 p_source_id => p_qte_id,
10939 p_sts_code => 'CURRENT')
10940 LOOP
10941 l_cfo_exists_at_lq := t_rec.cfo_exists;
10942 END LOOP;
10943 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10944 'After check_cfo_exists_csr. l_cfo_exists_at_lq' || l_cfo_exists_at_lq);
10945 -- Populate the l_payment_header_rec and l_payment_level_tbl structures
10946 -- CFO, CFH Population
10947 IF l_cfo_exists_at_lq = 'YES'
10948 THEN
10949 l_lq_payment_header_rec.cashflow_header_id := l_lq_cash_flow_rec.caf_id;
10950 l_lq_payment_header_rec.cashflow_object_id := l_lq_cash_flow_rec.cfo_id;
10951 l_lq_payment_header_rec.stream_type_id := l_lq_cash_flow_rec.sty_id;
10952 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10953 'Passing l_lq_payment_header_rec.cashflow_header_id ' ||
10954 l_lq_payment_header_rec.cashflow_header_id );
10955 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10956 ' l_lq_payment_header_rec.cashflow_object_id ' ||
10957 l_lq_payment_header_rec.cashflow_object_id);
10958 END IF;
10959 IF l_lq_payment_header_rec.stream_type_id IS NULL OR
10960 l_cfo_exists_at_lq = 'NO'
10961 THEN
10962 OPEN c_strm_type ( quote_rec.id, quote_rec.expected_start_date );
10963 FETCH c_strm_type INTO r_strm_type;
10964 CLOSE c_strm_type;
10965 l_lq_payment_header_rec.stream_type_id := r_strm_type.payment_type_id;
10966 END IF;
10967 -- Store the rent Stream ID
10968 l_rent_sty_id := l_lq_payment_header_rec.stream_type_id;
10969 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10970 'Fetched the RENT Stream Type ID ' || l_lq_payment_header_rec.stream_type_id
10971 || ' Quote ID ' || quote_rec.id || ' Start Date ' || quote_rec.expected_start_date );
10972 l_lq_payment_header_rec.parent_object_id := p_qte_id;
10973 l_lq_payment_header_rec.quote_id := p_qte_id;
10974 l_lq_payment_header_rec.type_code := 'INFLOW';
10975 IF l_lq_cash_flow_rec.sts_code = 'CURRENT' THEN
10976 l_lq_payment_header_rec.status_code:= 'CURRENT';
10977 ELSE
10978 l_lq_payment_header_rec.status_code:= 'WORK';
10979 END IF;
10980 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10981 '****** Cash flow status code ' || l_lq_payment_header_rec.status_code );
10982 l_lq_payment_header_rec.parent_object_code := 'LEASE_QUOTE';
10983 l_lq_payment_header_rec.arrears_flag := l_lq_cash_flow_rec.due_arrears_yn;
10984 l_lq_payment_header_rec.quote_type_code := l_quote_type_code;
10985 -- Populate the Cash flow levels
10986 IF l_lq_cash_flow_det_tbl.COUNT > 0
10987 THEN
10988 l_lq_payment_header_rec.frequency_code :=
10989 l_lq_cash_flow_det_tbl(l_lq_cash_flow_det_tbl.FIRST).fqy_code;
10990 FOR t_index IN l_lq_cash_flow_det_tbl.FIRST .. l_lq_cash_flow_det_tbl.LAST
10991 LOOP
10992 IF l_cfo_exists_at_lq = 'YES'
10993 THEN
10994 l_lq_payment_level_tbl(t_index).cashflow_level_id := l_lq_cash_flow_det_tbl(t_index).cfl_id;
10995 l_lq_payment_level_tbl(t_index).record_mode := 'UPDATE';
10996 l_lq_payment_level_tbl(t_index).cashflow_level_ovn := NULL;
10997 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
10998 ' l_lq_payment_level_tbl(t_index).cashflow_level_id ' ||
10999 l_lq_payment_level_tbl(t_index).cashflow_level_id);
11000 ELSE
11001 l_lq_payment_level_tbl(t_index).record_mode := 'CREATE';
11002 END IF;
11003 l_lq_payment_level_tbl(t_index).rate := l_lq_cash_flow_det_tbl(t_index).rate;
11004 l_lq_payment_level_tbl(t_index).stub_days := l_lq_cash_flow_det_tbl(t_index).stub_days;
11005 l_lq_payment_level_tbl(t_index).stub_amount := l_lq_cash_flow_det_tbl(t_index).stub_amount;
11006 l_lq_payment_level_tbl(t_index).periods := l_lq_cash_flow_det_tbl(t_index).number_of_periods;
11007 l_lq_payment_level_tbl(t_index).periodic_amount := l_lq_cash_flow_det_tbl(t_index).amount;
11008 l_lq_payment_level_tbl(t_index).start_date := l_lq_cash_flow_det_tbl(t_index).start_date;
11009 END LOOP;
11010 END IF;
11011 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11012 'Stored the Cash Flows in the l_lq_payment_level_tbl' );
11013 -- Populated the payment_header_rec and payment_level for use at later Stage !
11014 get_day_count_method(
11015 p_days_in_month => l_days_in_month,
11016 p_days_in_year => l_days_in_year,
11017 x_day_count_method => l_day_count_method,
11018 x_return_status => l_return_status );
11019 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11020 'Return Status | l_days_in_month | l_days_in_year | l_day_count_method ' );
11021 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11022 l_return_status || ' | ' || l_days_in_month || ' | ' || l_days_in_year || ' | ' || l_day_count_method );
11023 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11024 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11025 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11026 --Bug 5884825 PAGARG start
11027 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
11028 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
11029 p_token1 => 'PRODUCT_NAME',
11030 p_token1_value => l_product_name);
11031 --Bug 5884825 PAGARG end
11032 RAISE OKL_API.G_EXCEPTION_ERROR;
11033 END IF;
11034 -- Generate the Streams for the payment at the Quote Level !
11035 IF l_lq_cash_flow_det_tbl IS NOT NULL AND
11036 l_lq_cash_flow_det_tbl.COUNT > 0
11037 THEN
11038 -- Initialize the Strm Count to Zero
11039 gen_so_cf_strms(
11040 p_api_version => p_api_version,
11041 p_init_msg_list => p_init_msg_list,
11042 x_return_status => l_return_status,
11043 x_msg_count => x_msg_count,
11044 x_msg_data => x_msg_data,
11045 p_cash_flow_rec => l_lq_cash_flow_rec,
11046 p_cf_details_tbl => l_lq_cash_flow_det_tbl,
11047 x_cash_inflow_strms_tbl => l_lq_cash_inflows);
11048 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11049 'After gen_so_cf_strms ' || l_return_status);
11050 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11051 'Number of Stream Elements generated ' || l_lq_cash_inflows.COUNT);
11052 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11053 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11054 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11055 RAISE OKL_API.G_EXCEPTION_ERROR;
11056 END IF;
11057 -- Get the DPP and PPY inorder to populate for the Residuals Table
11058 get_dpp_ppy(
11059 p_frequency => l_lq_cash_flow_det_tbl(l_lq_cash_flow_det_tbl.FIRST).fqy_code,
11060 x_dpp => l_cf_dpp,
11061 x_ppy => l_cf_ppy,
11062 x_return_status => l_return_status );
11063 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11064 'After get_dpp_ppy ' || l_return_status );
11065 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11066 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11067 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11068 RAISE OKL_API.G_EXCEPTION_ERROR;
11069 END IF;
11070 ELSE
11071 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11072 '********** No pricing option picked @ LQ ! *******' );
11073 END IF; -- IF l_cash_flow_det_tbl.COUNT > 0
11074 END IF; -- IF pricing_method <> 'RC'
11075 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module,
11076 'price method ' || quote_rec.pricing_method, l_return_status );
11077 IF quote_rec.pricing_method = 'SP' OR
11078 quote_rec.pricing_method = 'SM'
11079 THEN
11080 -- Solve for Payment
11081 l_lq_pricing_parameter_rec.financed_amount := 0;
11082 l_lq_pricing_parameter_rec.down_payment := 0;
11083 l_lq_pricing_parameter_rec.trade_in := 0;
11084 l_lq_pricing_parameter_rec.subsidy := 0;
11085 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
11086 pp_index := 1;
11087 lnoa_index := 1;
11088 res_index := 1;
11089 l_non_overiding_assets_tbl.DELETE;
11090 -- Loop through the Assets and check price the asset seperately
11091 -- which has overriddent the payment option picked at the Quote Level
11092 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
11093 LOOP
11094 -- Check whether this Asset has overridden the Payment option defined
11095 -- at the quote level !
11096 IF assets_rec.fee_type <> 'FREE_FORM1'
11097 THEN
11098 l_overridden := TRUE;
11099 ELSE
11100 l_overridden := is_asset_overriding(
11101 p_qte_id => p_qte_id,
11102 p_ast_id => assets_rec.ast_id,
11103 p_lq_line_level_pricing => quote_rec.line_level_pricing,
11104 p_lq_srt_id => quote_rec.rate_template_id,
11105 p_ast_srt_id => assets_rec.rate_template_id,
11106 p_lq_struct_pricing => quote_rec.structured_pricing,
11107 p_ast_struct_pricing => assets_rec.structured_pricing,
11108 p_lq_arrears_yn => quote_rec.target_arrears,
11109 p_ast_arrears_yn => assets_rec.target_arrears,
11110 x_return_status => l_return_status);
11111 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11112 'After is_asset_overriding assets_rec.id =' || assets_rec.ast_id);
11113 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11114 ' l_return_status =' || l_return_status );
11115 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11116 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11117 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11118 RAISE OKL_API.G_EXCEPTION_ERROR;
11119 END IF;
11120 END IF;
11121 IF l_overridden = FALSE
11122 THEN
11123 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11124 ' Asset follows the Payment Structure defined @ Lease Quote level ' || assets_rec.asset_number );
11125 -- The current Asset is following the pricing option defined at the LQ level !
11126 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
11127 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
11128 astid => assets_rec.ast_id)
11129 LOOP
11130 -- Fetch the Asset Cost Adjustment information like ..
11131 -- Down Payment/Subsidy/Trade-in
11132 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
11133 THEN
11134 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
11135 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
11136 THEN
11137 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
11138 THEN
11139 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
11140 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
11141 CLOSE subsidy_adj_csr;
11142 -- Bug 6622178 : Start
11143 -- Consider all subsidies for the asset
11144 IF l_noa_pp_tbl.EXISTS(lnoa_index) then
11145 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(subsidy_adj_rec.amount,0);
11146 ELSE
11147 l_noa_pp_tbl(lnoa_index).subsidy := NVL(subsidy_adj_rec.amount,0);
11148 -- Bug 6622178 : End
11149 END IF;
11150 ELSE
11151 -- Bug 6622178 : Start
11152 -- Consider all subsidies for the asset
11153 IF l_noa_pp_tbl.EXISTS(lnoa_index) then
11154 l_noa_pp_tbl(lnoa_index).subsidy := NVL(l_noa_pp_tbl(lnoa_index).subsidy,0) + NVL(asset_cost_adj_rec.value,0);
11155 ELSE
11156 l_noa_pp_tbl(lnoa_index).subsidy := NVL(asset_cost_adj_rec.value,0);
11157 -- Bug 6622178 : End
11158 END IF;
11159 END IF;
11160 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
11161 THEN
11162 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
11163 END IF;
11164 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11165 'After Retrieving the Asset Cost Adjustments ');
11166 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11167 'Down Payment| Trade In | Subsidy ' );
11168 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11169 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' || l_noa_pp_tbl(lnoa_index).trade_in || ' | ' || l_noa_pp_tbl(lnoa_index).subsidy );
11170 END LOOP;
11171 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
11172 LOOP
11173 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec,0);
11174 -- Calculate the Capitalized Fee for this Asset
11175 FOR ct_rec IN get_asset_cap_fee_amt(
11176 p_source_type => 'ASSET',
11177 p_source_id => assets_rec.ast_id,
11178 p_related_line_type => 'CAPITALIZED')
11179 LOOP
11180 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
11181 END LOOP;
11182 l_lq_residual_inflows(res_index).line_number := res_index;
11183 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
11184 THEN
11185 -- Store EOT %age in terms of Decimal like 0.25 for 25%
11186 l_lq_residual_inflows(res_index).cf_amount :=
11187 nvl((asset_adj_rec.end_of_term_value /100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0);
11188 ELSE
11189 -- EOT is mentioned in terms of Amount
11190 l_lq_residual_inflows(res_index).cf_amount := nvl(asset_adj_rec.end_of_term_value, 0);
11191 END IF;
11192 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
11193 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
11194 l_lq_residual_inflows(res_index).is_stub := 'N';
11195 l_lq_residual_inflows(res_index).is_arrears := 'Y';
11196 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
11197 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
11198 -- Store the Asset Residuals in the corresponding NOA Assets table
11199 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
11200 -- Increment the res_index
11201 res_index := res_index + 1;
11202 END LOOP;
11203 -- Bug 6669429 : Start
11204 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
11205 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
11206 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
11207 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
11208 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);
11209 -- Bug 6669429 : End
11210 lnoa_index := lnoa_index + 1;
11211 ELSE -- IF l_overridden = FALSE
11212 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
11213 IF assets_rec.fee_type = 'FREE_FORM1'
11214 THEN
11215 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11216 ' Asset with ID '|| assets_rec.ast_id || ' overrides the payment structure @ LQ level' );
11217 price_standard_quote_asset(
11218 x_return_status => l_return_status,
11219 x_msg_count => x_msg_count,
11220 x_msg_data => x_msg_data,
11221 p_api_version => p_api_version,
11222 p_init_msg_list => p_init_msg_list,
11223 p_qte_id => p_qte_id,
11224 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
11225 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
11226 p_target_rate => NULL,
11227 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
11228 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11229 'After price_standard_quote_asset ' || l_return_status );
11230 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11231 RAISE okl_api.g_exception_unexpected_error;
11232 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11233 RAISE okl_api.g_exception_error;
11234 END IF;
11235 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
11236 -- Increment the pp_index
11237 pp_index := pp_index + 1;
11238 END IF;
11239 END IF;
11240 END LOOP; -- Loop on the Assets csr
11241 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11242 ' Number of Overriding Lines = ' || l_pricing_parameter_tbl.COUNT || ' | ' ||
11243 ' Number of Non-Overriding Lines = ' || l_non_overiding_assets_tbl.COUNT );
11244 IF l_non_overiding_assets_tbl.COUNT > 0
11245 THEN
11246 -- Store into Pricing Params only if there is atleast one noa assets
11247 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
11248 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
11249 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11250 ' Before Calling compute_iir to solve for payment @ LQ level ' );
11251 -- Now Solve for Payment at the Lease Quote Level using amortization logic !
11252 compute_iir(
11253 p_api_version => p_api_version,
11254 p_init_msg_list => p_init_msg_list,
11255 x_return_status => l_return_status,
11256 x_msg_count => x_msg_count,
11257 x_msg_data => x_msg_data,
11258 p_start_date => quote_rec.expected_start_date,
11259 p_day_count_method => l_day_count_method,
11260 p_pricing_method => quote_rec.pricing_method,
11261 p_initial_guess => l_initial_guess,
11262 px_pricing_parameter_rec => l_lq_pricing_parameter_rec,
11263 px_iir => x_iir,
11264 x_payment => x_payment);
11265 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11266 'After compute_iir ' || l_return_status );
11267 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11268 RAISE okl_api.g_exception_unexpected_error;
11269 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11270 RAISE okl_api.g_exception_error;
11271 END IF;
11272 IF x_payment < 0
11273 THEN
11274 OKL_API.SET_MESSAGE (
11275 p_app_name => G_APP_NAME,
11276 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
11277 p_token1 => 'TYPE',
11278 p_token1_value => 'Payment',
11279 p_token2 => 'AMOUNT',
11280 p_token2_value => round(x_payment,2) );
11281 RAISE okl_api.g_exception_error;
11282 END IF;
11283 -- Now, we need to populate back the Payment Amount back
11284 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11285 '***** **** Updating the stream elements and cash flow with the amount ' || x_payment );
11286 -- Update the Cash inflows with the Solved Amount ..
11287 FOR t_in IN l_lq_pricing_parameter_rec.cash_inflows.FIRST ..
11288 l_lq_pricing_parameter_rec.cash_inflows.LAST
11289 LOOP
11290 IF l_lq_pricing_parameter_rec.cash_inflows(t_in).cf_miss_pay = 'Y' OR
11291 quote_rec.pricing_method = 'SP'
11292 THEN
11293 l_lq_pricing_parameter_rec.cash_inflows(t_in).cf_amount := x_payment;
11294 END IF;
11295 END LOOP;
11296 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11297 'After Updating the PP_REC.cash_inflows with the solved payment amount ' || round( x_payment, 4) );
11298 -- Update the LQ Cash inflows with the Solved Payment Amount
11299 FOR t_in IN l_lq_cash_flow_det_tbl.FIRST..l_lq_cash_flow_det_tbl.LAST
11300 LOOP
11301 IF quote_rec.pricing_method = 'SP' OR
11302 (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
11303 ( 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
11304 IF l_lq_cash_flow_det_tbl(t_in).number_of_periods > 0
11305 THEN
11306 l_lq_payment_level_tbl(t_in).periodic_amount := x_payment;
11307 l_lq_payment_level_tbl(t_in).missing_pmt_flag := 'Y';
11308 ELSE
11309 l_lq_payment_level_tbl(t_in).stub_amount := x_payment;
11310 l_lq_payment_level_tbl(t_in).missing_pmt_flag := 'Y';
11311 END IF;
11312 END IF;
11313 END LOOP;
11314 -- Storing the l_lq_pricing_parameter_rec for derieving payments @ every NOA Asset Level.
11315 l_an_ass_follow_lq := TRUE; -- Store the flag
11316 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
11317 IF l_cfo_exists_at_lq = 'YES'
11318 THEN
11319 -- Delete the Cash Flow Levels which may be already created by Pricing ..
11320 okl_lease_quote_cashflow_pvt.delete_cashflows (
11321 p_api_version => p_api_version,
11322 p_init_msg_list => p_init_msg_list,
11323 p_transaction_control => NULL,
11324 p_source_object_code => 'LEASE_QUOTE',
11325 p_source_object_id => p_qte_id,
11326 x_return_status => l_return_status,
11327 x_msg_count => x_msg_count,
11328 x_msg_data => x_msg_data);
11329 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11330 ' ----- After deleting the Cash flows for the asset ' || l_return_status );
11331 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11332 RAISE okl_api.g_exception_unexpected_error;
11333 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11334 RAISE okl_api.g_exception_error;
11335 END IF;
11336 END IF;
11337 FOR cfl_index IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
11338 LOOP
11339 l_lq_payment_level_tbl(cfl_index).record_mode := 'CREATE';
11340 END LOOP;
11341 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11342 'Before creating the cash flows call' );
11343 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
11344 p_api_version => p_api_version,
11345 p_init_msg_list => p_init_msg_list,
11346 p_transaction_control => NULL,
11347 p_cashflow_header_rec => l_lq_payment_header_rec,
11348 p_cashflow_level_tbl => l_lq_payment_level_tbl,
11349 x_return_status => l_return_status,
11350 x_msg_count => x_msg_count,
11351 x_msg_data => x_msg_data);
11352 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11353 'After update_cashflow call ' || l_Return_Status );
11354 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11355 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11356 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11357 RAISE OKL_API.G_EXCEPTION_ERROR;
11358 END IF;
11359 -- pp_index is an post-assigned incremented index!
11360 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
11361 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
11362 -- Increment the pp_index
11363 pp_index := pp_index + 1;
11364 END IF;
11365 -- Store the Pricing Params to solve again for Non-Subsidized Yields
11366 -- Handling the ROLLOVER AND FINANCED FEES
11367 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
11368 LOOP
11369 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
11370 THEN
11371 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11372 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
11373 -- Price the fees ROLLOVER OR FINANCED
11374 price_standard_quote_asset(
11375 x_return_status => l_return_status,
11376 x_msg_count => x_msg_count,
11377 x_msg_data => x_msg_data,
11378 p_api_version => p_api_version,
11379 p_init_msg_list => p_init_msg_list,
11380 p_qte_id => p_qte_id,
11381 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
11382 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
11383 p_target_rate => NULL,
11384 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
11385 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11386 'After price_standard_quote_asset ' || l_return_status );
11387 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11388 RAISE okl_api.g_exception_unexpected_error;
11389 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11390 RAISE okl_api.g_exception_error;
11391 END IF;
11392 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
11393 -- Increment the pp_index
11394 pp_index := pp_index + 1;
11395 END IF;
11396 END LOOP;
11397 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
11398 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
11399 compute_irr(
11400 p_api_version => p_api_version,
11401 p_init_msg_list => p_init_msg_list,
11402 x_return_status => l_return_status,
11403 x_msg_count => x_msg_count,
11404 x_msg_data => x_msg_data,
11405 p_start_date => quote_rec.expected_start_date,
11406 p_day_count_method => l_day_count_method,
11407 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
11408 p_pricing_method => 'SY',
11409 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
11410 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
11411 px_irr => x_iir,
11412 x_payment => x_payment);
11413 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11414 '1/ After Computation of SUBSIDIZED-IIR @ LQ Level ' || l_return_status );
11415 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11416 'SOLVED FOR IIR ' || x_iir );
11417 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11418 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11419 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11420 RAISE OKL_API.G_EXCEPTION_ERROR;
11421 END IF;
11422 l_subsidized_yields_rec.iir := x_iir;
11423 l_subsidized_yields_rec.bk_yield := l_subsidized_yields_rec.iir;
11424 -- Populate the Pricing Params with all the other configuration lines
11425 -- for solving the SUBSIDIZED YIELDS @ Lease Quote Level
11426 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
11427 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
11428 LOOP
11429 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
11430 THEN
11431 -- Delete the previous fees cash flows
11432 l_fee_outflow_cfl_tbl.DELETE;
11433 l_fee_inflow_cfl_tbl.DELETE;
11434 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11435 '!!!!!! Handling fee ' || assets_rec.fee_type );
11436 get_lq_fee_cash_flows(
11437 p_api_version => p_api_version,
11438 p_init_msg_list => p_init_msg_list,
11439 x_return_status => l_return_status,
11440 x_msg_count => x_msg_count,
11441 x_msg_data => x_msg_data,
11442 p_fee_type => assets_rec.fee_type,
11443 p_lq_id => p_qte_id,
11444 p_fee_id => assets_rec.fee_id,
11445 x_outflow_caf_rec => l_fee_outflow_caf_rec,
11446 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
11447 x_inflow_caf_rec => l_fee_inflow_caf_rec,
11448 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
11449 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11450 'After get_lq_fee_cash_flows ' || l_return_status );
11451 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11452 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11453 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11454 RAISE OKL_API.G_EXCEPTION_ERROR;
11455 END IF;
11456 -- Based on the outflows/Inflows obtained generate the streams
11457 IF l_fee_outflow_cfl_tbl.COUNT > 0
11458 THEN
11459 l_cash_inflows.DELETE;
11460 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11461 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
11462 gen_so_cf_strms(
11463 p_api_version => p_api_version,
11464 p_init_msg_list => p_init_msg_list,
11465 x_return_status => l_return_status,
11466 x_msg_count => x_msg_count,
11467 x_msg_data => x_msg_data,
11468 p_cash_flow_rec => l_fee_outflow_caf_rec,
11469 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
11470 x_cash_inflow_strms_tbl => l_cash_inflows);
11471 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11472 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11473 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11474 RAISE OKL_API.G_EXCEPTION_ERROR;
11475 END IF;
11476 -- Place the information in the pricing params
11477 pp_index := pp_index + 1;
11478 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
11479 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
11480 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
11481 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
11482 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
11483 END IF;
11484 -- Based on the outflows/Inflows obtained generate the streams
11485 IF l_fee_inflow_cfl_tbl.COUNT > 0
11486 THEN
11487 l_cash_inflows.DELETE;
11488 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11489 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
11490 gen_so_cf_strms(
11491 p_api_version => p_api_version,
11492 p_init_msg_list => p_init_msg_list,
11493 x_return_status => l_return_status,
11494 x_msg_count => x_msg_count,
11495 x_msg_data => x_msg_data,
11496 p_cash_flow_rec => l_fee_inflow_caf_rec,
11497 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
11498 x_cash_inflow_strms_tbl => l_cash_inflows);
11499 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11500 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11501 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11502 RAISE OKL_API.G_EXCEPTION_ERROR;
11503 END IF;
11504 -- Place the information in the pricing params
11505 pp_index := pp_index + 1;
11506 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
11507 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
11508 THEN
11509 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
11510 ELSE
11511 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
11512 END IF;
11513 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
11514 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
11515 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
11516 END IF;
11517 END IF; -- IF on Fee_type not in ...
11518 IF assets_rec.fee_type = 'ABSORBED'
11519 THEN
11520 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11521 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
11522 -- Increment the pp_index and store the pricng params
11523 pp_index := pp_index + 1;
11524 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
11525 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
11526 END IF;
11527 END LOOP;
11528 -- Store the Pricing Params to solve again for Non-Subsidized IRR Yields
11529 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
11530 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11531 '1/ Before Computation of SUBSIDIZED-IRR @ LQ Level ' );
11532 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
11533 compute_irr(
11534 p_api_version => p_api_version,
11535 p_init_msg_list => p_init_msg_list,
11536 x_return_status => l_return_status,
11537 x_msg_count => x_msg_count,
11538 x_msg_data => x_msg_data,
11539 p_start_date => quote_rec.expected_start_date,
11540 p_day_count_method => l_day_count_method,
11541 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
11542 p_pricing_method => 'SY',
11543 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
11544 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
11545 px_irr => l_subsidized_yields_rec.pre_tax_irr,
11546 x_payment => x_payment);
11547 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11548 '1/ After Computation of SUBSIDIZED-IRR @ LQ Level ' || l_return_status );
11549 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11550 'SOLVED FOR IRR ' || l_subsidized_yields_rec.pre_tax_irr );
11551 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11552 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11553 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11554 RAISE OKL_API.G_EXCEPTION_ERROR;
11555 END IF;
11556 -- Calculation of the Non-Subsidized Yields
11557 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11558 '!!!!!!!!!! Before Computation of NON-SUBSIDIZED-IIR @ LQ Level !!!!!!!!' );
11559 -- Remove subsidy Amount and then solve the IIR now
11560 FOR t_in IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
11561 LOOP
11562 l_pp_non_sub_iir_tbl(t_in).subsidy := 0;
11563 END LOOP;
11564 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
11565 compute_irr(
11566 p_api_version => p_api_version,
11567 p_init_msg_list => p_init_msg_list,
11568 x_return_status => l_return_status,
11569 x_msg_count => x_msg_count,
11570 x_msg_data => x_msg_data,
11571 p_start_date => quote_rec.expected_start_date,
11572 p_day_count_method => l_day_count_method,
11573 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
11574 p_pricing_method => 'SY',
11575 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
11576 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
11577 px_irr => l_yields_rec.iir,
11578 x_payment => x_payment);
11579 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11580 '1/ After Computation of NON-SUBSIDIZED-IIR @ LQ Level ' || l_return_status );
11581 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11582 'SOLVED FOR NON-SUBSIDIZED-IIR ' || l_yields_rec.iir );
11583 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11584 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11585 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11586 RAISE OKL_API.G_EXCEPTION_ERROR;
11587 END IF;
11588 l_yields_rec.bk_yield := l_yields_rec.iir;
11589 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11590 '1/ Before Computation of NON-SUBSIDIZED-IRR @ LQ Level ' );
11591 FOR t_in IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
11592 LOOP
11593 l_pp_non_sub_irr_tbl(t_in).subsidy := 0;
11594 END LOOP;
11595 -- Now call the compute_irr api to solve for the IIR Yield at the Lease quote Level !
11596 compute_irr(
11597 p_api_version => p_api_version,
11598 p_init_msg_list => p_init_msg_list,
11599 x_return_status => l_return_status,
11600 x_msg_count => x_msg_count,
11601 x_msg_data => x_msg_data,
11602 p_start_date => quote_rec.expected_start_date,
11603 p_day_count_method => l_day_count_method,
11604 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
11605 p_pricing_method => 'SY',
11606 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
11607 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
11608 px_irr => l_yields_rec.pre_tax_irr,
11609 x_payment => x_payment);
11610 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11611 'After Computation of NON-SUBSIDIZED-IRR @ LQ Level ' || l_return_status );
11612 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11613 'SOLVED FOR NON-SUBSIDIZED-IRR ' || l_yields_rec.pre_tax_irr );
11614 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11615 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11616 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11617 RAISE OKL_API.G_EXCEPTION_ERROR;
11618 END IF;
11619 ELSIF quote_rec.pricing_method = 'SF'
11620 THEN
11621 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11622 ' SOLVING FOR FINANCED AMOUNT ' || l_return_status );
11623 -- End of IF p_pricing_method = 'SP' / 'SM' and begin 'SF'.
11624 -- Solve for Financed Amount
11625 l_lq_pricing_parameter_rec.financed_amount := 0;
11626 l_lq_pricing_parameter_rec.down_payment := 0;
11627 l_lq_pricing_parameter_rec.trade_in := 0;
11628 l_lq_pricing_parameter_rec.subsidy := 0;
11629 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
11630 l_sum_of_noa_oec_percent := 0;
11631 pp_index := 1;
11632 lnoa_index := 1;
11633 res_index := 1;
11634 l_non_overiding_assets_tbl.DELETE;
11635 -- Bug 6622178 : Start
11636 l_disp_sf_msg := FALSE;
11637 -- Bug 6622178 : End
11638 FOR assets_rec IN assets_csr(p_qte_id)
11639 LOOP
11640 -- Loop through all the assets !
11641 IF assets_rec.fee_type <> 'FREE_FORM1'
11642 THEN
11643 l_overridden := TRUE;
11644 ELSE
11645 l_overridden := is_asset_overriding(
11646 p_qte_id => p_qte_id,
11647 p_ast_id => assets_rec.ast_id,
11648 p_lq_line_level_pricing => quote_rec.line_level_pricing,
11649 p_lq_srt_id => quote_rec.rate_template_id,
11650 p_ast_srt_id => assets_rec.rate_template_id,
11651 p_lq_struct_pricing => quote_rec.structured_pricing,
11652 p_ast_struct_pricing => assets_rec.structured_pricing,
11653 p_lq_arrears_yn => quote_rec.target_arrears,
11654 p_ast_arrears_yn => assets_rec.target_arrears,
11655 x_return_status => l_return_status);
11656 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11657 ' Pricing method = SF | x_return_status = ' || l_return_status );
11658 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11659 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11660 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11661 RAISE OKL_API.G_EXCEPTION_ERROR;
11662 END IF;
11663 END IF;
11664 IF l_overridden = FALSE
11665 THEN
11666 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11667 ' Asset follows the Payment Structure defined @ Lease Quote level ' || assets_rec.asset_number );
11668 -- The current Asset is following the pricing option defined at the LQ level !
11669 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
11670 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
11671 astid => assets_rec.ast_id)
11672 LOOP
11673 -- Fetch the Asset Cost Adjustment information like ..
11674 -- Down Payment/Subsidy/Trade-in
11675 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
11676 THEN
11677 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
11678 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
11679 THEN
11680 -- Bug 6622178 : Start
11681 /* IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
11682 THEN
11683 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
11684 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
11685 CLOSE subsidy_adj_csr;
11686 l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
11687 ELSE
11688 l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
11689 END IF;
11690 */
11691 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
11692 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
11693 CLOSE subsidy_adj_csr;
11694 IF ( UPPER(subsidy_adj_rec.SUBSIDY_CALC_BASIS) = 'FINANCED_AMOUNT' AND
11695 asset_cost_adj_rec.value IS NULL)
11696 THEN
11697 l_disp_sf_msg := TRUE;
11698 END IF;
11699 -- Bug 6622178 : End
11700 l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
11701 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
11702 THEN
11703 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
11704 END IF;
11705 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11706 'After Retrieving the Asset Cost Adjustments ');
11707 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11708 'Down Payment| Trade In | Subsidy ' );
11709 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11710 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' || l_noa_pp_tbl(lnoa_index).trade_in || ' | ' || l_noa_pp_tbl(lnoa_index).subsidy );
11711 END LOOP;
11712 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
11713 LOOP
11714 -- Dont know how to store the financed amount here
11715 l_noa_pp_tbl(lnoa_index).financed_amount := 0;
11716 -- Calculate the Capitalized Fee for this Asset
11717 FOR ct_rec IN get_asset_cap_fee_amt(
11718 p_source_type => 'ASSET',
11719 p_source_id => assets_rec.ast_id,
11720 p_related_line_type => 'CAPITALIZED')
11721 LOOP
11722 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
11723 END LOOP;
11724 l_lq_residual_inflows(res_index).line_number := res_index;
11725 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
11726 THEN
11727 -- Store EOT %age in terms of Decimal like 0.25 for 25%
11728 l_lq_residual_inflows(res_index).cf_amount :=
11729 (asset_adj_rec.end_of_term_value /100) * (assets_rec.oec_percentage/100);
11730 -- Accumulate Assets OEC in the l_sum_of_noa_oec_percent
11731 l_sum_of_noa_oec_percent := l_sum_of_noa_oec_percent + nvl(assets_rec.oec_percentage,0);
11732 ELSE
11733 -- EOT is mentioned in terms of Amount
11734 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
11735 END IF;
11736 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
11737 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
11738 l_lq_residual_inflows(res_index).is_stub := 'N';
11739 l_lq_residual_inflows(res_index).is_arrears := 'Y';
11740 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
11741 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
11742 -- Store the Asset Residuals in the corresponding NOA Assets table
11743 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
11744 -- Increment the res_index
11745 res_index := res_index + 1;
11746 END LOOP;
11747 -- Bug 6669429 : Start
11748 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
11749 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
11750 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
11751 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
11752 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);
11753 -- Bug 6669429 : End
11754 lnoa_index := lnoa_index + 1;
11755 ELSE -- IF l_overridden = FALSE in pricing method 'SF'
11756 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
11757 IF assets_rec.fee_type = 'FREE_FORM1' --, 'ROLLOVER', 'FINANCED' )
11758 THEN
11759 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11760 ' Asset Overrides the Payment Structure defined @ Lease Quote level ' || assets_rec.asset_number );
11761 price_standard_quote_asset(
11762 x_return_status => l_return_status,
11763 x_msg_count => x_msg_count,
11764 x_msg_data => x_msg_data,
11765 p_api_version => p_api_version,
11766 p_init_msg_list => p_init_msg_list,
11767 p_qte_id => p_qte_id,
11768 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
11769 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
11770 p_target_rate => NULL,
11771 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
11772 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11773 'PM = SF | After price_Standard_quote_asset l_return_Status = '|| l_return_status );
11774 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11775 RAISE okl_api.g_exception_unexpected_error;
11776 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11777 RAISE okl_api.g_exception_error;
11778 END IF;
11779 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
11780 -- Increment the pp_index
11781 pp_index := pp_index + 1;
11782 END IF;
11783 END IF;
11784 END LOOP; -- Loop on the Assets csr
11785 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11786 ' Number of Overriding Lines = ' || l_pricing_parameter_tbl.COUNT );
11787 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11788 ' Number of Non-Overriding Lines = ' || l_non_overiding_assets_tbl.COUNT );
11789 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
11790 -- using amortization logic !
11791 IF l_non_overiding_assets_tbl.COUNT > 0
11792 THEN
11793 -- Manipulate the l_lq_residual_inflows such that the Effective EOT %age is based on
11794 -- OEC Percentage of only non-overriding Assets. Refer eg. in Bug. 5167302
11795 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' ) AND
11796 nvl(l_sum_of_noa_oec_percent,100) <> 100
11797 THEN
11798 IF l_lq_residual_inflows IS NOT NULL AND
11799 l_lq_residual_inflows.COUNT > 0
11800 THEN
11801 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11802 ' !!!! Manipulating the Effective EOT %age. l_sum_of_noa_oec_percent = ' || round(l_sum_of_noa_oec_percent, 4) );
11803 FOR r_in IN l_lq_residual_inflows.FIRST .. l_lq_residual_inflows.LAST
11804 LOOP
11805 l_lq_residual_inflows(r_in).cf_amount := l_lq_residual_inflows(r_in).cf_amount * 100 /l_sum_of_noa_oec_percent;
11806 END LOOP;
11807 END IF;
11808 IF l_noa_pp_tbl IS NOT NULL AND l_noa_pp_tbl.COUNT > 0
11809 THEN
11810 FOR t_in IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
11811 LOOP
11812 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount :=
11813 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount * 100 /l_sum_of_noa_oec_percent;
11814 END LOOP;
11815 END IF;
11816 END IF;
11817 -- If there is atleast one asset which follows the Payment Structure
11818 -- defined at Lease Quote Level, then pass the Pricing param table
11819 -- withe the Cash flows information at lease quote level else DON'T !!
11820 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
11821 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
11822 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
11823 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
11824 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11825 'SF | ------------------ Before compute_iir ------------------ ' );
11826 IF l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT'
11827 THEN
11828 l_pricing_method := 'SFP';
11829 ELSE
11830 l_pricing_method := 'SF';
11831 END IF;
11832 compute_iir(
11833 p_api_version => p_api_version,
11834 p_init_msg_list => p_init_msg_list,
11835 x_return_status => l_return_status,
11836 x_msg_count => x_msg_count,
11837 x_msg_data => x_msg_data,
11838 p_start_date => quote_rec.expected_start_date,
11839 p_day_count_method => l_day_count_method,
11840 p_pricing_method => l_pricing_method,
11841 p_initial_guess => l_initial_guess,
11842 px_pricing_parameter_rec => l_lq_pricing_parameter_rec,
11843 px_iir => x_iir,
11844 x_payment => x_payment);
11845 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11846 'Pricing method = SF | After compute_iir l_return_Status = ' || l_return_status || ' Financed Amount = ' ||
11847 round(l_lq_pricing_parameter_rec.financed_amount, 4) );
11848 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11849 RAISE okl_api.g_exception_unexpected_error;
11850 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11851 RAISE okl_api.g_exception_error;
11852 END IF;
11853 IF l_pricing_method = 'SFP'
11854 THEN
11855 l_pricing_method := 'SF'; -- Revert back the pricing method to 'SF'
11856 -- Calculate the Residual Amount for each of the Non-overridden Asset for furhter yields calculation
11857 IF l_lq_pricing_parameter_rec.residual_inflows IS NOT NULL AND
11858 l_lq_pricing_parameter_rec.residual_inflows.COUNT > 0
11859 THEN
11860 FOR t_in IN l_lq_pricing_parameter_rec.residual_inflows.FIRST ..
11861 l_lq_pricing_parameter_rec.residual_inflows.LAST
11862 LOOP
11863 l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount :=
11864 l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount *
11865 l_lq_pricing_parameter_rec.financed_amount;
11866 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11867 'l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount = ' || round(l_lq_pricing_parameter_rec.residual_inflows(t_in).cf_amount, 4) );
11868
11869 END LOOP;
11870 END IF; -- Count on Residual Table
11871 -- Calculate the Residual Amount for each of the Non-overridden Asset for pmnt calculation
11872 IF l_noa_pp_tbl IS NOT NULL AND l_noa_pp_tbl.COUNT > 0
11873 THEN
11874 FOR t_in IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
11875 LOOP
11876 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount :=
11877 l_noa_pp_tbl(t_in).residual_inflows(1).cf_amount * l_lq_pricing_parameter_rec.financed_amount;
11878 END LOOP;
11879 END IF;
11880 END IF; -- IF l_pricing_method = 'SFP'
11881 -- So, we have now already solved for financed amount at lease quote level !
11882 -- We need to distribute the solved financed amount ( which is at the LQ level )
11883 -- to individual assets !
11884 l_an_ass_follow_lq := TRUE; -- Store the flag
11885 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
11886 distribute_fin_amount_lq(
11887 p_api_version => p_api_version,
11888 p_init_msg_list => p_init_msg_list,
11889 x_return_status => l_return_status,
11890 x_msg_count => x_msg_count,
11891 x_msg_data => x_msg_data,
11892 p_lq_id => p_qte_id,
11893 p_tot_fin_amount => l_lq_pricing_parameter_rec.financed_amount);
11894 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11895 'After distribute_fin_amount_lq ' || l_return_status );
11896 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11897 RAISE okl_api.g_exception_unexpected_error;
11898 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11899 RAISE okl_api.g_exception_error;
11900 END IF;
11901 -- After compute_iir above, the l_lq_pricing_parameter_rec
11902 -- should have been populated with the appropriate values for
11903 -- Financed Amount, Down Payment, Subsidy and all
11904 -- pp_index is an post-assigned incremented index!
11905 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
11906 pp_index := pp_index + 1;
11907 -- Pricing has to create the Cash Flow levels when the Pricing option is SRT.
11908 -- So, check whether the Cash flows have been already created by the Pricing or not
11909 -- If already created, then delete and create new else, create new cash flow levels.
11910 IF quote_rec.rate_template_id IS NOT NULL
11911 THEN
11912 IF l_cfo_exists_at_lq = 'YES'
11913 THEN
11914 -- Delete the Cash Flow Levels which may be already created by Pricing ..
11915 okl_lease_quote_cashflow_pvt.delete_cashflows (
11916 p_api_version => p_api_version,
11917 p_init_msg_list => p_init_msg_list,
11918 p_transaction_control => NULL,
11919 p_source_object_code => 'LEASE_QUOTE',
11920 p_source_object_id => p_qte_id,
11921 x_return_status => l_return_status,
11922 x_msg_count => x_msg_count,
11923 x_msg_data => x_msg_data);
11924 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11925 ' ----- "SF" ---- After deleting the Cash flows @ LQ Level ' || l_return_status );
11926 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11927 RAISE okl_api.g_exception_unexpected_error;
11928 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11929 RAISE okl_api.g_exception_error;
11930 END IF;
11931 END IF;
11932 FOR cfl_index IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
11933 LOOP
11934 l_lq_payment_level_tbl(cfl_index).record_mode := 'CREATE';
11935 END LOOP;
11936 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11937 'Before creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
11938 || 'Status_code ' || l_lq_payment_header_rec.status_code );
11939 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
11940 p_api_version => p_api_version,
11941 p_init_msg_list => p_init_msg_list,
11942 p_transaction_control => NULL,
11943 p_cashflow_header_rec => l_lq_payment_header_rec,
11944 p_cashflow_level_tbl => l_lq_payment_level_tbl,
11945 x_return_status => l_return_status,
11946 x_msg_count => x_msg_count,
11947 x_msg_data => x_msg_data);
11948 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11949 'After update_cashflow call ' || l_Return_Status );
11950 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11951 'After creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
11952 || 'Status_code ' || l_lq_payment_header_rec.status_code );
11953 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
11954 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
11955 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
11956 RAISE OKL_API.G_EXCEPTION_ERROR;
11957 END IF;
11958 END IF; -- Check if Pricing Option = SRT
11959 END IF;
11960 -- Handling the ROLLOVER AND FINANCED FEES
11961 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
11962 LOOP
11963 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
11964 THEN
11965 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11966 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
11967 -- Price the fees ROLLOVER OR FINANCED
11968 price_standard_quote_asset(
11969 x_return_status => l_return_status,
11970 x_msg_count => x_msg_count,
11971 x_msg_data => x_msg_data,
11972 p_api_version => p_api_version,
11973 p_init_msg_list => p_init_msg_list,
11974 p_qte_id => p_qte_id,
11975 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
11976 p_price_at_lq_level => FALSE, -- Use Fee Level Cash flows only !
11977 p_target_rate => NULL,
11978 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
11979 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11980 'After price_standard_quote_asset ' || l_return_status );
11981 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
11982 RAISE okl_api.g_exception_unexpected_error;
11983 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
11984 RAISE okl_api.g_exception_error;
11985 END IF;
11986 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
11987 -- Increment the pp_index
11988 pp_index := pp_index + 1;
11989 END IF;
11990 END LOOP;
11991 -- Build Pricing Params for solving IIR @ LQ level
11992 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
11993 -- Now call the compute_iir api to solve the IIR @ Lease Quote Level
11994 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
11995 '!!!!!!!! Before Calculating the Subsidized IIR !!!!!!!!!!!' );
11996 compute_irr(
11997 p_api_version => p_api_version,
11998 p_init_msg_list => p_init_msg_list,
11999 x_return_status => l_return_status,
12000 x_msg_count => x_msg_count,
12001 x_msg_data => x_msg_data,
12002 p_start_date => quote_rec.expected_start_date,
12003 p_day_count_method => l_day_count_method,
12004 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12005 p_pricing_method => 'SY',
12006 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
12007 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
12008 px_irr => l_subsidized_yields_rec.iir,
12009 x_payment => x_payment);
12010 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12011 'After Calculating the Subsidized IIR ' || round(l_subsidized_yields_rec.iir, 4) );
12012 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12013 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12014 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12015 RAISE OKL_API.G_EXCEPTION_ERROR;
12016 END IF;
12017 -- Store the IIR as the Booking Yield
12018 l_subsidized_yields_rec.bk_yield := l_subsidized_yields_rec.iir;
12019 -- Now Build the pricing params table for the calculation of the
12020 -- IRR @ Lease Quote level
12021 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
12022 ppfs_index := nvl(l_pp_non_sub_irr_tbl.LAST, 0);
12023 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
12024 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
12025 LOOP
12026 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
12027 THEN
12028 -- Delete the previous fees cash flows
12029 l_fee_outflow_cfl_tbl.DELETE;
12030 l_fee_inflow_cfl_tbl.DELETE;
12031 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12032 '!!!!!! Handling fee ' || assets_rec.fee_type );
12033 get_lq_fee_cash_flows(
12034 p_api_version => p_api_version,
12035 p_init_msg_list => p_init_msg_list,
12036 x_return_status => l_return_status,
12037 x_msg_count => x_msg_count,
12038 x_msg_data => x_msg_data,
12039 p_fee_type => assets_rec.fee_type,
12040 p_lq_id => p_qte_id,
12041 p_fee_id => assets_rec.fee_id,
12042 x_outflow_caf_rec => l_fee_outflow_caf_rec,
12043 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
12044 x_inflow_caf_rec => l_fee_inflow_caf_rec,
12045 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
12046 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12047 'After get_lq_fee_cash_flows ' || l_return_status );
12048 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12049 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12050 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12051 RAISE OKL_API.G_EXCEPTION_ERROR;
12052 END IF;
12053 -- Based on the outflows/Inflows obtained generate the streams
12054 IF l_fee_outflow_cfl_tbl.COUNT > 0
12055 THEN
12056 l_cash_inflows.DELETE;
12057 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12058 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
12059 gen_so_cf_strms(
12060 p_api_version => p_api_version,
12061 p_init_msg_list => p_init_msg_list,
12062 x_return_status => l_return_status,
12063 x_msg_count => x_msg_count,
12064 x_msg_data => x_msg_data,
12065 p_cash_flow_rec => l_fee_outflow_caf_rec,
12066 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
12067 x_cash_inflow_strms_tbl => l_cash_inflows);
12068 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12069 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12070 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12071 RAISE OKL_API.G_EXCEPTION_ERROR;
12072 END IF;
12073 -- Place the information in the pricing params
12074 ppfs_index := ppfs_index + 1;
12075 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
12076 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
12077 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
12078 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
12079 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
12080 END IF;
12081 -- Based on the outflows/Inflows obtained generate the streams
12082 IF l_fee_inflow_cfl_tbl.COUNT > 0
12083 THEN
12084 l_cash_inflows.DELETE;
12085 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12086 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
12087 gen_so_cf_strms(
12088 p_api_version => p_api_version,
12089 p_init_msg_list => p_init_msg_list,
12090 x_return_status => l_return_status,
12091 x_msg_count => x_msg_count,
12092 x_msg_data => x_msg_data,
12093 p_cash_flow_rec => l_fee_inflow_caf_rec,
12094 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
12095 x_cash_inflow_strms_tbl => l_cash_inflows);
12096 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12097 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12098 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12099 RAISE OKL_API.G_EXCEPTION_ERROR;
12100 END IF;
12101 -- Place the information in the pricing params
12102 ppfs_index := ppfs_index + 1;
12103 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
12104 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
12105 THEN
12106 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'INCOME';
12107 ELSE
12108 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'SECDEPOSIT';
12109 END IF;
12110 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
12111 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
12112 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
12113 END IF;
12114 END IF; -- IF on Fee_type not in ...
12115 IF assets_rec.fee_type = 'ABSORBED'
12116 THEN
12117 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12118 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
12119 -- Increment the pp_index and store the pricng params
12120 ppfs_index := ppfs_index + 1;
12121 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
12122 l_pp_non_sub_irr_tbl(ppfs_index).financed_amount := assets_rec.fee_amount;
12123 END IF;
12124 END LOOP;
12125 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12126 'Populated the Fees and Service Pricing Params ' );
12127 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
12128 compute_irr(
12129 p_api_version => p_api_version,
12130 p_init_msg_list => p_init_msg_list,
12131 x_return_status => l_return_status,
12132 x_msg_count => x_msg_count,
12133 x_msg_data => x_msg_data,
12134 p_start_date => quote_rec.expected_start_date,
12135 p_day_count_method => l_day_count_method,
12136 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12137 p_pricing_method => 'SY',
12138 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
12139 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
12140 px_irr => l_subsidized_yields_rec.pre_tax_irr,
12141 x_payment => x_payment);
12142 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12143 'After Calculating the Subsidized IRR ' || round(l_subsidized_yields_rec.pre_tax_irr, 4) );
12144 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12145 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12146 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12147 RAISE OKL_API.G_EXCEPTION_ERROR;
12148 END IF;
12149 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12150 '!!!!!!!!!!! NON-SUBSIDIZIED YIELDS CALCULATION !!!!!!!!!!!' );
12151 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12152 'Removing subsidy from the l_pp_non_sub_iir_tbl ' );
12153 FOR t IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
12154 LOOP
12155 IF l_pp_non_sub_iir_tbl(t).line_type = 'FREE_FORM1'
12156 THEN
12157 l_pp_non_sub_iir_tbl(t).subsidy := 0;
12158 END IF;
12159 END LOOP;
12160 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12161 'Before calculating the IIR ( NON-SUBSIDY ) ' );
12162 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
12163 compute_irr(
12164 p_api_version => p_api_version,
12165 p_init_msg_list => p_init_msg_list,
12166 x_return_status => l_return_status,
12167 x_msg_count => x_msg_count,
12168 x_msg_data => x_msg_data,
12169 p_start_date => quote_rec.expected_start_date,
12170 p_day_count_method => l_day_count_method,
12171 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12172 p_pricing_method => 'SY',
12173 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
12174 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
12175 px_irr => l_yields_rec.iir,
12176 x_payment => x_payment);
12177 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12178 'After Calculating the NON-Subsidized IIR ' || round(l_yields_rec.pre_tax_irr, 4) );
12179 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12180 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12181 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12182 RAISE OKL_API.G_EXCEPTION_ERROR;
12183 END IF;
12184 l_yields_rec.bk_yield := l_yields_rec.iir;
12185 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12186 'Removing subsidy from the l_pp_non_sub_irr_tbl ' );
12187 FOR t IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
12188 LOOP
12189 IF l_pp_non_sub_irr_tbl(t).line_type = 'FREE_FORM1'
12190 THEN
12191 l_pp_non_sub_irr_tbl(t).subsidy := 0;
12192 END IF;
12193 END LOOP;
12194 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12195 'Before calculating the IIR ( NON-SUBSIDY ) ' );
12196 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
12197 compute_irr(
12198 p_api_version => p_api_version,
12199 p_init_msg_list => p_init_msg_list,
12200 x_return_status => l_return_status,
12201 x_msg_count => x_msg_count,
12202 x_msg_data => x_msg_data,
12203 p_start_date => quote_rec.expected_start_date,
12204 p_day_count_method => l_day_count_method,
12205 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12206 p_pricing_method => 'SY',
12207 p_initial_guess => l_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
12208 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
12209 px_irr => l_yields_rec.pre_tax_irr,
12210 x_payment => x_payment);
12211 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12212 'After Calculating the NON-Subsidized IRR ' || round(l_yields_rec.pre_tax_irr, 4) );
12213 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12214 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12215 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12216 RAISE OKL_API.G_EXCEPTION_ERROR;
12217 END IF;
12218 IF (l_disp_sf_msg) THEN
12219 OKL_API.SET_MESSAGE (
12220 p_app_name => G_APP_NAME,
12221 p_msg_name => 'OKL_UNSUB_RATES_SF');
12222 END IF;
12223 ELSIF quote_rec.pricing_method = 'SI' OR
12224 quote_rec.pricing_method = 'SD' OR
12225 quote_rec.pricing_method = 'SS'
12226 THEN
12227 -- End of IF p_pricing_method = 'SF' and begin SI/SD/SS
12228 l_lq_pricing_parameter_rec.financed_amount := 0;
12229 l_lq_pricing_parameter_rec.down_payment := 0;
12230 l_lq_pricing_parameter_rec.trade_in := 0;
12231 l_lq_pricing_parameter_rec.subsidy := 0;
12232 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
12233 pp_index := 1;
12234 lnoa_index := 1;
12235 res_index := 1;
12236 l_non_overiding_assets_tbl.DELETE;
12237 -- Loop through all the Assets !
12238 FOR assets_rec IN assets_csr(p_qte_id)
12239 LOOP
12240 If assets_rec.fee_type <> 'FREE_FORM1'
12241 THEN
12242 l_overridden := TRUE;
12243 ELSE
12244 l_overridden := is_asset_overriding(
12245 p_qte_id => p_qte_id,
12246 p_ast_id => assets_rec.ast_id,
12247 p_lq_line_level_pricing => quote_rec.line_level_pricing,
12248 p_lq_srt_id => quote_rec.rate_template_id,
12249 p_ast_srt_id => assets_rec.rate_template_id,
12250 p_lq_struct_pricing => quote_rec.structured_pricing,
12251 p_ast_struct_pricing => assets_rec.structured_pricing,
12252 p_lq_arrears_yn => quote_rec.target_arrears,
12253 p_ast_arrears_yn => assets_rec.target_arrears,
12254 x_return_status => l_return_status);
12255 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12256 'PM = SS/SD/ST | After is_asset_overriding | l_return_status = ' ||
12257 l_return_status || ' | Asset ID = ' || assets_rec.ast_id );
12258 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12259 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12260 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12261 RAISE OKL_API.G_EXCEPTION_ERROR;
12262 END IF;
12263 END IF;
12264 IF l_overridden = FALSE
12265 THEN
12266 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12267 'This configuration line follows payment defined @ LQ level !!' );
12268 -- Storing the non overriding assets for future
12269 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
12270 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
12271 astid => assets_rec.ast_id)
12272 LOOP
12273 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE AND
12274 quote_rec.pricing_method <> 'SD'
12275 THEN
12276 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
12277 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE AND
12278 quote_rec.pricing_method <> 'SS'
12279 THEN
12280 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
12281 THEN
12282 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
12283 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
12284 CLOSE subsidy_adj_csr;
12285 l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
12286 ELSE
12287 l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
12288 END IF;
12289 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE AND
12290 quote_rec.pricing_method <> 'SI'
12291 THEN
12292 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0 );
12293 END IF;
12294 END LOOP;
12295 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
12296 LOOP
12297 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec,0);
12298 -- Calculate the Capitalized Fee for this Asset
12299 FOR ct_rec IN get_asset_cap_fee_amt(
12300 p_source_type => 'ASSET',
12301 p_source_id => assets_rec.ast_id,
12302 p_related_line_type => 'CAPITALIZED')
12303 LOOP
12304 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
12305 END LOOP;
12306 l_lq_residual_inflows(res_index).line_number := res_index;
12307 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
12308 THEN
12309 -- EOT = OEC * EOT %age /100;
12310 l_lq_residual_inflows(res_index).cf_amount :=
12311 nvl((asset_adj_rec.end_of_term_value/100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0);
12312 ELSE
12313 -- EOT is an amount so directly store it ..
12314 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
12315 END IF;
12316 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
12317 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
12318 l_lq_residual_inflows(res_index).is_stub := 'N';
12319 l_lq_residual_inflows(res_index).is_arrears := 'Y';
12320 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
12321 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
12322 -- Store the Asset Residuals in the corresponding NOA Assets table
12323 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
12324 -- Increment the res_index
12325 res_index := res_index + 1;
12326 END LOOP;
12327 -- Bug 6669429 : Start
12328 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
12329 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
12330 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
12331 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
12332 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);
12333 -- Bug 6669429 : End
12334 -- Increment the lnoa_index
12335 lnoa_index := lnoa_index + 1;
12336 ELSE -- IF l_overridden = FALSE
12337 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
12338 IF assets_rec.fee_type = 'FREE_FORM1'
12339 THEN
12340 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12341 'Asset with ID ' || assets_rec.ast_id || ' is overriding the payment structure defined @ LQ level !!' );
12342 price_standard_quote_asset(
12343 x_return_status => l_return_status,
12344 x_msg_count => x_msg_count,
12345 x_msg_data => x_msg_data,
12346 p_api_version => p_api_version,
12347 p_init_msg_list => p_init_msg_list,
12348 p_qte_id => p_qte_id,
12349 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
12350 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
12351 p_target_rate => NULL,
12352 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
12353 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12354 'Pricing method = ' || quote_rec.pricing_method || ' | After price_standard_quote_asset l_return_status = ' || l_return_status ||
12355 ' | assets_rec.ast_id = ' || assets_rec.ast_id );
12356 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12357 RAISE okl_api.g_exception_unexpected_error;
12358 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12359 RAISE okl_api.g_exception_error;
12360 END IF;
12361 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
12362 -- Increment the pp_index
12363 pp_index := pp_index + 1;
12364 END IF;
12365 END IF;
12366 END LOOP; -- Loop on the Assets csr
12367 -- Now Solve for Subsidy/Trade in/Down Payment at the Lease Quote Level
12368 -- using amortization logic for assets which doesnot override the payment structure
12369 -- at lease quote level !
12370 IF l_non_overiding_assets_tbl.COUNT > 0
12371 THEN
12372 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
12373 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
12374 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
12375 -- Step 1: Solve for DownPayment/Subsidy/Trade-in @ Lease Quote Level
12376 -- Using payment structures defined @ LQ !
12377 compute_iir(
12378 p_api_version => p_api_version,
12379 p_init_msg_list => p_init_msg_list,
12380 x_return_status => l_return_status,
12381 x_msg_count => x_msg_count,
12382 x_msg_data => x_msg_data,
12383 p_start_date => quote_rec.expected_start_date,
12384 p_day_count_method => l_day_count_method,
12385 p_pricing_method => quote_rec.pricing_method,
12386 p_initial_guess => l_initial_guess,
12387 px_pricing_parameter_rec => l_lq_pricing_parameter_rec,
12388 px_iir => x_iir,
12389 x_payment => x_payment);
12390 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12391 'Pricing Method =' || quote_rec.pricing_method || ' | 1/ After compute_iir at LQ level l_return_status = ' || l_return_status );
12392 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12393 'Financed Amount | Down Payment | Subsidy Amount | Trade In Amount | CAP Fee Amt ' );
12394 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12395 round(l_lq_pricing_parameter_rec.financed_amount, 4 ) || ' | ' || round(l_lq_pricing_parameter_rec.down_payment, 4)
12396 || ' | ' || round(l_lq_pricing_parameter_rec.subsidy, 4) || ' | ' || round(l_lq_pricing_parameter_rec.trade_in, 4)
12397 || ' | ' || round(l_lq_pricing_parameter_rec.cap_fee_amount, 4));
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 l_an_ass_follow_lq := TRUE; -- Store the flag
12404 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
12405 -- By now, we have solved for the Down Payment/Subsidy/Tradein @ LQ Level !
12406 -- Now calculate the IIR at the LQ Level. Here, we have to just consider those
12407 -- assets only which follow the payment structured defined at LQ level !
12408 -- l_lq_pricing_parameter_rec will be now updated with the solved
12409 -- DownPayment/Subsidy/Trade In
12410 -- Calculating the IIR at LQ level ( including only assets which follows the payment structure
12411 -- defined at the asset, 'coz there can be multiple paymnet levels in the payment structure !!
12412 l_lq_pp_noa_dts := l_lq_pricing_parameter_rec;
12413 -- Proportionate the Solved Down Payment/Subsidy/TradeIn Amount now
12414 -- based on the Asset OEC ! -- TBD
12415 l_tot_noa_oec := 0;
12416 FOR t_index IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
12417 LOOP
12418 l_tot_noa_oec := l_tot_noa_oec + nvl( l_noa_pp_tbl(t_index).financed_amount, 0 );
12419 END LOOP;
12420 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12421 'SUM( OEC ) of non-overriding Assets ' || round( l_tot_noa_oec , 4 ));
12422 FOR t_index IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
12423 LOOP
12424 ----------------------------------------------------------------------------------
12425 -- Create an Asset Cost Adjustment for the Solved Down Payment/Trade-in/Subsidy !!
12426 ----------------------------------------------------------------------------------
12427 l_ass_adj_tbl.DELETE;
12428 l_ass_adj_tbl(1).parent_object_code := 'ASSET';
12429 l_ass_adj_tbl(1).parent_object_id := l_non_overiding_assets_tbl(t_index); -- Asset ID
12430 l_ass_adj_tbl(1).basis := 'FIXED';
12431 IF quote_rec.pricing_method = 'SI'
12432 THEN
12433 l_ass_adj_tbl(1).adjustment_source_type := 'TRADEIN';
12434 l_ass_adj_tbl(1).VALUE := l_lq_pp_noa_dts.trade_in *
12435 l_noa_pp_tbl(t_index).financed_amount/ l_tot_noa_oec;
12436 l_noa_pp_tbl(t_index).trade_in := l_ass_adj_tbl(1).VALUE;
12437 l_adj_type := 'Trade-in';
12438 ELSIF quote_rec.pricing_method = 'SD'
12439 THEN
12440 l_ass_adj_tbl(1).adjustment_source_type := 'DOWN_PAYMENT';
12441 l_ass_adj_tbl(1).VALUE := l_lq_pp_noa_dts.down_payment *
12442 l_noa_pp_tbl(t_index).financed_amount/ l_tot_noa_oec;
12443 l_noa_pp_tbl(t_index).down_payment := l_ass_adj_tbl(1).VALUE;
12444 l_adj_type := 'Down Payment';
12445 ELSIF quote_rec.pricing_method = 'SS'
12446 THEN
12447 l_ass_adj_tbl(1).adjustment_source_type := 'SUBSIDY';
12448 l_ass_adj_tbl(1).VALUE := l_lq_pp_noa_dts.subsidy *
12449 l_noa_pp_tbl(t_index).financed_amount/ l_tot_noa_oec;
12450 l_noa_pp_tbl(t_index).subsidy := l_ass_adj_tbl(1).VALUE;
12451 l_adj_type := 'Subsidy';
12452 END IF;
12453 IF l_ass_adj_tbl(1).VALUE < 0
12454 THEN
12455 OKL_API.SET_MESSAGE (
12456 p_app_name => G_APP_NAME,
12457 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
12458 p_token1 => 'TYPE',
12459 p_token1_value => l_adj_type,
12460 p_token2 => 'AMOUNT',
12461 p_token2_value => round(l_ass_adj_tbl(1).VALUE,2));
12462 RAISE okl_api.g_exception_error;
12463 END IF;
12464 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12465 'Asset ID | Cost | Down Payment | Subsidy | Trade In ' );
12466 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12467 l_ass_adj_tbl(1).parent_object_id || ' | ' ||
12468 round( l_noa_pp_tbl(t_index).financed_amount , 4 ) || ' | ' ||
12469 round( l_noa_pp_tbl(t_index).down_payment , 4 ) || ' | ' ||
12470 round( l_noa_pp_tbl(t_index).subsidy , 4 ) || ' | ' ||
12471 round( l_noa_pp_tbl(t_index).trade_in , 4 ) );
12472 -- Create/Update the Solved Financial Adjustment
12473 okl_lease_quote_asset_pvt.create_adjustment(
12474 p_api_version => p_api_version,
12475 p_init_msg_list => p_init_msg_list,
12476 p_transaction_control => FND_API.G_TRUE,
12477 p_asset_adj_tbl => l_ass_adj_tbl,
12478 x_return_status => l_return_status,
12479 x_msg_count => x_msg_count,
12480 x_msg_data => x_msg_data );
12481 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12482 'After okl_lease_quote.asset.create_adjustment ' || l_return_status);
12483 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12484 RAISE okl_api.g_exception_unexpected_error;
12485 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12486 RAISE okl_api.g_exception_error;
12487 END IF;
12488 END LOOP; -- Loop on the Non-overriding Assets
12489 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
12490 -- pp_index is an post-assigned incremented index!
12491 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
12492 pp_index := pp_index + 1;
12493 -- Pricing has to create the Cash Flow levels when the Pricing option is SRT @ LQ level.
12494 -- So, check whether the Cash flows have been already created by the Pricing or not
12495 -- If already created, then delete and create new else, create new cash flow levels.
12496 IF quote_rec.rate_template_id IS NOT NULL
12497 THEN
12498 IF l_cfo_exists_at_lq = 'YES'
12499 THEN
12500 -- Delete the Cash Flow Levels which may be already created by Pricing ..
12501 okl_lease_quote_cashflow_pvt.delete_cashflows (
12502 p_api_version => p_api_version,
12503 p_init_msg_list => p_init_msg_list,
12504 p_transaction_control => NULL,
12505 p_source_object_code => 'LEASE_QUOTE',
12506 p_source_object_id => p_qte_id,
12507 x_return_status => l_return_status,
12508 x_msg_count => x_msg_count,
12509 x_msg_data => x_msg_data);
12510 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12511 ' ----- "SD/SS/ST" ---- After deleting the Cash flows @ LQ Level ' || l_return_status );
12512 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12513 RAISE okl_api.g_exception_unexpected_error;
12514 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12515 RAISE okl_api.g_exception_error;
12516 END IF;
12517 END IF;
12518 FOR cfl_index IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
12519 LOOP
12520 l_lq_payment_level_tbl(cfl_index).record_mode := 'CREATE';
12521 END LOOP;
12522 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12523 'Before creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
12524 || 'Status_code ' || l_lq_payment_header_rec.status_code );
12525 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
12526 p_api_version => p_api_version,
12527 p_init_msg_list => p_init_msg_list,
12528 p_transaction_control => NULL,
12529 p_cashflow_header_rec => l_lq_payment_header_rec,
12530 p_cashflow_level_tbl => l_lq_payment_level_tbl,
12531 x_return_status => l_return_status,
12532 x_msg_count => x_msg_count,
12533 x_msg_data => x_msg_data);
12534 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12535 'After update_cashflow call ' || l_Return_Status );
12536 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12537 'After creating the cash flows call ' || 'Sty_id ' || l_lq_payment_header_rec.stream_type_id
12538 || 'Status_code ' || l_lq_payment_header_rec.status_code );
12539 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12540 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12541 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12542 RAISE OKL_API.G_EXCEPTION_ERROR;
12543 END IF;
12544 END IF; -- Check if Pricing Option = SRT
12545 END IF; -- IF noa count > 0
12546 -- Fetch the ROLLOVER and Financed Fees Information
12547 FOR assets_rec IN assets_csr(p_qte_id)
12548 LOOP
12549 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED' )
12550 THEN
12551 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12552 ' Pricing for fee type ' || assets_rec.fee_type );
12553 price_standard_quote_asset(
12554 x_return_status => l_return_status,
12555 x_msg_count => x_msg_count,
12556 x_msg_data => x_msg_data,
12557 p_api_version => p_api_version,
12558 p_init_msg_list => p_init_msg_list,
12559 p_qte_id => p_qte_id,
12560 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
12561 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
12562 p_target_rate => NULL,
12563 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
12564 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12565 'Pricing method = ' || quote_rec.pricing_method ||
12566 ' | After price_standard_quote_asset l_return_status = ' || l_return_status ||
12567 ' | assets_rec.ast_id = ' || assets_rec.ast_id );
12568 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12569 RAISE okl_api.g_exception_unexpected_error;
12570 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12571 RAISE okl_api.g_exception_error;
12572 END IF;
12573 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
12574 -- Increment the pp_index
12575 pp_index := pp_index + 1;
12576 END IF;
12577 END LOOP; -- FOR assets_rec IN assets_csr(p_qte_id)
12578 -- Store the Pricing Params for later use
12579 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
12580 ----------------------------------------------------------------------
12581 -- Compute the IIR @ Lease quote level, considering all the Assets !
12582 ----------------------------------------------------------------------
12583 compute_irr(
12584 p_api_version => p_api_version,
12585 p_init_msg_list => p_init_msg_list,
12586 x_return_status => l_return_status,
12587 x_msg_count => x_msg_count,
12588 x_msg_data => x_msg_data,
12589 p_start_date => quote_rec.expected_start_date,
12590 p_day_count_method => l_day_count_method,
12591 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12592 p_pricing_method => 'SY',
12593 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
12594 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
12595 px_irr => x_iir,
12596 x_payment => x_payment);
12597 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12598 'After Calculating the Subsidized IIR ' || round(x_iir, 4) );
12599 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12600 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12601 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12602 RAISE OKL_API.G_EXCEPTION_ERROR;
12603 END IF;
12604 l_subsidized_yields_rec.iir := x_iir;
12605 l_subsidized_yields_rec.bk_yield := x_iir;
12606 -- Fetching the Fees and Service Information for the calculation of the
12607 -- Pre-tax Internal Rate of Return
12608 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
12609 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
12610 LOOP
12611 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
12612 THEN
12613 -- Delete the previous fees cash flows
12614 l_fee_outflow_cfl_tbl.DELETE;
12615 l_fee_inflow_cfl_tbl.DELETE;
12616 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12617 '!!!!!! Handling fee ' || assets_rec.fee_type );
12618 get_lq_fee_cash_flows(
12619 p_api_version => p_api_version,
12620 p_init_msg_list => p_init_msg_list,
12621 x_return_status => l_return_status,
12622 x_msg_count => x_msg_count,
12623 x_msg_data => x_msg_data,
12624 p_fee_type => assets_rec.fee_type,
12625 p_lq_id => p_qte_id,
12626 p_fee_id => assets_rec.fee_id,
12627 x_outflow_caf_rec => l_fee_outflow_caf_rec,
12628 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
12629 x_inflow_caf_rec => l_fee_inflow_caf_rec,
12630 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
12631 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12632 'After get_lq_fee_cash_flows ' || l_return_status );
12633 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12634 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12635 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12636 RAISE OKL_API.G_EXCEPTION_ERROR;
12637 END IF;
12638 -- Based on the outflows/Inflows obtained generate the streams
12639 IF l_fee_outflow_cfl_tbl.COUNT > 0
12640 THEN
12641 l_cash_inflows.DELETE;
12642 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12643 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
12644 gen_so_cf_strms(
12645 p_api_version => p_api_version,
12646 p_init_msg_list => p_init_msg_list,
12647 x_return_status => l_return_status,
12648 x_msg_count => x_msg_count,
12649 x_msg_data => x_msg_data,
12650 p_cash_flow_rec => l_fee_outflow_caf_rec,
12651 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
12652 x_cash_inflow_strms_tbl => l_cash_inflows);
12653 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12654 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12655 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12656 RAISE OKL_API.G_EXCEPTION_ERROR;
12657 END IF;
12658 -- Place the information in the pricing params
12659 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
12660 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
12661 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
12662 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
12663 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
12664 pp_index := pp_index + 1;
12665 END IF;
12666 -- Based on the outflows/Inflows obtained generate the streams
12667 IF l_fee_inflow_cfl_tbl.COUNT > 0
12668 THEN
12669 l_cash_inflows.DELETE;
12670 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12671 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
12672 gen_so_cf_strms(
12673 p_api_version => p_api_version,
12674 p_init_msg_list => p_init_msg_list,
12675 x_return_status => l_return_status,
12676 x_msg_count => x_msg_count,
12677 x_msg_data => x_msg_data,
12678 p_cash_flow_rec => l_fee_inflow_caf_rec,
12679 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
12680 x_cash_inflow_strms_tbl => l_cash_inflows);
12681 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12682 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12683 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12684 RAISE OKL_API.G_EXCEPTION_ERROR;
12685 END IF;
12686 -- Place the information in the pricing params
12687 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
12688 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
12689 THEN
12690 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
12691 ELSE
12692 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
12693 END IF;
12694 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
12695 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
12696 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
12697 pp_index := pp_index + 1;
12698 END IF;
12699 END IF; -- IF on Fee_type not in ...
12700 IF assets_rec.fee_type = 'ABSORBED'
12701 THEN
12702 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12703 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
12704 -- Increment the pp_index and store the pricng params
12705 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
12706 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
12707 pp_index := pp_index + 1;
12708 END IF;
12709 END LOOP;
12710 -- Store the Pricing Params for calculation of Non-subsidized IRR
12711 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
12712 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
12713 compute_irr(
12714 p_api_version => p_api_version,
12715 p_init_msg_list => p_init_msg_list,
12716 x_return_status => l_return_status,
12717 x_msg_count => x_msg_count,
12718 x_msg_data => x_msg_data,
12719 p_start_date => quote_rec.expected_start_date,
12720 p_day_count_method => l_day_count_method,
12721 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12722 p_pricing_method => 'SY',
12723 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
12724 px_pricing_parameter_tbl => l_pricing_parameter_tbl,
12725 px_irr => l_subsidized_yields_rec.pre_tax_irr,
12726 x_payment => x_payment);
12727 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12728 'After Calculating the Subsidized IRR ' || round(l_subsidized_yields_rec.pre_tax_irr, 4) );
12729 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12730 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12731 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12732 RAISE OKL_API.G_EXCEPTION_ERROR;
12733 END IF;
12734 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12735 '!!!!!!!!!!! NON-SUBSIDIZIED YIELDS CALCULATION !!!!!!!!!!!' );
12736 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12737 'Removing subsidy from the l_pp_non_sub_iir_tbl ' );
12738 FOR t IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
12739 LOOP
12740 IF l_pp_non_sub_iir_tbl(t).line_type = 'FREE_FORM1'
12741 THEN
12742 l_pp_non_sub_iir_tbl(t).subsidy := 0;
12743 END IF;
12744 END LOOP;
12745 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12746 'Before calculating the IIR ( NON-SUBSIDY ) ' );
12747 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
12748 compute_irr(
12749 p_api_version => p_api_version,
12750 p_init_msg_list => p_init_msg_list,
12751 x_return_status => l_return_status,
12752 x_msg_count => x_msg_count,
12753 x_msg_data => x_msg_data,
12754 p_start_date => quote_rec.expected_start_date,
12755 p_day_count_method => l_day_count_method,
12756 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12757 p_pricing_method => 'SY',
12758 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
12759 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
12760 px_irr => l_yields_rec.iir,
12761 x_payment => x_payment);
12762 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12763 'After Calculating the NON-Subsidized IIR ' || round(l_yields_rec.pre_tax_irr, 4) );
12764 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12765 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12766 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12767 RAISE OKL_API.G_EXCEPTION_ERROR;
12768 END IF;
12769 l_yields_rec.bk_yield := l_yields_rec.iir;
12770 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12771 'Removing subsidy from the l_pp_non_sub_irr_tbl ' );
12772 FOR t IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
12773 LOOP
12774 IF l_pp_non_sub_irr_tbl(t).line_type = 'FREE_FORM1'
12775 THEN
12776 l_pp_non_sub_irr_tbl(t).subsidy := 0;
12777 END IF;
12778 END LOOP;
12779 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12780 'Before calculating the IIR ( NON-SUBSIDY ) ' );
12781 -- Now call the compute_irr api to solve for the IIR @ LQ Level !
12782 compute_irr(
12783 p_api_version => p_api_version,
12784 p_init_msg_list => p_init_msg_list,
12785 x_return_status => l_return_status,
12786 x_msg_count => x_msg_count,
12787 x_msg_data => x_msg_data,
12788 p_start_date => quote_rec.expected_start_date,
12789 p_day_count_method => l_day_count_method,
12790 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
12791 p_pricing_method => 'SY',
12792 p_initial_guess => l_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
12793 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
12794 px_irr => l_yields_rec.pre_tax_irr,
12795 x_payment => x_payment);
12796 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12797 'After Calculating the NON-Subsidized IRR ' || round(l_yields_rec.pre_tax_irr, 4) );
12798 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12799 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12800 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12801 RAISE OKL_API.G_EXCEPTION_ERROR;
12802 END IF;
12803 ELSIF quote_rec.pricing_method = 'TR'
12804 THEN
12805 -- Target for rate, which is IIR !
12806 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
12807 l_lq_pricing_parameter_rec.financed_amount := 0;
12808 l_lq_pricing_parameter_rec.down_payment := 0;
12809 l_lq_pricing_parameter_rec.trade_in := 0;
12810 l_lq_pricing_parameter_rec.subsidy := 0;
12811 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
12812 pp_index := 1;
12813 lnoa_index := 1;
12814 res_index := 1;
12815 l_non_overiding_assets_tbl.DELETE;
12816 -- Loop through the Assets and check price the asset seperately
12817 -- which has overriddent the payment option picked at the Quote Level
12818 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
12819 LOOP
12820 -- Check whether this Asset has overridden the Payment option defined
12821 -- at the quote level !
12822 IF ( assets_rec.fee_type <> 'FREE_FORM1' )
12823 THEN
12824 -- For financed fee/Rollover fee its not yet clear ..but
12825 -- pricing needs to solve the payments for them for sure !
12826 l_overridden := TRUE;
12827 ELSE
12828 -- All assets in TR pricing method follow the pricing option picked at lease quote
12829 l_overridden := FALSE;
12830 END IF;
12831 IF l_overridden = FALSE
12832 THEN
12833 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12834 ' Asset Follows the Payment Structure @ Lease Quote Level ' || assets_rec.asset_number );
12835 -- If asset is not overriding the Payment option defined at the Quote Level ...
12836 -- Store the Asset Id for later use ..
12837 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
12838 -- Fetch the Asset Cost Adjustment Details for each Asset and accumulate them
12839 -- in the lx_pricing_parameter_rec
12840 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
12841 astid => assets_rec.ast_id)
12842 LOOP
12843 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
12844 THEN
12845 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
12846 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
12847 THEN
12848 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
12849 THEN
12850 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
12851 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
12852 CLOSE subsidy_adj_csr;
12853 l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
12854 ELSE
12855 l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
12856 END IF;
12857 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
12858 THEN
12859 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
12860 END IF;
12861 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12862 'After Retrieving the Asset Cost Adjustments ');
12863 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12864 'Down Payment| Trade In | Subsidy ' );
12865 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12866 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' || l_noa_pp_tbl(lnoa_index).trade_in || ' | ' ||
12867 l_noa_pp_tbl(lnoa_index).subsidy );
12868 END LOOP;
12869 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
12870 LOOP
12871 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec,0);
12872 -- Calculate the Capitalized Fee for this Asset
12873 FOR ct_rec IN get_asset_cap_fee_amt(
12874 p_source_type => 'ASSET',
12875 p_source_id => assets_rec.ast_id,
12876 p_related_line_type => 'CAPITALIZED')
12877 LOOP
12878 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
12879 END LOOP;
12880 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12881 'Unit Cost=' || asset_adj_rec.unit_cost || ' No. of Units ' || asset_adj_rec.number_of_units);
12882 l_lq_residual_inflows(res_index).line_number := res_index;
12883 l_lq_residual_inflows(res_index).line_number := res_index;
12884 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
12885 THEN
12886 -- EOT = OEC * EOT %age /100;
12887 l_lq_residual_inflows(res_index).cf_amount :=
12888 nvl((asset_adj_rec.end_of_term_value/100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0);
12889 ELSE
12890 -- EOT is an amount so directly store it ..
12891 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
12892 END IF;
12893 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
12894 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
12895 l_lq_residual_inflows(res_index).is_stub := 'N';
12896 l_lq_residual_inflows(res_index).is_arrears := 'Y';
12897 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
12898 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
12899 -- Store the Asset Residuals in the corresponding NOA Assets table
12900 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
12901 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12902 'Financed Amount = ' || l_noa_pp_tbl(lnoa_index).financed_amount);
12903 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12904 'Storing residual amt ' || l_lq_residual_inflows(res_index).cf_amount );
12905 -- Increment the res_index
12906 res_index := res_index + 1;
12907 END LOOP;
12908 -- Bug 6669429 : Start
12909 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
12910 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
12911 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
12912 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
12913 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);
12914 -- Bug 6669429 : End
12915 lnoa_index := lnoa_index + 1;
12916 END IF;
12917 END LOOP; -- Loop on the Assets csr
12918 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
12919 -- at the Lease Quote Header Level
12920 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
12921 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
12922 l_an_ass_follow_lq := TRUE; -- Store the flag
12923 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
12924 -- Extract and preserve the Fees and Other Information and
12925 -- store it in l_pp_lq_fee_srv_tbl
12926 l_pp_non_sub_iir_tbl.DELETE;
12927 l_pp_non_sub_iir_tbl(1) := l_lq_pricing_parameter_rec;
12928 ppfs_index := 1; -- Only one pricing parameter rec would have been built
12929 -- Need to derieve the Payment for the FINANCED/ROLLOVER Fees.
12930 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
12931 LOOP
12932 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
12933 THEN
12934 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12935 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
12936 -- Price the fees ROLLOVER OR FINANCED
12937 price_standard_quote_asset(
12938 x_return_status => l_return_status,
12939 x_msg_count => x_msg_count,
12940 x_msg_data => x_msg_data,
12941 p_api_version => p_api_version,
12942 p_init_msg_list => p_init_msg_list,
12943 p_qte_id => p_qte_id,
12944 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
12945 p_price_at_lq_level => TRUE, -- Use Asset Level Cash flows only !
12946 p_target_rate => quote_rec.target_rate / 100,
12947 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
12948 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12949 'After price_standard_quote_asset ' || l_return_status );
12950 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
12951 RAISE okl_api.g_exception_unexpected_error;
12952 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
12953 RAISE okl_api.g_exception_error;
12954 END IF;
12955 FOR t_in IN l_tmp_pricing_parameter_rec.cash_inflows.FIRST ..
12956 l_tmp_pricing_parameter_rec.cash_inflows.LAST
12957 LOOP
12958 l_tmp_pricing_parameter_rec.cash_inflows(t_in).locked_amt := 'Y';
12959 END LOOP;
12960 -- Store the ROLLOVER/FINANCED Fee PP Rec in the l_pp_non_sub_iir_tbl
12961 ppfs_index := ppfs_index + 1;
12962 l_pp_non_sub_iir_tbl(ppfs_index) := l_tmp_pricing_parameter_rec;
12963 END IF;
12964 END LOOP;
12965 l_pp_non_sub_irr_tbl.DELETE;
12966 l_pp_non_sub_irr_tbl := l_pp_non_sub_iir_tbl;
12967 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
12968 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
12969 LOOP
12970 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
12971 THEN
12972 -- Delete the previous fees cash flows
12973 l_fee_outflow_cfl_tbl.DELETE;
12974 l_fee_inflow_cfl_tbl.DELETE;
12975 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12976 '!!!!!! Handling fee ' || assets_rec.fee_type );
12977 get_lq_fee_cash_flows(
12978 p_api_version => p_api_version,
12979 p_init_msg_list => p_init_msg_list,
12980 x_return_status => l_return_status,
12981 x_msg_count => x_msg_count,
12982 x_msg_data => x_msg_data,
12983 p_fee_type => assets_rec.fee_type,
12984 p_lq_id => p_qte_id,
12985 p_fee_id => assets_rec.fee_id,
12986 x_outflow_caf_rec => l_fee_outflow_caf_rec,
12987 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
12988 x_inflow_caf_rec => l_fee_inflow_caf_rec,
12989 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
12990 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
12991 'After get_lq_fee_cash_flows ' || l_return_status );
12992 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
12993 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
12994 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
12995 RAISE OKL_API.G_EXCEPTION_ERROR;
12996 END IF;
12997 -- Based on the outflows/Inflows obtained generate the streams
12998 IF l_fee_outflow_cfl_tbl.COUNT > 0
12999 THEN
13000 l_cash_inflows.DELETE;
13001 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13002 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
13003 IF quote_rec.target_rate_type = 'PIRR'
13004 THEN
13005 FOR t_in IN l_fee_outflow_cfl_tbl.FIRST ..l_fee_outflow_cfl_tbl.LAST
13006 LOOP
13007 l_fee_outflow_cfl_tbl(t_in).rate := quote_rec.target_rate;
13008 END LOOP;
13009 END IF;
13010 gen_so_cf_strms(
13011 p_api_version => p_api_version,
13012 p_init_msg_list => p_init_msg_list,
13013 x_return_status => l_return_status,
13014 x_msg_count => x_msg_count,
13015 x_msg_data => x_msg_data,
13016 p_cash_flow_rec => l_fee_outflow_caf_rec,
13017 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
13018 x_cash_inflow_strms_tbl => l_cash_inflows);
13019 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13020 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13021 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13022 RAISE OKL_API.G_EXCEPTION_ERROR;
13023 END IF;
13024 -- Place the information in the pricing params
13025 ppfs_index := ppfs_index + 1;
13026 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
13027 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
13028 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
13029 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
13030 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
13031 END IF;
13032 -- Based on the outflows/Inflows obtained generate the streams
13033 IF l_fee_inflow_cfl_tbl.COUNT > 0
13034 THEN
13035 l_cash_inflows.DELETE;
13036 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13037 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
13038 IF quote_rec.target_rate_type = 'PIRR'
13039 THEN
13040 FOR t_in IN l_fee_inflow_cfl_tbl.FIRST ..l_fee_inflow_cfl_tbl.LAST
13041 LOOP
13042 l_fee_inflow_cfl_tbl(t_in).rate := quote_rec.target_rate;
13043 END LOOP;
13044 END IF;
13045 gen_so_cf_strms(
13046 p_api_version => p_api_version,
13047 p_init_msg_list => p_init_msg_list,
13048 x_return_status => l_return_status,
13049 x_msg_count => x_msg_count,
13050 x_msg_data => x_msg_data,
13051 p_cash_flow_rec => l_fee_inflow_caf_rec,
13052 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
13053 x_cash_inflow_strms_tbl => l_cash_inflows);
13054 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13055 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13056 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13057 RAISE OKL_API.G_EXCEPTION_ERROR;
13058 END IF;
13059 -- Place the information in the pricing params
13060 ppfs_index := ppfs_index + 1;
13061 l_pp_non_sub_irr_tbl(ppfs_index).line_type := assets_rec.fee_type;
13062 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
13063 THEN
13064 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'INCOME';
13065 ELSE
13066 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'SECDEPOSIT';
13067 END IF;
13068 l_pp_non_sub_irr_tbl(ppfs_index).line_start_date := assets_rec.line_start_date;
13069 l_pp_non_sub_irr_tbl(ppfs_index).line_end_date := assets_rec.line_end_date;
13070 l_pp_non_sub_irr_tbl(ppfs_index).cash_inflows := l_cash_inflows;
13071 END IF;
13072 END IF; -- IF on Fee_type not in ...
13073 IF assets_rec.fee_type = 'ABSORBED'
13074 THEN
13075 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13076 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
13077 -- Increment the pp_index and store the pricng params
13078 ppfs_index := ppfs_index + 1;
13079 l_pp_non_sub_irr_tbl(ppfs_index).payment_type := 'EXPENSE';
13080 l_pp_non_sub_irr_tbl(ppfs_index).financed_amount := assets_rec.fee_amount;
13081 END IF;
13082 END LOOP;-- FOR LOOP ON Assets_csr
13083 -- Solve for the Payment
13084 IF quote_rec.target_rate_type = 'IIR'
13085 THEN
13086 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13087 'Calling the IIR api to solve the payment amount ' );
13088 -- Now solve the Payment amount calling the compute_irr
13089 compute_irr(
13090 p_api_version => p_api_version,
13091 p_init_msg_list => p_init_msg_list,
13092 x_return_status => l_return_status,
13093 x_msg_count => x_msg_count,
13094 x_msg_data => x_msg_data,
13095 p_start_date => quote_rec.expected_start_date,
13096 p_day_count_method => l_day_count_method,
13097 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13098 p_pricing_method => quote_rec.pricing_method,
13099 p_initial_guess => l_initial_guess, -- Use the IIR derieved prev. as initial guess
13100 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
13101 px_irr => x_iir,
13102 x_payment => x_payment);
13103 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13104 RAISE okl_api.g_exception_unexpected_error;
13105 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13106 RAISE okl_api.g_exception_error;
13107 END IF;
13108 -- IIR @ LQ level has already been given by the user itself ..
13109 -- So, we wont be calling the compute_irr api just passing the assets information.
13110 l_subsidized_yields_rec.iir := quote_rec.target_rate / 100;
13111 l_subsidized_yields_rec.bk_yield := l_subsidized_yields_rec.iir;
13112 ELSE
13113 compute_irr(
13114 p_api_version => p_api_version,
13115 p_init_msg_list => p_init_msg_list,
13116 x_return_status => l_return_status,
13117 x_msg_count => x_msg_count,
13118 x_msg_data => x_msg_data,
13119 p_start_date => quote_rec.expected_start_date,
13120 p_day_count_method => l_day_count_method,
13121 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13122 p_pricing_method => quote_rec.pricing_method,
13123 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
13124 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
13125 px_irr => l_subsidized_yields_rec.pre_tax_irr,
13126 x_payment => x_payment);
13127 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13128 quote_rec.pricing_method || ': FINAL: After compute_irr ' || l_return_status );
13129 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13130 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13131 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13132 RAISE OKL_API.G_EXCEPTION_ERROR;
13133 END IF;
13134 l_subsidized_yields_rec.pre_tax_irr := quote_rec.target_rate / 100;
13135 END IF;
13136 IF x_payment < 0
13137 THEN
13138 OKL_API.SET_MESSAGE (
13139 p_app_name => G_APP_NAME,
13140 p_msg_name => 'OKL_NEGATIVE_ADJ_AMT',
13141 p_token1 => 'TYPE',
13142 p_token1_value => 'Payment',
13143 p_token2 => 'AMOUNT',
13144 p_token2_value => round(x_payment,2) );
13145 RAISE okl_api.g_exception_error;
13146 END IF;
13147 -- Store the Calculated Payment amount back in the quote Header
13148 l_lease_qte_rec.target_amount := x_payment;
13149 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13150 'SOLVED TARGET AMOUNT ' || round(l_lease_qte_rec.target_amount,4) );
13151 -- Pricing need to create CFO, CFH, CFL @ Lease Quote level storing this
13152 -- targetted Amount
13153 -- When the pricing method is Target Rate, pricing will create cash flows with
13154 -- only one cash flow level always, which is a regular payment. Hence, updating the CFL
13155 -- with the solved amount.
13156 FOR t_in IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
13157 LOOP
13158 l_lq_payment_level_tbl(t_in).periodic_amount := x_payment;
13159 END LOOP;
13160 IF l_cfo_exists_at_lq = 'YES'
13161 THEN
13162 -- Update the CFL Table
13163 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13164 'Before OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow l_lq_payment_header_rec '
13165 || l_lq_payment_header_rec.stream_type_id
13166 || ' status_code ' || l_lq_payment_header_rec.status_code );
13167 OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow (
13168 p_api_version => G_API_VERSION,
13169 p_init_msg_list => p_init_msg_list,
13170 p_transaction_control => G_FALSE,
13171 p_cashflow_header_rec => l_lq_payment_header_rec,
13172 p_cashflow_level_tbl => l_lq_payment_level_tbl,
13173 x_return_status => l_return_status,
13174 x_msg_count => x_msg_count,
13175 x_msg_data => x_msg_data);
13176 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13177 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow ' || l_return_status );
13178 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13179 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.update_cashflow l_lq_payment_header_rec '
13180 || l_lq_payment_header_rec.stream_type_id
13181 || ' status_code ' || l_lq_payment_header_rec.status_code );
13182 IF l_return_status = G_RET_STS_UNEXP_ERROR THEN
13183 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13184 ELSIF l_return_status = G_RET_STS_ERROR THEN
13185 RAISE OKL_API.G_EXCEPTION_ERROR;
13186 END IF;
13187 ELSE
13188 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13189 'Before OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow l_lq_payment_header_rec '
13190 || l_lq_payment_header_rec.stream_type_id
13191 || ' status_code ' || l_lq_payment_header_rec.status_code );
13192 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow (
13193 p_api_version => p_api_version,
13194 p_init_msg_list => p_init_msg_list,
13195 p_transaction_control => G_FALSE,
13196 p_cashflow_header_rec => l_lq_payment_header_rec,
13197 p_cashflow_level_tbl => l_lq_payment_level_tbl,
13198 x_return_status => l_return_status,
13199 x_msg_count => x_msg_count,
13200 x_msg_data => x_msg_data);
13201 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13202 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow ' || l_return_status );
13203 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13204 'After OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow l_lq_payment_header_rec '
13205 || l_lq_payment_header_rec.stream_type_id
13206 || ' status_code ' || l_lq_payment_header_rec.status_code );
13207 IF l_return_status = G_RET_STS_UNEXP_ERROR THEN
13208 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13209 ELSIF l_return_status = G_RET_STS_ERROR THEN
13210 RAISE OKL_API.G_EXCEPTION_ERROR;
13211 END IF;
13212 END IF;
13213 -- Update pmnt. amount in l_pp_non_sub_iir_tbl(1).cash_inflows and l_pp_non_sub_irr_tbl(1).cash_inflows
13214 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13215 '***** Updating the stream elements with the solved amount *****');
13216 FOR t IN l_pp_non_sub_iir_tbl(1).cash_inflows.FIRST ..
13217 l_pp_non_sub_iir_tbl(1).cash_inflows.LAST
13218 LOOP
13219 -- Update the Cash Inflow Streams for the FREE_FORM1 line !
13220 l_pp_non_sub_iir_tbl(1).cash_inflows(t).cf_amount := x_payment;
13221 l_pp_non_sub_irr_tbl(1).cash_inflows(t).cf_amount := x_payment;
13222 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13223 l_pp_non_sub_iir_tbl(1).cash_inflows(t).cf_date || ' | ' ||
13224 l_pp_non_sub_iir_tbl(1).cash_inflows(t).cf_amount );
13225 END LOOP;
13226 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13227 'Updated the Payment amount back in the Cash Inflows ');
13228 -- Need to solve for the IIR if Target_Rate is PIRR else Solve for IRR if
13229 -- target rate type is IIR
13230 IF quote_rec.target_rate_type = 'IIR'
13231 THEN
13232 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13233 '******** Solving for the Subsidized IRR ********** ' );
13234 compute_irr(
13235 p_api_version => p_api_version,
13236 p_init_msg_list => p_init_msg_list,
13237 x_return_status => l_return_status,
13238 x_msg_count => x_msg_count,
13239 x_msg_data => x_msg_data,
13240 p_start_date => quote_rec.expected_start_date,
13241 p_day_count_method => l_day_count_method,
13242 p_currency_code => l_currency,
13243 p_pricing_method => 'SY',
13244 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13245 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl,
13246 px_irr => l_subsidized_yields_rec.pre_tax_irr,
13247 x_payment => x_payment);
13248 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13249 quote_rec.pricing_method || ': FINAL: After compute_irr ' || l_return_status );
13250 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13251 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13252 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13253 RAISE OKL_API.G_EXCEPTION_ERROR;
13254 END IF;
13255 ELSE
13256 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13257 '******** Solving for the Subsidized IIR ********** ' );
13258 -- Now solve the Payment amount calling the compute_iir
13259 compute_irr(
13260 p_api_version => p_api_version,
13261 p_init_msg_list => p_init_msg_list,
13262 x_return_status => l_return_status,
13263 x_msg_count => x_msg_count,
13264 x_msg_data => x_msg_data,
13265 p_start_date => quote_rec.expected_start_date,
13266 p_day_count_method => l_day_count_method,
13267 p_currency_code => l_currency,
13268 p_pricing_method => 'SY',
13269 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
13270 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl,
13271 px_irr => x_iir,
13272 x_payment => x_payment);
13273 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13274 RAISE okl_api.g_exception_unexpected_error;
13275 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13276 RAISE okl_api.g_exception_error;
13277 END IF;
13278 -- IIR @ LQ level has already been given by the user itself ..
13279 -- So, we wont be calling the compute_irr api just passing the assets information.
13280 l_subsidized_yields_rec.iir := x_iir;
13281 l_subsidized_yields_rec.bk_yield := x_iir;
13282 END IF;
13283 -- Solve for the Non-Subsidized Yields now
13284 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13285 '!!!!!!!!!!!!! SOLVING FOR NON-SUBSIDIZED YIELDS NOW !!!!!!!!!!!!!!!!! ' );
13286 -- Loop through the l_pp_non_sub_iir_tbl table and make the Subsidy Amount to zero !
13287 FOR ny IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
13288 LOOP
13289 -- line_type, subsidy
13290 l_pp_non_sub_iir_tbl(ny).subsidy := 0;
13291 END LOOP;
13292 compute_irr(
13293 p_api_version => p_api_version,
13294 p_init_msg_list => p_init_msg_list,
13295 x_return_status => l_return_status,
13296 x_msg_count => x_msg_count,
13297 x_msg_data => x_msg_data,
13298 p_start_date => quote_rec.expected_start_date,
13299 p_day_count_method => l_day_count_method,
13300 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13301 p_pricing_method => 'SY',
13302 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13303 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
13304 px_irr => l_yields_rec.iir,
13305 x_payment => x_payment);
13306 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13307 '1/ After Computation of IIR (NON-SUBSIDIZED) ' || l_return_status );
13308 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13309 'SOLVED FOR IIR (NON-SUBSIDY)' || x_iir );
13310 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13311 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13312 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13313 RAISE OKL_API.G_EXCEPTION_ERROR;
13314 END IF;
13315 -- Store the IIR as the Booking Yield
13316 l_yields_rec.bk_yield := l_yields_rec.iir;
13317 -- Loop through the l_pp_non_sub_iir_tbl table and make the Subsidy Amount to zero !
13318 FOR ny IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
13319 LOOP
13320 -- line_type, subsidy
13321 l_pp_non_sub_irr_tbl(ny).subsidy := 0;
13322 END LOOP;
13323 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
13324 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13325 '1/ Before Computation of IRR @ LQ Level ' );
13326 compute_irr(
13327 p_api_version => p_api_version,
13328 p_init_msg_list => p_init_msg_list,
13329 x_return_status => l_return_status,
13330 x_msg_count => x_msg_count,
13331 x_msg_data => x_msg_data,
13332 p_start_date => quote_rec.expected_start_date,
13333 p_day_count_method => l_day_count_method,
13334 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13335 p_pricing_method => 'SY',
13336 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
13337 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
13338 px_irr => l_yields_rec.pre_tax_irr,
13339 x_payment => x_payment);
13340 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13341 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
13342 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13343 'SOLVED FOR IRR (NON-SUBSIDY)' || x_iir );
13344 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13345 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13346 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13347 RAISE OKL_API.G_EXCEPTION_ERROR;
13348 END IF;
13349 ELSIF quote_rec.pricing_method = 'RC'
13350 THEN
13351 -- Fetch the SGT Day convention to be used
13352 get_lq_sgt_day_convention(
13353 p_api_version => p_api_version,
13354 p_init_msg_list => p_init_msg_list,
13355 x_return_status => l_return_status,
13356 x_msg_count => x_msg_count,
13357 x_msg_data => x_msg_data,
13358 p_lq_id => p_qte_id,
13359 x_days_in_month => l_days_in_month,
13360 x_days_in_year => l_days_in_year);
13361 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13362 ': After Fetching the Day convention from the SGT - RC ' );
13363 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13364 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13365 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13366 RAISE OKL_API.G_EXCEPTION_ERROR;
13367 END IF;
13368 -- Get the Day count method for passing into the compute_irr api version.
13369 get_day_count_method(
13370 p_days_in_month => l_days_in_month,
13371 p_days_in_year => l_days_in_year,
13372 x_day_count_method => l_day_count_method,
13373 x_return_status => l_return_status );
13374 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13375 'Return Status | l_days_in_month | l_days_in_year | l_day_count_method ' );
13376 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13377 l_return_status || ' | ' || l_days_in_month || ' | ' ||
13378 l_days_in_year || ' | ' || l_day_count_method );
13379 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13380 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13381 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13382 --Bug 5884825 PAGARG start
13383 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
13384 p_msg_name => 'OKL_ISG_DAY_CONVENTION',
13385 p_token1 => 'PRODUCT_NAME',
13386 p_token1_value => l_product_name);
13387 --Bug 5884825 PAGARG end
13388 RAISE OKL_API.G_EXCEPTION_ERROR;
13389 END IF;
13390 pp_index := 1;
13391 -- Loop through each configuration line and price it seperately ...
13392 FOR assets_rec IN assets_csr(p_qte_id)
13393 LOOP
13394 IF assets_rec.fee_type = 'FREE_FORM1'
13395 THEN
13396 -- For Rate Card Pricing the price_standard_quote_asset api will
13397 -- a/ Create Cash flows for each configuration line
13398 -- Checks whether to pick the RC from Header of configuration level itself.
13399 -- b/ builds and return the pricing parameter record
13400 price_standard_quote_asset(
13401 x_return_status => l_return_status,
13402 x_msg_count => x_msg_count,
13403 x_msg_data => x_msg_data,
13404 p_api_version => p_api_version,
13405 p_init_msg_list => p_init_msg_list,
13406 p_qte_id => p_qte_id,
13407 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
13408 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
13409 p_target_rate => NULL,
13410 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
13411 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13412 'After price_standard_quote_asset ' || l_return_status );
13413 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13414 RAISE okl_api.g_exception_unexpected_error;
13415 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13416 RAISE okl_api.g_exception_error;
13417 END IF;
13418 -- Store the Pricing Parameter for solving yields at the entire quote level
13419 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
13420 -- Increment the pp_index
13421 pp_index := pp_index + 1;
13422 END IF;
13423 END LOOP; -- Loop on the Assets csr
13424 -- Loop through ROLLOVER and Financed Fees, and fetch the pricng parameter rec. structure
13425 FOR assets_rec IN assets_csr(p_qte_id)
13426 LOOP
13427 IF assets_rec.fee_type in ('ROLLOVER', 'FINANCED')
13428 THEN
13429 -- For Rate Card Pricing the price_standard_quote_asset api will
13430 -- a/ Create Cash flows for each configuration line
13431 -- Checks whether to pick the RC from Header of configuration level itself.
13432 -- b/ builds and return the pricing parameter record
13433 price_standard_quote_asset(
13434 x_return_status => l_return_status,
13435 x_msg_count => x_msg_count,
13436 x_msg_data => x_msg_data,
13437 p_api_version => p_api_version,
13438 p_init_msg_list => p_init_msg_list,
13439 p_qte_id => p_qte_id,
13440 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
13441 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
13442 p_target_rate => NULL,
13443 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
13444 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13445 'After price_standard_quote_asset ' || l_return_status );
13446 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13447 RAISE okl_api.g_exception_unexpected_error;
13448 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13449 RAISE okl_api.g_exception_error;
13450 END IF;
13451 -- Store the Pricing Parameter for solving yields at the entire quote level
13452 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
13453 -- Increment the pp_index
13454 pp_index := pp_index + 1;
13455 END IF;
13456 END LOOP; -- Loop on the Assets csr
13457 -- Store the Pricing Param Table for calculation of the Non-Subsidized Yields
13458 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
13459 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13460 'Before calling irr for iir at quote level ' || l_return_status );
13461 -- Compute IIR @ Lease Quote Level.
13462 compute_irr(
13463 p_api_version => p_api_version,
13464 p_init_msg_list => p_init_msg_list,
13465 x_return_status => l_return_status,
13466 x_msg_count => x_msg_count,
13467 x_msg_data => x_msg_data,
13468 p_start_date => quote_rec.expected_start_date,
13469 p_day_count_method => l_day_count_method,
13470 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13471 p_pricing_method => 'SY',
13472 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
13473 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
13474 px_irr => x_iir,
13475 x_payment => x_payment);
13476 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13477 '1/ After Computation of IIR @ LQ Level ( SUBSIDY )' || l_return_status );
13478 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13479 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13480 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13481 RAISE OKL_API.G_EXCEPTION_ERROR;
13482 END IF;
13483 l_subsidized_yields_rec.iir := x_iir;
13484 l_subsidized_yields_rec.bk_yield := x_iir;
13485 -- Extract the other fees and other lines information for computation of the IRR
13486 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
13487 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
13488 LOOP
13489 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
13490 THEN
13491 -- Delete the previous fees cash flows
13492 l_fee_outflow_cfl_tbl.DELETE;
13493 l_fee_inflow_cfl_tbl.DELETE;
13494 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13495 '!!!!!! Handling fee ' || assets_rec.fee_type );
13496 get_lq_fee_cash_flows(
13497 p_api_version => p_api_version,
13498 p_init_msg_list => p_init_msg_list,
13499 x_return_status => l_return_status,
13500 x_msg_count => x_msg_count,
13501 x_msg_data => x_msg_data,
13502 p_fee_type => assets_rec.fee_type,
13503 p_lq_id => p_qte_id,
13504 p_fee_id => assets_rec.fee_id,
13505 x_outflow_caf_rec => l_fee_outflow_caf_rec,
13506 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
13507 x_inflow_caf_rec => l_fee_inflow_caf_rec,
13508 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
13509 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13510 'After get_lq_fee_cash_flows ' || l_return_status );
13511 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13512 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13513 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13514 RAISE OKL_API.G_EXCEPTION_ERROR;
13515 END IF;
13516 -- Based on the outflows/Inflows obtained generate the streams
13517 IF l_fee_outflow_cfl_tbl.COUNT > 0
13518 THEN
13519 l_cash_inflows.DELETE;
13520 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13521 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
13522 gen_so_cf_strms(
13523 p_api_version => p_api_version,
13524 p_init_msg_list => p_init_msg_list,
13525 x_return_status => l_return_status,
13526 x_msg_count => x_msg_count,
13527 x_msg_data => x_msg_data,
13528 p_cash_flow_rec => l_fee_outflow_caf_rec,
13529 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
13530 x_cash_inflow_strms_tbl => l_cash_inflows);
13531 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13532 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13533 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13534 RAISE OKL_API.G_EXCEPTION_ERROR;
13535 END IF;
13536 -- Place the information in the pricing params
13537 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
13538 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
13539 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
13540 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
13541 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
13542 pp_index := pp_index + 1;
13543 END IF;
13544 -- Based on the outflows/Inflows obtained generate the streams
13545 IF l_fee_inflow_cfl_tbl.COUNT > 0
13546 THEN
13547 l_cash_inflows.DELETE;
13548 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13549 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
13550 gen_so_cf_strms(
13551 p_api_version => p_api_version,
13552 p_init_msg_list => p_init_msg_list,
13553 x_return_status => l_return_status,
13554 x_msg_count => x_msg_count,
13555 x_msg_data => x_msg_data,
13556 p_cash_flow_rec => l_fee_inflow_caf_rec,
13557 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
13558 x_cash_inflow_strms_tbl => l_cash_inflows);
13559 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13560 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13561 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13562 RAISE OKL_API.G_EXCEPTION_ERROR;
13563 END IF;
13564 -- Place the information in the pricing params
13565 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
13566 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
13567 THEN
13568 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
13569 ELSE
13570 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
13571 END IF;
13572 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
13573 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
13574 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
13575 pp_index := pp_index + 1;
13576 END IF;
13577 END IF; -- IF on Fee_type not in ...
13578 IF assets_rec.fee_type = 'ABSORBED'
13579 THEN
13580 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13581 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
13582 -- Increment the pp_index and store the pricng params
13583 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
13584 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
13585 pp_index := pp_index + 1;
13586 END IF;
13587 END LOOP;
13588 -- Store the Pricing Param Table for calculation of the
13589 -- Non-Subsidized Yields
13590 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
13591 compute_irr(
13592 p_api_version => p_api_version,
13593 p_init_msg_list => p_init_msg_list,
13594 x_return_status => l_return_status,
13595 x_msg_count => x_msg_count,
13596 x_msg_data => x_msg_data,
13597 p_start_date => quote_rec.expected_start_date,
13598 p_day_count_method => l_day_count_method,
13599 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13600 p_pricing_method => 'SY',
13601 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
13602 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
13603 px_irr => l_subsidized_yields_rec.pre_tax_irr,
13604 x_payment => x_payment);
13605 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13606 '1/ After Computation of IRR @ LQ Level ( SUBSIDY )' || l_return_status );
13607 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13608 'SOLVED FOR IRR ' || x_iir );
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 -- Calculate the Yields without involving the Subsidy Amount
13615 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13616 '1/ CALCULATING THE YEILDS WIHTOUT THE SUBSIDY AMOUNT INVOLVED !! ' );
13617 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
13618 FOR ny IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
13619 LOOP
13620 -- line_type, subsidy
13621 l_pp_non_sub_iir_tbl(ny).subsidy := 0;
13622 END LOOP;
13623 compute_irr(
13624 p_api_version => p_api_version,
13625 p_init_msg_list => p_init_msg_list,
13626 x_return_status => l_return_status,
13627 x_msg_count => x_msg_count,
13628 x_msg_data => x_msg_data,
13629 p_start_date => quote_rec.expected_start_date,
13630 p_day_count_method => l_day_count_method,
13631 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13632 p_pricing_method => 'SY',
13633 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
13634 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
13635 px_irr => l_yields_rec.iir,
13636 x_payment => x_payment);
13637 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13638 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
13639 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13640 'SOLVED FOR IIR (NON-SUBSIDY)' || x_iir );
13641 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13642 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13643 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13644 RAISE OKL_API.G_EXCEPTION_ERROR;
13645 END IF;
13646 -- Store the IIR as the Booking Yield
13647 l_yields_rec.bk_yield := l_yields_rec.iir;
13648
13649 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
13650 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13651 '1/ Before Computation of IRR @ LQ Level ' );
13652 FOR ny IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
13653 LOOP
13654 -- For Asset lines, change the Subsidy Amount to Zero ..
13655 IF l_pp_non_sub_irr_tbl(ny).line_type = 'FREE_FORM1'
13656 THEN
13657 l_pp_non_sub_irr_tbl(ny).subsidy := 0;
13658 END IF;
13659 END LOOP;
13660 compute_irr(
13661 p_api_version => p_api_version,
13662 p_init_msg_list => p_init_msg_list,
13663 x_return_status => l_return_status,
13664 x_msg_count => x_msg_count,
13665 x_msg_data => x_msg_data,
13666 p_start_date => quote_rec.expected_start_date,
13667 p_day_count_method => l_day_count_method,
13668 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13669 p_pricing_method => 'SY',
13670 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
13671 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
13672 px_irr => l_yields_rec.pre_tax_irr,
13673 x_payment => x_payment);
13674 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13675 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
13676 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13677 'SOLVED FOR IRR (NON-SUBSIDY)' || x_iir );
13678 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13679 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13680 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13681 RAISE OKL_API.G_EXCEPTION_ERROR;
13682 END IF;
13683 -- End of Rate Card Pricing
13684 ELSIF quote_rec.pricing_method = 'SY'
13685 THEN
13686 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13687 'SOlving for Yields ' || l_return_status );
13688 l_lq_pricing_parameter_rec.financed_amount := 0;
13689 l_lq_pricing_parameter_rec.down_payment := 0;
13690 l_lq_pricing_parameter_rec.trade_in := 0;
13691 l_lq_pricing_parameter_rec.subsidy := 0;
13692 l_lq_pricing_parameter_rec.cap_fee_amount := 0;
13693 pp_index := 1;
13694 lnoa_index := 1;
13695 res_index := 1;
13696 l_non_overiding_assets_tbl.DELETE;
13697 -- Loop through the Assets and check price the asset seperately
13698 -- which has overriddent the payment option picked at the Quote Level
13699 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
13700 LOOP
13701 -- Check whether this Asset has overridden the Payment option defined
13702 -- at the quote level !
13703 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13704 'loop thru assets ' || assets_rec.asset_number || ' ' || l_return_status );
13705 IF nvl(assets_rec.fee_type, 'XXXX') <> 'FREE_FORM1'
13706 THEN
13707 l_overridden := TRUE;
13708 ELSE
13709 l_overridden := is_asset_overriding(
13710 p_qte_id => p_qte_id,
13711 p_ast_id => assets_rec.ast_id,
13712 p_lq_line_level_pricing => quote_rec.line_level_pricing,
13713 p_lq_srt_id => quote_rec.rate_template_id,
13714 p_ast_srt_id => assets_rec.rate_template_id,
13715 p_lq_struct_pricing => quote_rec.structured_pricing,
13716 p_ast_struct_pricing => assets_rec.structured_pricing,
13717 p_lq_arrears_yn => quote_rec.target_arrears,
13718 p_ast_arrears_yn => assets_rec.target_arrears,
13719 x_return_status => l_return_status);
13720 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13721 'After is_asset_overriding assets_rec.id =' || assets_rec.ast_id || ' | ' ||
13722 ' l_return_status =' || l_return_status );
13723 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13724 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13725 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13726 RAISE OKL_API.G_EXCEPTION_ERROR;
13727 END IF;
13728 END IF;
13729 IF l_overridden = FALSE
13730 THEN
13731 -- If asset is not overriding the Payment option defined at the Quote Level ...
13732 -- Store the Asset Id for later use ..
13733 l_non_overiding_assets_tbl(lnoa_index) := assets_rec.ast_id;
13734 -- Fetch the Asset Cost Adjustment Details for each Asset and accumulate them
13735 -- in the lx_pricing_parameter_rec
13736 FOR asset_cost_adj_rec IN asset_cost_adj_csr( qteid => p_qte_id,
13737 astid => assets_rec.ast_id)
13738 LOOP
13739 IF asset_cost_adj_rec.adjustment_source_type = G_DOWNPAYMENT_TYPE
13740 THEN
13741 l_noa_pp_tbl(lnoa_index).down_payment := nvl(asset_cost_adj_rec.VALUE, 0 );
13742 ELSIF asset_cost_adj_rec.adjustment_source_type = G_SUBSIDY_TYPE
13743 THEN
13744 IF ( nvl(asset_cost_adj_rec.value, -9999) = -9999)
13745 THEN
13746 OPEN subsidy_adj_csr(asset_cost_adj_rec.ADJUSTMENT_SOURCE_ID);
13747 FETCH subsidy_adj_csr INTO subsidy_adj_rec;
13748 CLOSE subsidy_adj_csr;
13749 l_noa_pp_tbl(lnoa_index).subsidy := subsidy_adj_rec.amount;
13750 ELSE
13751 l_noa_pp_tbl(lnoa_index).subsidy := asset_cost_adj_rec.value;
13752 END IF;
13753 ELSIF asset_cost_adj_rec.adjustment_source_type = G_TRADEIN_TYPE
13754 THEN
13755 l_noa_pp_tbl(lnoa_index).trade_in := nvl(asset_cost_adj_rec.VALUE, 0);
13756 END IF;
13757 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13758 'Down Payment| Trade In | Subsidy ' );
13759 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13760 l_noa_pp_tbl(lnoa_index).down_payment || ' | ' ||
13761 l_noa_pp_tbl(lnoa_index).trade_in || ' | ' ||
13762 l_noa_pp_tbl(lnoa_index).subsidy );
13763 END LOOP;
13764 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13765 'After Retrieving the Asset Cost Adjustments ');
13766 --res_index := 1;
13767 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, assets_rec.ast_id)
13768 LOOP
13769 l_noa_pp_tbl(lnoa_index).financed_amount := nvl(asset_adj_rec.oec, 0);
13770 -- Calculate the Capitalized Fee for this Asset
13771 FOR ct_rec IN get_asset_cap_fee_amt(
13772 p_source_type => 'ASSET',
13773 p_source_id => assets_rec.ast_id,
13774 p_related_line_type => 'CAPITALIZED')
13775 LOOP
13776 l_noa_pp_tbl(lnoa_index).cap_fee_amount := nvl(ct_rec.capitalized_amount, 0);
13777 END LOOP;
13778 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13779 asset_adj_rec.unit_cost|| ' No. of Units ' || asset_adj_rec.number_of_units);
13780 l_lq_residual_inflows(res_index).line_number := res_index;
13781 IF ( l_eot_type_code = 'PERCENT' OR l_eot_type_code = 'RESIDUAL_PERCENT' )
13782 THEN
13783 -- EOT = OEC * EOT %age /100;
13784 l_lq_residual_inflows(res_index).cf_amount :=
13785 nvl((asset_adj_rec.end_of_term_value/100) * l_noa_pp_tbl(lnoa_index).financed_amount, 0 );
13786 ELSE
13787 -- EOT is an amount so directly store it ..
13788 l_lq_residual_inflows(res_index).cf_amount := asset_adj_rec.end_of_term_value;
13789 END IF;
13790 l_lq_residual_inflows(res_index).cf_date := l_eot_date;
13791 l_lq_residual_inflows(res_index).cf_miss_pay := 'N';
13792 l_lq_residual_inflows(res_index).is_stub := 'N';
13793 l_lq_residual_inflows(res_index).is_arrears := 'Y';
13794 l_lq_residual_inflows(res_index).cf_dpp := l_cf_dpp;
13795 l_lq_residual_inflows(res_index).cf_ppy := l_cf_ppy;
13796 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13797 'Financed Amount = ' || l_noa_pp_tbl(lnoa_index).financed_amount);
13798 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13799 'Storing residual amt ' || l_lq_residual_inflows(res_index).cf_amount );
13800 -- Store the Asset Residuals in the corresponding NOA Assets table
13801 l_noa_pp_tbl(lnoa_index).residual_inflows(1) := l_lq_residual_inflows(res_index);
13802 -- Increment the res_index
13803 res_index := res_index + 1;
13804 END LOOP;
13805 -- Bug 6669429 : Start
13806 l_lq_pricing_parameter_rec.financed_amount := l_lq_pricing_parameter_rec.financed_amount + nvl(l_noa_pp_tbl(lnoa_index).financed_amount,0);
13807 l_lq_pricing_parameter_rec.down_payment := l_lq_pricing_parameter_rec.down_payment + nvl(l_noa_pp_tbl(lnoa_index).down_payment,0);
13808 l_lq_pricing_parameter_rec.trade_in := l_lq_pricing_parameter_rec.trade_in + nvl(l_noa_pp_tbl(lnoa_index).trade_in,0);
13809 l_lq_pricing_parameter_rec.subsidy := l_lq_pricing_parameter_rec.subsidy + nvl(l_noa_pp_tbl(lnoa_index).subsidy,0);
13810 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);
13811 -- Bug 6669429 : End
13812 lnoa_index := lnoa_index + 1;
13813 ELSE -- IF l_overridden = TRUE
13814 IF assets_rec.fee_type = 'FREE_FORM1'
13815 THEN
13816 -- Price this Asset which has overridden the payment strcuture defined on the LQ !
13817 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13818 ' Calling price_standard_quote_asset ' || 'p_qte_id ' || p_qte_id
13819 || ' | assets_rec.ast_id ' || nvl(assets_rec.ast_id, assets_rec.fee_id) ||
13820 ' | p_price_at_lq_level = FALSE | p_target_rate = NULL' );
13821 price_standard_quote_asset(
13822 x_return_status => l_return_status,
13823 x_msg_count => x_msg_count,
13824 x_msg_data => x_msg_data,
13825 p_api_version => p_api_version,
13826 p_init_msg_list => p_init_msg_list,
13827 p_qte_id => p_qte_id,
13828 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
13829 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
13830 p_target_rate => NULL,
13831 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
13832 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13833 'After price_standard_quote_asset ' || l_return_status );
13834 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13835 RAISE okl_api.g_exception_unexpected_error;
13836 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13837 RAISE okl_api.g_exception_error;
13838 END IF;
13839 -- Increment the pp_index
13840 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
13841 pp_index := pp_index + 1;
13842 END IF;
13843 END IF;
13844 END LOOP; -- Loop on the Assets csr
13845 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13846 ' Number of Overriding Lines = ' || l_pricing_parameter_tbl.COUNT || ' | ' ||
13847 ' Number of Non-Overriding Lines = ' || l_non_overiding_assets_tbl.COUNT );
13848 IF l_non_overiding_assets_tbl.COUNT > 0
13849 THEN
13850 -- If there is atleast one asset which follows the Payment Structure
13851 -- defined at Lease Quote Level, then pass the Pricing param table
13852 -- withe the Cash flows information at lease quote level else DON'T !!
13853 -- Store the Cash inflow streams and Residual streams in the l_lq_pricing_parameter_rec
13854 l_lq_pricing_parameter_rec.cash_inflows := l_lq_cash_inflows;
13855 l_lq_pricing_parameter_rec.residual_inflows := l_lq_residual_inflows;
13856 -- pp_index is an post-assigned incremented index!
13857 l_lq_pricing_parameter_rec.line_type := 'FREE_FORM1';
13858 l_pricing_parameter_tbl(pp_index) := l_lq_pricing_parameter_rec;
13859 pp_index := pp_index + 1;
13860 l_an_ass_follow_lq := TRUE; -- Store the flag
13861 l_lq_details_prc_rec := l_lq_pricing_parameter_rec;
13862 END IF;
13863 -- Handling the ROLLOVER AND FINANCED FEES
13864 FOR assets_rec IN assets_csr(p_qte_id) -- ALL Assets or FEES
13865 LOOP
13866 IF assets_rec.fee_type IN ( 'ROLLOVER', 'FINANCED')
13867 THEN
13868 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13869 ' Calling price_standard_quote_asset for ' || assets_rec.fee_type || ' with ID ' || assets_rec.fee_id );
13870 -- Price the fees ROLLOVER OR FINANCED
13871 price_standard_quote_asset(
13872 x_return_status => l_return_status,
13873 x_msg_count => x_msg_count,
13874 x_msg_data => x_msg_data,
13875 p_api_version => p_api_version,
13876 p_init_msg_list => p_init_msg_list,
13877 p_qte_id => p_qte_id,
13878 p_ast_id => nvl(assets_rec.ast_id, assets_rec.fee_id),
13879 p_price_at_lq_level => FALSE, -- Use Asset Level Cash flows only !
13880 p_target_rate => NULL,
13881 x_pricing_parameter_rec => l_tmp_pricing_parameter_rec );
13882 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13883 'After price_standard_quote_asset ' || l_return_status );
13884 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
13885 RAISE okl_api.g_exception_unexpected_error;
13886 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
13887 RAISE okl_api.g_exception_error;
13888 END IF;
13889 l_pricing_parameter_tbl(pp_index) := l_tmp_pricing_parameter_rec;
13890 -- Increment the pp_index
13891 pp_index := pp_index + 1;
13892 END IF;
13893 END LOOP;
13894 -- Store the Pricing Param Table for calculation of the Non-Subsidized Yields
13895 l_pp_non_sub_iir_tbl := l_pricing_parameter_tbl;
13896 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13897 'Before calling irr for iir at quote level ' || l_return_status );
13898 -- Compute IIR @ Lease Quote Level.
13899 compute_irr(
13900 p_api_version => p_api_version,
13901 p_init_msg_list => p_init_msg_list,
13902 x_return_status => l_return_status,
13903 x_msg_count => x_msg_count,
13904 x_msg_data => x_msg_data,
13905 p_start_date => quote_rec.expected_start_date,
13906 p_day_count_method => l_day_count_method,
13907 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
13908 p_pricing_method => 'SY',
13909 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
13910 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
13911 px_irr => x_iir,
13912 x_payment => x_payment);
13913 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13914 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
13915 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13916 'SOLVED FOR IIR ' || x_iir );
13917 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13918 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13919 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13920 RAISE OKL_API.G_EXCEPTION_ERROR;
13921 END IF;
13922 l_subsidized_yields_rec.iir := x_iir;
13923 l_subsidized_yields_rec.bk_yield := x_iir;
13924 -- Extract the fess information and built the Cash Inflows and Pricing Parameters
13925 FOR assets_rec IN assets_csr(p_qte_id) -- for all assets
13926 LOOP
13927 IF ( assets_rec.fee_type NOT IN ('FREE_FORM1', 'ROLLOVER', 'FINANCED', 'ABSORBED') )
13928 THEN
13929 -- Delete the previous fees cash flows
13930 l_fee_outflow_cfl_tbl.DELETE;
13931 l_fee_inflow_cfl_tbl.DELETE;
13932 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13933 '!!!!!! Handling fee ' || assets_rec.fee_type );
13934 get_lq_fee_cash_flows(
13935 p_api_version => p_api_version,
13936 p_init_msg_list => p_init_msg_list,
13937 x_return_status => l_return_status,
13938 x_msg_count => x_msg_count,
13939 x_msg_data => x_msg_data,
13940 p_fee_type => assets_rec.fee_type,
13941 p_lq_id => p_qte_id,
13942 p_fee_id => assets_rec.fee_id,
13943 x_outflow_caf_rec => l_fee_outflow_caf_rec,
13944 x_outflow_cfl_tbl => l_fee_outflow_cfl_tbl,
13945 x_inflow_caf_rec => l_fee_inflow_caf_rec,
13946 x_inflow_cfl_tbl => l_fee_inflow_cfl_tbl);
13947 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13948 'After get_lq_fee_cash_flows ' || l_return_status );
13949 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13950 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13951 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13952 RAISE OKL_API.G_EXCEPTION_ERROR;
13953 END IF;
13954 -- Based on the outflows/Inflows obtained generate the streams
13955 IF l_fee_outflow_cfl_tbl.COUNT > 0
13956 THEN
13957 l_cash_inflows.DELETE;
13958 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13959 '!!!!!!! Obtained Expense Cash flow levels !!!!!!!!' );
13960 gen_so_cf_strms(
13961 p_api_version => p_api_version,
13962 p_init_msg_list => p_init_msg_list,
13963 x_return_status => l_return_status,
13964 x_msg_count => x_msg_count,
13965 x_msg_data => x_msg_data,
13966 p_cash_flow_rec => l_fee_outflow_caf_rec,
13967 p_cf_details_tbl => l_fee_outflow_cfl_tbl,
13968 x_cash_inflow_strms_tbl => l_cash_inflows);
13969 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13970 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13971 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
13972 RAISE OKL_API.G_EXCEPTION_ERROR;
13973 END IF;
13974 -- Place the information in the pricing params
13975 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
13976 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
13977 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
13978 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
13979 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
13980 pp_index := pp_index + 1;
13981 END IF;
13982 -- Based on the outflows/Inflows obtained generate the streams
13983 IF l_fee_inflow_cfl_tbl.COUNT > 0
13984 THEN
13985 l_cash_inflows.DELETE;
13986 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
13987 '!!!!!!! Obtained Income Cash flow levels !!!!!!!!' );
13988 gen_so_cf_strms(
13989 p_api_version => p_api_version,
13990 p_init_msg_list => p_init_msg_list,
13991 x_return_status => l_return_status,
13992 x_msg_count => x_msg_count,
13993 x_msg_data => x_msg_data,
13994 p_cash_flow_rec => l_fee_inflow_caf_rec,
13995 p_cf_details_tbl => l_fee_inflow_cfl_tbl,
13996 x_cash_inflow_strms_tbl => l_cash_inflows);
13997 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
13998 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
13999 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14000 RAISE OKL_API.G_EXCEPTION_ERROR;
14001 END IF;
14002 -- Place the information in the pricing params
14003 l_pricing_parameter_tbl(pp_index).line_type := assets_rec.fee_type;
14004 IF assets_rec.fee_type IN ( 'INCOME', 'MISCELLANEOUS' )
14005 THEN
14006 l_pricing_parameter_tbl(pp_index).payment_type := 'INCOME';
14007 ELSE
14008 l_pricing_parameter_tbl(pp_index).payment_type := 'SECDEPOSIT';
14009 END IF;
14010 l_pricing_parameter_tbl(pp_index).line_start_date := assets_rec.line_start_date;
14011 l_pricing_parameter_tbl(pp_index).line_end_date := assets_rec.line_end_date;
14012 l_pricing_parameter_tbl(pp_index).cash_inflows := l_cash_inflows;
14013 pp_index := pp_index + 1;
14014 END IF;
14015 END IF; -- IF on Fee_type not in ...
14016 IF assets_rec.fee_type = 'ABSORBED'
14017 THEN
14018 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14019 '!!!!!! Building cash inflows for this Absorbed fee ' || assets_rec.fee_type );
14020 -- Increment the pp_index and store the pricng params
14021 l_pricing_parameter_tbl(pp_index).payment_type := 'EXPENSE';
14022 l_pricing_parameter_tbl(pp_index).financed_amount := assets_rec.fee_amount;
14023 pp_index := pp_index + 1;
14024 END IF;
14025 END LOOP;
14026 -- Store the Pricing Param Table for calculation of the
14027 -- Non-Subsidized Yields
14028 l_pp_non_sub_irr_tbl.DELETE;
14029 l_pp_non_sub_irr_tbl := l_pricing_parameter_tbl;
14030 -- Now call the compute_irr api to solve for the Yield at the Lease quote Level !
14031 compute_irr(
14032 p_api_version => p_api_version,
14033 p_init_msg_list => p_init_msg_list,
14034 x_return_status => l_return_status,
14035 x_msg_count => x_msg_count,
14036 x_msg_data => x_msg_data,
14037 p_start_date => quote_rec.expected_start_date,
14038 p_day_count_method => l_day_count_method,
14039 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14040 p_pricing_method => 'SY',
14041 p_initial_guess => x_iir, -- Use the IIR derieved prev. as initial guess
14042 px_pricing_parameter_tbl => l_pricing_parameter_tbl, -- includes the fees as well
14043 px_irr => x_iir,
14044 x_payment => x_payment);
14045 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14046 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
14047 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14048 'SOLVED FOR IRR ' || x_iir );
14049 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14050 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14051 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14052 RAISE OKL_API.G_EXCEPTION_ERROR;
14053 END IF;
14054 l_subsidized_yields_rec.pre_tax_irr := x_iir;
14055 -- Calculate the Yields without involving the Subsidy Amount
14056 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14057 '1/ CALCULATING THE YEILDS WIHTOUT THE SUBSIDY AMOUNT INVOLVED !! ' );
14058 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14059 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
14060 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
14061 FOR ny IN l_pp_non_sub_iir_tbl.FIRST .. l_pp_non_sub_iir_tbl.LAST
14062 LOOP
14063 -- line_type, subsidy
14064 l_pp_non_sub_iir_tbl(ny).subsidy := 0;
14065 END LOOP;
14066 compute_irr(
14067 p_api_version => p_api_version,
14068 p_init_msg_list => p_init_msg_list,
14069 x_return_status => l_return_status,
14070 x_msg_count => x_msg_count,
14071 x_msg_data => x_msg_data,
14072 p_start_date => quote_rec.expected_start_date,
14073 p_day_count_method => l_day_count_method,
14074 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14075 p_pricing_method => 'SY',
14076 p_initial_guess => l_subsidized_yields_rec.iir, -- Use the IIR derieved prev. as initial guess
14077 px_pricing_parameter_tbl => l_pp_non_sub_iir_tbl, -- includes the fees as well
14078 px_irr => l_yields_rec.iir,
14079 x_payment => x_payment);
14080 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14081 '1/ After Computation of IIR @ LQ Level ' || l_return_status );
14082 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14083 'SOLVED FOR IIR (NON-SUBSIDY)' || x_iir );
14084 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14085 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14086 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14087 RAISE OKL_API.G_EXCEPTION_ERROR;
14088 END IF;
14089 -- Store the IIR as the Booking Yield
14090 l_yields_rec.bk_yield := l_yields_rec.iir;
14091 -- Loop through the l_pp_non_sub_iir_tbl table and delete the Subsidy Amount
14092 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14093 '1/ Before Computation of IRR @ LQ Level loop subsidy ' || to_char(l_pp_non_sub_irr_tbl.COUNT));
14094 FOR ny IN l_pp_non_sub_irr_tbl.FIRST .. l_pp_non_sub_irr_tbl.LAST
14095 LOOP
14096 -- For Asset lines, change the Subsidy Amount to Zero ..
14097 IF nvl(l_pp_non_sub_irr_tbl(ny).line_type, 'XXXX') = 'FREE_FORM1'
14098 THEN
14099 l_pp_non_sub_irr_tbl(ny).subsidy := 0;
14100 END IF;
14101 END LOOP;
14102 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14103 '1/ Before Computation of IRR @ LQ Level ' );
14104 compute_irr(
14105 p_api_version => p_api_version,
14106 p_init_msg_list => p_init_msg_list,
14107 x_return_status => l_return_status,
14108 x_msg_count => x_msg_count,
14109 x_msg_data => x_msg_data,
14110 p_start_date => quote_rec.expected_start_date,
14111 p_day_count_method => l_day_count_method,
14112 p_currency_code => l_currency, -- Replace this USD with the appropriate column!
14113 p_pricing_method => 'SY',
14114 p_initial_guess => l_subsidized_yields_rec.pre_tax_irr, -- Use the IIR derieved prev. as initial guess
14115 px_pricing_parameter_tbl => l_pp_non_sub_irr_tbl, -- includes the fees as well
14116 px_irr => l_yields_rec.pre_tax_irr,
14117 x_payment => x_payment);
14118 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14119 '1/ After Computation of IRR @ LQ Level ' || l_return_status );
14120 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14121 'SOLVED FOR IRR (NON-SUBSIDY)' || x_iir );
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 END IF;
14128 -- Populate the l_lease_qte_rec appropriately for the Updation
14129 l_lease_qte_rec.id := p_qte_id;
14130 l_lease_qte_rec.SUB_IIR := round(l_subsidized_yields_rec.iir * 100, 4);
14131 l_lease_qte_rec.SUB_PIRR := round(l_subsidized_yields_rec.pre_tax_irr * 100, 4);
14132 l_lease_qte_rec.SUB_BOOKING_YIELD := round(l_subsidized_yields_rec.bk_yield * 100, 4);
14133 l_lease_qte_rec.IIR := round(l_yields_rec.iir * 100, 4);
14134 l_lease_qte_rec.PIRR := round(l_yields_rec.pre_tax_irr * 100, 4);
14135 l_lease_qte_rec.BOOKING_YIELD := round(l_yields_rec.bk_yield * 100, 4);
14136 l_lease_qte_rec.status := 'PR-COMPLETE';
14137 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14138 'Update the Yields on the Lease Quote' );
14139 okl_lease_quote_pvt.update_lease_qte(
14140 p_api_version => p_api_version,
14141 p_init_msg_list => p_init_msg_list,
14142 p_transaction_control => NULL,
14143 p_lease_qte_rec => l_lease_qte_rec,
14144 x_lease_qte_rec => x_lease_qte_rec,
14145 x_return_status => l_return_status,
14146 x_msg_count => x_msg_count,
14147 x_msg_data => x_msg_data);
14148 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14149 'After updation of Yields on Lease Quote. Status: ' || l_return_status );
14150 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14151 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14152 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14153 RAISE OKL_API.G_EXCEPTION_ERROR;
14154 END IF;
14155 -- Now after the Yields has been calculated, we need to calculate the payments
14156 -- for all Non-Overridden assets !
14157 IF quote_rec.pricing_method <> 'RC'
14158 AND l_an_ass_follow_lq
14159 THEN
14160 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14161 ' !!!!!!!! CALCULATION OF THE ASSET LEVEL PAYMENTS !!!!!! ' );
14162 -- Calculate the Quote leve C-S-D-T
14163 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14164 'LQ Level: Asset Cost (C) | Down Payment (D) | Trade-in (T) | Subsidy (s)' );
14165 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14166 round( l_lq_details_prc_rec.financed_amount, 4) || ' | ' || round( l_lq_details_prc_rec.down_payment, 4) || ' | ' ||
14167 round( l_lq_details_prc_rec.trade_in, 4) || ' | ' || round( l_lq_details_prc_rec.subsidy, 4));
14168 IF quote_rec.pricing_method <> 'TR'
14169 THEN
14170 -- Now compute the IIR for the group of assets which follow the payment
14171 -- entered at the Quote Level.
14172 compute_iir(
14173 p_api_version => p_api_version,
14174 p_init_msg_list => p_init_msg_list,
14175 x_return_status => l_return_status,
14176 x_msg_count => x_msg_count,
14177 x_msg_data => x_msg_data,
14178 p_start_date => quote_rec.expected_start_date,
14179 p_day_count_method => l_day_count_method,
14180 p_pricing_method => 'SY',
14181 p_initial_guess => (l_lease_qte_rec.iir/ 100 ),
14182 px_pricing_parameter_rec => l_lq_details_prc_rec,
14183 px_iir => l_iir,
14184 x_payment => l_miss_payment);
14185 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14186 'After SY @ LQ level ' || x_return_status || ' | l_iir=' || round(l_iir,4) );
14187 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14188 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14189 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14190 RAISE OKL_API.G_EXCEPTION_ERROR;
14191 END IF;
14192 ELSE
14193 l_iir := (l_lease_qte_rec.iir / 100 );
14194 END IF;
14195 -- Loop the Streams at the Quote level and put the l_iir as rate, and cf_ratio also
14196 -- needs to be populated appropriately.
14197 l_lq_con_cash_inflows := l_lq_details_prc_rec.cash_inflows;
14198 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14199 '!! Assigning the Quote level rate and cf_ratio !!' );
14200 FOR t_in IN l_lq_con_cash_inflows.FIRST .. l_lq_con_cash_inflows.LAST
14201 LOOP
14202 IF l_lq_con_cash_inflows(t_in).cf_amount > 0
14203 THEN
14204 l_tmp_amount := l_lq_con_cash_inflows(t_in).cf_amount;
14205 EXIT;
14206 END IF;
14207 END LOOP;
14208 FOR t_in IN l_lq_con_cash_inflows.FIRST .. l_lq_con_cash_inflows.LAST
14209 LOOP
14210 l_lq_con_cash_inflows(t_in).cf_rate := l_iir;
14211 l_lq_con_cash_inflows(t_in).cf_ratio:= l_lq_con_cash_inflows(t_in).cf_amount/l_tmp_amount;
14212 END LOOP;
14213 -- Store the amount from the first cash flow level which can be a Stub/Periodic Amount and is non-zero
14214 FOR t_in IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
14215 LOOP
14216 IF l_lq_payment_level_tbl(t_in).stub_days IS NOT NULL AND
14217 l_lq_payment_level_tbl(t_in).stub_amount > 0
14218 THEN
14219 -- Found a first stub CFL with some amount, using this as a base for the proportion.
14220 l_tmp_amount := l_lq_payment_level_tbl(t_in).stub_amount;
14221 EXIT;
14222 ELSIF l_lq_payment_level_tbl(t_in).periods IS NOT NULL AND
14223 l_lq_payment_level_tbl(t_in).periodic_amount > 0
14224 THEN
14225 -- Found a regular CFL with some amount, using this as a base for the proportion.
14226 l_tmp_amount := l_lq_payment_level_tbl(t_in).periodic_amount;
14227 EXIT;
14228 END IF;
14229 END LOOP;
14230 l_rnd_lq_payment_level_tbl := l_lq_payment_level_tbl;
14231 l_rnd_sum_assets_pmnts_tbl := l_lq_payment_level_tbl;
14232 FOR t_in IN l_rnd_lq_payment_level_tbl.FIRST .. l_rnd_lq_payment_level_tbl.LAST
14233 LOOP
14234 IF l_rnd_lq_payment_level_tbl(t_in).stub_days IS NOT NULL AND
14235 l_rnd_lq_payment_level_tbl(t_in).stub_amount > 0
14236 THEN
14237 l_rnd_lq_payment_level_tbl(t_in).stub_amount :=
14238 okl_accounting_util.round_amount(
14239 p_amount => l_rnd_lq_payment_level_tbl(t_in).stub_amount,
14240 p_currency_code => l_currency );
14241 l_rnd_sum_assets_pmnts_tbl(t_in).stub_amount := 0;
14242 ELSE
14243 l_rnd_lq_payment_level_tbl(t_in).periodic_amount :=
14244 okl_accounting_util.round_amount(
14245 p_amount => l_rnd_lq_payment_level_tbl(t_in).periodic_amount,
14246 p_currency_code => l_currency );
14247 l_rnd_sum_assets_pmnts_tbl(t_in).periodic_amount := 0;
14248 END IF;
14249 END LOOP;
14250 -- Loop through the assets which follow the LQ payment structure
14251 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14252 '!!!!!!!! **** DERIEVING PAYMENTS FOR ALL ASSETS ***** !!!!!!!!!' );
14253 FOR t IN l_noa_pp_tbl.FIRST .. l_noa_pp_tbl.LAST
14254 LOOP
14255 IF quote_rec.pricing_method IN ( 'SF' )
14256 THEN
14257 -- Asset Cost is not stored in the l_noa_pp_tbl while solving it .. Hence, fetch it
14258 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14259 ' Asset ID = ' || l_non_overiding_assets_tbl(t) );
14260 FOR asset_adj_rec IN asset_adj_csr(p_qte_id, l_non_overiding_assets_tbl(t))
14261 LOOP
14262 l_noa_pp_tbl(t).financed_amount := nvl(asset_adj_rec.oec,0);
14263 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14264 'Asset cost was fetched from the DB ' || l_noa_pp_tbl(t).financed_amount );
14265 END LOOP;
14266 END IF;
14267 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14268 'Asset Cost (C) | Down Payment (D) | Trade-in (T) | Subsidy (s)' );
14269 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14270 round( l_noa_pp_tbl(t).financed_amount, 4) || ' | ' || round( l_noa_pp_tbl(t).down_payment, 4) || ' | ' ||
14271 round( l_noa_pp_tbl(t).trade_in, 4) || ' | ' || round( l_noa_pp_tbl(t).subsidy, 4));
14272 -- The streams for this asset should resemble the Quote level ones. Hence, copying them to the Asset PP Rec.
14273 l_noa_pp_tbl(t).cash_inflows := l_lq_con_cash_inflows;
14274 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14275 'Calculating the Asset level Payment for ID ' || l_non_overiding_assets_tbl(t) );
14276 compute_iir(
14277 p_api_version => p_api_version,
14278 p_init_msg_list => p_init_msg_list,
14279 x_return_status => l_return_status,
14280 x_msg_count => x_msg_count,
14281 x_msg_data => x_msg_data,
14282 p_start_date => quote_rec.expected_start_date,
14283 p_day_count_method => l_day_count_method,
14284 p_pricing_method => 'SPP', -- Use the Algorithm which proportionates the Payment Amt
14285 p_initial_guess => l_lease_qte_rec.iir,
14286 px_pricing_parameter_rec => l_noa_pp_tbl(t),
14287 px_iir => l_iir,
14288 x_payment => l_miss_payment);
14289 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14290 'SPP: For Asset Status=' || x_return_status || ' | l_iir=' || round(l_iir,4) || ' | l_miss_payment = ' || round(l_miss_payment, 2));
14291 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14292 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14293 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14294 RAISE OKL_API.G_EXCEPTION_ERROR;
14295 END IF;
14296 -- Need to delete the cash flow (if any exists) for this Asset with WORK Status.
14297 l_cfo_exists_at_noa := 'YES';
14298 FOR t_rec IN check_cfo_exists_csr(
14299 p_oty_code => 'QUOTED_ASSET',
14300 p_source_table => 'OKL_ASSETS_B',
14301 p_source_id => l_non_overiding_assets_tbl(t),
14302 p_sts_code => 'WORK')
14303 LOOP
14304 l_cfo_exists_at_noa := t_rec.cfo_exists;
14305 END LOOP;
14306 -- Delete the Cash flows if they are already present
14307 IF l_cfo_exists_at_noa = 'YES'
14308 THEN
14309 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14310 ' Deleting already existing CFO ' );
14311 -- Delete the Cash Flow Levels which may be already created by Pricing ..
14312 okl_lease_quote_cashflow_pvt.delete_cashflows (
14313 p_api_version => p_api_version,
14314 p_init_msg_list => p_init_msg_list,
14315 p_transaction_control => NULL,
14316 p_source_object_code => 'QUOTED_ASSET',
14317 p_source_object_id => l_non_overiding_assets_tbl(t),
14318 x_return_status => l_return_status,
14319 x_msg_count => x_msg_count,
14320 x_msg_data => x_msg_data);
14321 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14322 ' ----- After deleting the Cash flows for the asset ' || l_return_status );
14323 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
14324 RAISE okl_api.g_exception_unexpected_error;
14325 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
14326 RAISE okl_api.g_exception_error;
14327 END IF;
14328 END IF;
14329 -- Create the Cash flows with the structure similiar to the LQ
14330 l_asset_caf_rec.parent_object_code := 'QUOTED_ASSET';
14331 l_asset_caf_rec.parent_object_id := l_non_overiding_assets_tbl(t);
14332 l_asset_caf_rec.status_code := 'WORK';
14333 l_asset_caf_rec.type_code := 'INFLOW';
14334 l_asset_caf_rec.arrears_flag := l_lq_payment_header_rec.arrears_flag;
14335 l_asset_caf_rec.stream_type_id := l_rent_sty_id;
14336 l_asset_caf_rec.frequency_code := l_lq_payment_header_rec.frequency_code;
14337 l_asset_caf_rec.quote_type_code := l_quote_type_code;
14338 l_asset_caf_rec.quote_id := p_qte_id;
14339 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14340 ' Frequency | Adv/ Arrears | Rate | Stub Days | Stub Amount | Periods | Amount | Start Date ' );
14341 FOR i in l_lq_payment_level_tbl.FIRST..l_lq_payment_level_tbl.LAST
14342 LOOP
14343 l_asset_cfl_tbl(i).record_mode := 'CREATE';
14344 l_asset_cfl_tbl(i).start_date := l_lq_payment_level_tbl(i).start_date;
14345 l_asset_cfl_tbl(i).rate := l_iir;
14346 l_asset_cfl_tbl(i).stub_amount := l_lq_payment_level_tbl(i).stub_amount;
14347 l_asset_cfl_tbl(i).stub_days := l_lq_payment_level_tbl(i).stub_days;
14348 l_asset_cfl_tbl(i).periods := l_lq_payment_level_tbl(i).periods;
14349 l_asset_cfl_tbl(i).periodic_amount := l_lq_payment_level_tbl(i).periodic_amount;
14350 -- Using the l_miss_amount and the ratio of the cash flows we need to determine the Amount @ every CFL
14351 IF l_lq_cash_flow_det_tbl(i).stub_days > 0
14352 THEN
14353 IF t = l_noa_pp_tbl.LAST
14354 THEN
14355 -- The Last Payment, hence use the Round LQ Amount - Sum of Prev. Assets Amount, instead of the proportion.
14356 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;
14357 ELSE
14358 l_asset_cfl_tbl(i).stub_amount :=
14359 l_miss_payment * (l_lq_payment_level_tbl(i).stub_amount / l_tmp_amount);
14360 l_rnd_sum_assets_pmnts_tbl(i).stub_amount := l_rnd_sum_assets_pmnts_tbl(i).stub_amount +
14361 okl_accounting_util.round_amount(
14362 p_amount => l_asset_cfl_tbl(i).stub_amount,
14363 p_currency_code => l_currency );
14364 END IF;
14365 ELSIF l_lq_cash_flow_det_tbl(i).number_of_periods > 0
14366 THEN
14367 IF t = l_noa_pp_tbl.LAST
14368 THEN
14369 -- The Last Payment, hence use the Round LQ Amount - Sum of Prev. Assets Amount, instead of the proportion.
14370 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;
14371 ELSE
14372 l_asset_cfl_tbl(i).periodic_amount :=
14373 l_miss_payment * (l_lq_payment_level_tbl(i).periodic_amount / l_tmp_amount );
14374 l_rnd_sum_assets_pmnts_tbl(i).periodic_amount := l_rnd_sum_assets_pmnts_tbl(i).periodic_amount +
14375 okl_accounting_util.round_amount(
14376 p_amount => l_asset_cfl_tbl(i).periodic_amount,
14377 p_currency_code => l_currency );
14378 END IF;
14379 END IF;
14380 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14381 l_asset_caf_rec.frequency_code || ' | ' || l_asset_caf_rec.arrears_flag || ' | ' || l_asset_cfl_tbl(i).rate|| ' | ' ||
14382 l_asset_cfl_tbl(i).stub_days || ' | ' || l_asset_cfl_tbl(i).stub_amount|| ' | ' || l_asset_cfl_tbl(i).periods|| ' | ' ||
14383 l_asset_cfl_tbl(i).periodic_amount || ' | ' || l_asset_cfl_tbl(i).start_Date );
14384 END LOOP;
14385 -- Create the Cash flows for the Asset
14386 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
14387 p_api_version => p_api_version,
14388 p_init_msg_list => p_init_msg_list,
14389 p_transaction_control => NULL,
14390 p_cashflow_header_rec => l_asset_caf_rec,
14391 p_cashflow_level_tbl => l_asset_cfl_tbl,
14392 x_return_status => l_return_status,
14393 x_msg_count => x_msg_count,
14394 x_msg_data => x_msg_data);
14395 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14396 'After calling create_cash_flow ' || l_return_status);
14397 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14398 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14399 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14400 RAISE OKL_API.G_EXCEPTION_ERROR;
14401 END IF;
14402 END LOOP; -- Loop on the l_noa_det_prc_tbl
14403 END IF;
14404 -- Delete (if exists any..) LEASE_QUOTE_CONSOLIDATED cash flows existing
14405 -- at the Lease Quote level.
14406 l_cfo_exists_at_lq := 'NO';
14407 FOR t_rec IN check_cfo_exists_csr(
14408 p_oty_code => 'LEASE_QUOTE_CONSOLIDATED',
14409 p_source_table => 'OKL_LEASE_QUOTES_B',
14410 p_source_id => p_qte_id,
14411 p_sts_code => 'WORK')
14412 LOOP
14413 l_cfo_exists_at_lq := t_rec.cfo_exists;
14414 END LOOP;
14415 IF l_cfo_exists_at_lq = 'YES'
14416 THEN
14417 -- Delete the Payment structure already derieved by pricing
14418 okl_lease_quote_cashflow_pvt.delete_cashflows (
14419 p_api_version => p_api_version,
14420 p_init_msg_list => p_init_msg_list,
14421 p_transaction_control => NULL,
14422 p_source_object_code => 'LEASE_QUOTE_CONSOLIDATED',
14423 p_source_object_id => p_qte_id,
14424 x_return_status => l_return_status,
14425 x_msg_count => x_msg_count,
14426 x_msg_data => x_msg_data);
14427 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14428 'Deleted the Consolidated Cash flow levels @ LQ levels. Status: ' || l_return_status );
14429 IF (l_return_status = okl_api.g_ret_sts_unexp_error) THEN
14430 RAISE okl_api.g_exception_unexpected_error;
14431 ELSIF (l_return_status = okl_api.g_ret_sts_error) THEN
14432 RAISE okl_api.g_exception_error;
14433 END IF;
14434 END IF; -- IF l_cfo_exists_at_lq
14435 -- Code for solving the payment amount @ LQ level follows ..
14436 -- If for all the assets, frequency, adv/arrears, the payment structure matches
14437 -- then the solve_pmnts_at_lq API returns the solved payment structure @ LQ level
14438 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14439 '!!! *** DERIEVING THE CONSOLIDATED PAYMENT AMOUNT AT LEASE QUOTE LEVEL *** !!! ');
14440 solve_pmnts_at_lq(
14441 p_api_version => p_api_version,
14442 p_init_msg_list => p_init_msg_list,
14443 x_return_status => l_return_status,
14444 x_msg_count => x_msg_count,
14445 x_msg_data => x_msg_data,
14446 p_id => p_qte_id,
14447 x_caf_rec => l_lq_payment_header_rec,
14448 x_cfl_tbl => l_lq_payment_level_tbl,
14449 x_solved => l_solved);
14450 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14451 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14452 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14453 RAISE OKL_API.G_EXCEPTION_ERROR;
14454 END IF;
14455 IF l_solved = 'YES' AND l_lq_payment_level_tbl IS NOT NULL AND l_lq_payment_level_tbl.COUNT > 0
14456 THEN
14457 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14458 '!!! *** Payments can be derieved at Lease Quote level *** !!! ' || l_lq_payment_level_tbl.COUNT );
14459 l_lq_payment_header_rec.type_code := 'INFLOW';
14460 l_lq_payment_header_rec.parent_object_code := 'LEASE_QUOTE_CONSOLIDATED';
14461 l_lq_payment_header_rec.parent_object_id := p_qte_id;
14462 l_lq_payment_header_rec.status_code := 'WORK';
14463 IF quote_rec.pricing_method = 'RC'
14464 THEN
14465 OPEN c_strm_type ( quote_rec.id, quote_rec.expected_start_date );
14466 FETCH c_strm_type INTO r_strm_type;
14467 CLOSE c_strm_type;
14468 l_rent_sty_id := r_strm_type.payment_type_id;
14469 END IF;
14470 l_lq_payment_header_rec.stream_type_id := l_rent_sty_id;
14471 l_lq_payment_header_rec.quote_type_code := l_quote_type_code;
14472 l_lq_payment_header_rec.quote_id := p_qte_id;
14473 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14474 ' Frequency | Adv/ Arrears | Rate | Stub Days | Stub Amount | Periods | Amount | Start Date ' );
14475 FOR i IN l_lq_payment_level_tbl.FIRST .. l_lq_payment_level_tbl.LAST
14476 LOOP
14477 l_lq_payment_level_tbl(i).record_mode := 'CREATE';
14478 IF l_lq_payment_level_tbl(i).rate IS NULL
14479 THEN
14480 l_lq_payment_level_tbl(i).rate := l_lease_qte_rec.sub_iir;
14481 END IF;
14482 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14483 l_lq_payment_header_rec.frequency_code || ' | ' || l_lq_payment_header_rec.arrears_flag || ' | ' || l_lq_payment_level_tbl(i).rate|| ' | ' ||
14484 l_lq_payment_level_tbl(i).stub_days || ' | ' || l_lq_payment_level_tbl(i).stub_amount|| ' | ' || l_lq_payment_level_tbl(i).periods|| ' | ' ||
14485 l_lq_payment_level_tbl(i).periodic_amount || ' | ' || l_lq_payment_level_tbl(i).start_Date );
14486 END LOOP;
14487 OKL_LEASE_QUOTE_CASHFLOW_PVT.create_cashflow(
14488 p_api_version => p_api_version,
14489 p_init_msg_list => p_init_msg_list,
14490 p_transaction_control => NULL,
14491 p_cashflow_header_rec => l_lq_payment_header_rec,
14492 p_cashflow_level_tbl => l_lq_payment_level_tbl,
14493 x_return_status => l_return_status,
14494 x_msg_count => x_msg_count,
14495 x_msg_data => x_msg_data);
14496 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14497 'Creation of LQ level cash flow levels stauts: ' || l_Return_Status );
14498 IF(l_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
14499 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
14500 ELSIF (l_return_status = OKL_API.G_RET_STS_ERROR) THEN
14501 RAISE OKL_API.G_EXCEPTION_ERROR;
14502 END IF;
14503 ELSE
14504 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'S',
14505 '!!!!! PRICING ENGINE IS UNABLE TO DERIEVE PAYMENTS AT LQ LEVEL !!!!!' );
14506 END IF; -- IF l_solved = 'YES'
14507 -- Pass the results back
14508 x_return_status := l_return_status;
14509 OKL_API.END_ACTIVITY(x_msg_count => x_msg_count,
14510 x_msg_data => x_msg_data);
14511 put_in_log(l_debug_enabled,is_debug_procedure_on,is_debug_statement_on,l_module, 'P',
14512 'end debug OKLRPIUB.pls call ' || LOWER(l_api_name) );
14513 EXCEPTION
14514 WHEN OKL_API.G_EXCEPTION_ERROR THEN
14515 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
14516 p_api_name => l_api_name,
14517 p_pkg_name => G_PKG_NAME,
14518 p_exc_name => 'OKL_API.G_RET_STS_ERROR',
14519 x_msg_count => x_msg_count,
14520 x_msg_data => x_msg_data,
14521 p_api_type => g_api_type);
14522 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
14523 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
14524 p_api_name => l_api_name,
14525 p_pkg_name => G_PKG_NAME,
14526 p_exc_name => 'OKL_API.G_RET_STS_UNEXP_ERROR',
14527 x_msg_count => x_msg_count,
14528 x_msg_data => x_msg_data,
14529 p_api_type => g_api_type);
14530 WHEN OTHERS THEN
14531 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
14532 p_api_name => l_api_name,
14533 p_pkg_name => G_PKG_NAME,
14534 p_exc_name => 'OTHERS',
14535 x_msg_count => x_msg_count,
14536 x_msg_data => x_msg_data,
14537 p_api_type => g_api_type);
14538 END price_standard_quote;
14539 END OKL_PRICING_UTILS_PVT;