[Home] [Help]
PACKAGE BODY: APPS.OKL_PRICING_PVT
Source
1 PACKAGE BODY OKL_PRICING_PVT AS
2 /* $Header: OKLRPIGB.pls 120.80.12020000.3 2012/10/17 11:36:34 vloomba ship $ */
3
4 G_MODULE VARCHAR2(255) := 'okl.stream.esg.okl_esg_transport_pvt';
5 G_DEBUG_ENABLED CONSTANT VARCHAR2(10) := OKL_DEBUG_PUB.CHECK_LOG_ENABLED;
6 G_IS_DEBUG_STATEMENT_ON BOOLEAN;
7
8 -- Added for IRR Approximation
9 G_TOT_CAP_AMT NUMBER := 0;
10 G_TOT_INFLOW_AMT NUMBER := 0;
11 G_TOT_RV_AMT NUMBER := 0;
12
13 G_INVALID_VALUE CONSTANT VARCHAR2(200) := 'OKL_INVALID_VALUE ';
14 G_LLA_NO_MATCHING_RECORD CONSTANT VARCHAR2(200) := 'OKL_LLA_NO_MATCHING_RECORD';
15 G_COL_NAME_TOKEN CONSTANT VARCHAR2(200) := OKL_API.G_COL_NAME_TOKEN;
16 G_REQUIRED_VALUE CONSTANT VARCHAR2(200) := OKL_API.G_REQUIRED_VALUE;
17
18 PROCEDURE get_rate(p_khr_id IN NUMBER,
19 p_date IN DATE,
20 p_line_type IN VARCHAR2,
21 x_rate OUT NOCOPY NUMBER,
22 x_return_status OUT NOCOPY VARCHAR2) IS
23
24 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'get_rate';
25
26 Cursor c_rate Is
27 SELECT rte.amount rate,
28 ele.stream_element_date ele_date,
29 ele.comments
30 FROM okc_k_headers_b chr_so,
31 okc_line_styles_b lse_so,
32 okc_k_lines_b cle_so,
33 okl_strm_type_b sty,
34 okl_streams stm,
35 okl_strm_elements ele,
36 okl_strm_elements rte
37 WHERE stm.khr_id = chr_so.id
38 AND chr_so.id = p_khr_id
39 AND stm.kle_id = cle_so.id
40 AND cle_so.dnz_chr_id = chr_so.id
41 AND cle_so.lse_id = lse_so.id
42 AND lse_so.lty_code = p_line_type --'SO_PAYMENT'
43 AND stm.sty_id = sty.id
44 AND sty.stream_type_purpose = 'RENT'
45 AND stm.say_code = 'WORK'
46 AND stm.purpose_code = 'FLOW'
47 AND ele.stm_id = stm.id
48 AND rte.stm_id = stm.id
49 AND rte.sel_id = ele.id
50 ORDER BY ele.stream_element_date;
51
52 r_rate c_rate%ROWTYPE;
53 x_prev_rate NUMBER;
54
55 Begin
56
57 FOR r_rate in c_rate
58 LOOP
59
60 If ( p_date = r_rate.ele_date ) Then
61 x_rate := r_rate.rate;
62 return;
63 ElsIf (( p_date < r_rate.ele_date ) AND (r_rate.comments = 'Y') ) THen -- arrears
64 x_rate := r_rate.rate;
65 return;
66 ElsIf (( p_date < r_rate.ele_date ) AND (r_rate.comments = 'N') ) THen -- advance
67 x_rate := x_prev_rate;
68 return;
69 Else
70 x_prev_rate := r_rate.rate;
71 End If;
72
73 END LOOP;
74
75 x_rate := x_prev_rate; -- rate for the stubs.
76 return;
77
78 End get_rate;
79
80 PROCEDURE get_rate(p_khr_id IN NUMBER,
81 p_date IN DATE,
82 x_rate OUT NOCOPY NUMBER,
83 x_return_status OUT NOCOPY VARCHAR2) IS
84
85 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'get_rate';
86
87 Cursor c_rate Is
88 SELECT rte.amount rate,
89 ele.stream_element_date ele_date,
90 ele.comments
91 FROM okc_k_headers_b chr_so,
92 okc_line_styles_b lse_so,
93 okc_k_lines_b cle_so,
94 okl_strm_type_b sty,
95 okl_streams stm,
96 okl_strm_elements ele,
97 okl_strm_elements rte
98 WHERE stm.khr_id = chr_so.id
99 AND chr_so.id = p_khr_id
100 AND stm.kle_id = cle_so.id
101 AND cle_so.dnz_chr_id = chr_so.id
102 AND cle_so.lse_id = lse_so.id
103 AND lse_so.lty_code = 'SO_PAYMENT'
104 AND stm.sty_id = sty.id
105 AND sty.stream_type_purpose = 'RENT'
106 AND stm.say_code = 'WORK'
107 AND stm.purpose_code = 'FLOW'
108 AND ele.stm_id = stm.id
109 AND rte.stm_id = stm.id
110 AND rte.sel_id = ele.id
111 ORDER BY ele.stream_element_date;
112
113 r_rate c_rate%ROWTYPE;
114 x_prev_rate NUMBER;
115
116 Begin
117
118 FOR r_rate in c_rate
119 LOOP
120
121 If ( p_date = r_rate.ele_date ) Then
122 x_rate := r_rate.rate;
123 return;
124 ElsIf (( p_date < r_rate.ele_date ) AND (r_rate.comments = 'Y') ) THen -- arrears
125 x_rate := r_rate.rate;
126 return;
127 ElsIf (( p_date < r_rate.ele_date ) AND (r_rate.comments = 'N') ) THen -- advance
128 x_rate := x_prev_rate;
129 return;
130 Else
131 x_prev_rate := r_rate.rate;
132 End If;
133
134 END LOOP;
135
136 x_rate := x_prev_rate; -- rate for the stubs.
137 return;
138
139 End get_rate;
140
141
142 ---------------------------------------------------------------------------
143 -- PROCEDURE get_quote_amortization
144 --
145 -- Description
146 -- Populates Stream Element arrays with loan specific streams
147 ---------------------------------------------------------------------------
148 -- bug 2992184. Added p_purpose_code parameter.
149 PROCEDURE get_quote_amortization(p_khr_id IN NUMBER,
150 p_kle_id IN NUMBER,
151 p_investment IN NUMBER,
152 p_residual_value IN NUMBER,
153 p_start_date IN DATE,
154 p_asset_start_date IN DATE,
155 p_term_duration IN NUMBER,
156 x_principal_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
157 x_interest_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
158 x_prin_bal_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
159 x_termination_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
160 x_pre_tax_inc_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
161 x_interim_interest OUT NOCOPY NUMBER,
162 x_interim_days OUT NOCOPY NUMBER,
163 x_interim_dpp OUT NOCOPY NUMBER,
164 x_iir OUT NOCOPY NUMBER,
165 x_booking_yield OUT NOCOPY NUMBER,
166 x_return_status OUT NOCOPY VARCHAR2) IS
167
168 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'get_quote_amortization';
169
170 CURSOR c_rent_slls ( streamName VARCHAR2 ) IS
171 SELECT FND_DATE.canonical_to_date(sll.rule_information2) start_date,
172 TO_NUMBER(SLL.rule_information3) periods,
173 DECODE(sll.object1_id1, 'M', 30, 'Q', 120, 'S', 180, 'A', 360) dpp,
174 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) mpp,
175 NVL(sll.rule_information10, 'N') arrears_yn,
176 FND_NUMBER.canonical_to_number(sll.rule_information6) rent_amount
177 FROM okc_rules_b sll,
178 okc_rules_b slh,
179 okc_rule_groups_b rgp,
180 okl_strm_type_b sty,
181 okl_strm_type_tl styt
182 WHERE rgp.dnz_chr_id = p_khr_id
183 AND rgp.cle_id = p_kle_id
184 AND rgp.rgd_code= 'LALEVL'
185 AND rgp.id = slh.rgp_id
186 AND slh.rule_information_category = 'LASLH'
187 AND TO_NUMBER(slh.object1_id1) = sty.id
188 AND sty.version = '1.0'
189 AND sty.id = styt.id
190 AND STYT.LANGUAGE = USERENV('LANG') -- Bug 4626837
191 AND styt.name = streamName
192 AND TO_CHAR(slh.id) = sll.object2_id1
193 AND sll.rule_information_category = 'LASLL'
194 ORDER BY fnd_date.canonical_to_date(sll.rule_information2);
195
196 l_rent_sll c_rent_slls%ROWTYPE;
197
198 -- bug 2992184. Added where condition for multi-gaap reporting streams.
199 CURSOR c_rent_flows ( streamName VARCHAR2 ) IS
200 SELECT sel.id se_id,
201 sel.amount se_amount,
202 sel.stream_element_date se_date,
203 sel.comments se_arrears,
204 sel.sel_id se_sel_id
205 FROM okl_strm_elements sel,
206 okl_streams stm,
207 okl_strm_type_b sty,
208 okl_strm_type_tl styt
209 WHERE stm.kle_id = p_kle_id
210 AND stm.say_code = 'CURR'
211 AND stm.purpose_code IS NULL
212 AND stm.sty_id = sty.id
213 AND sty.version = '1.0'
214 AND sty.id = styt.id
215 AND STYT.LANGUAGE = USERENV('LANG') -- Bug 4626837
216 AND styt.name = streamName
217 AND stm.id = sel.stm_id
218 ORDER BY sel.stream_element_date;
219
220 Cursor c_stub IS
221 Select sel.id
222 from okl_streams stm,
223 okl_strm_elements sel
224 where stm.khr_id = p_khr_id
225 and stm.say_code = 'HIST'
226 and stm.SGN_CODE = 'MANL'
227 and stm.active_yn = 'N'
228 and stm.purpose_code = 'STUBS'
229 and stm.comments = 'STUB STREAMS'
230 and sel.stm_id = stm.id;
231 -- get payment next date after stub
232 CURSOR c_date_pay_stub(p_khr_id NUMBER,
233 p_kle_id NUMBER,
234 p_date date)
235 IS
236 SELECT TRUNC(FND_DATE.canonical_to_date(crl.rule_information2))
237 FROM okc_rule_groups_b crg,
238 okc_rules_b crl
239 WHERE crl.rgp_id = crg.id
240 AND crg.rgd_code = 'LALEVL'
241 AND crl.rule_information_category = 'LASLL'
242 AND crg.dnz_chr_id = p_khr_id
243 AND crg.cle_id = p_kle_id
244 AND TRUNC(FND_DATE.canonical_to_date(crl.rule_information2)) > TRUNC(p_date)
245 AND crl.rule_information2 IS NOT NULL
246 AND crl.rule_information6 IS NOT NULL
247 ORDER BY FND_DATE.canonical_to_date(crl.rule_information2);
248
249 l_stub_id NUMBER;
250
251 TYPE loan_rec IS RECORD (
252 se_amount NUMBER,
253 se_date DATE,
254 se_days NUMBER,
255 se_stub VARCHAR2(1),
256 se_arrears okl_strm_elements.comments%type);
257
258 TYPE loan_tbl IS TABLE OF loan_rec INDEX BY BINARY_INTEGER;
259
260 asset_rents loan_tbl;
261 loan_payment loan_tbl;
262 pricipal_payment loan_tbl;
263 interest_payment loan_tbl;
264 pre_tax_income loan_tbl;
265 termination_val loan_tbl;
266
267 l_iir_limit NUMBER := NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IIR_LIMIT')), 1000)/100;
268
269 l_start_date DATE;
270 l_sll_start_date DATE;
271 l_end_date DATE;
272 l_interim_days NUMBER;
273 l_interim_interest NUMBER;
274 l_open_book NUMBER;
275 l_close_book NUMBER;
276 l_payment NUMBER;
277 l_interest NUMBER;
278 l_principal NUMBER;
279 l_se_date DATE;
280 l_termination_val NUMBER;
281 l_days NUMBER;
282 l_iir NUMBER := 0;
283 l_bk_yield NUMBER := 0;
284
285 l_rent_period_end DATE;
286 l_k_end_date DATE := (ADD_MONTHS(p_start_date, p_term_duration) - 1);
287 l_total_periods NUMBER := 0;
288 l_term_complete VARCHAR2(1) := 'N';
289
290 l_increment NUMBER := 0.1;
291 l_abs_incr NUMBER;
292 l_prev_incr_sign NUMBER;
293 l_crossed_zero VARCHAR2(1) := 'N';
294
295 l_diff NUMBER;
296 l_prev_diff NUMBER;
297 l_prev_diff_sign NUMBER;
298
299 i BINARY_INTEGER := 0;
300 j BINARY_INTEGER := 0;
301 k BINARY_INTEGER := 0;
302 m BINARY_INTEGER := 0;
303 l BINARY_INTEGER := 0;
304
305 lx_return_status VARCHAR2(1);
306
307 Cursor fee_type_csr IS
308 Select nvl(fee_type, 'XYZ' ) fee_type
309 from okl_k_lines
310 where id = p_kle_id;
311
312 fee_type_rec fee_type_csr%ROWTYPe;
313
314
315 l_stream_name VARCHAR2(256);
316
317 cursor fee_strm_type_csr is
318 SELECT styt.name
319 FROM okc_rules_b sll,
320 okc_rules_b slh,
321 okc_rule_groups_b rgp,
322 okl_strm_type_b sty,
323 okl_strm_type_tl styt
324 WHERE rgp.dnz_chr_id = p_khr_id
325 AND rgp.cle_id = p_kle_id
326 AND rgp.rgd_code= 'LALEVL'
327 AND rgp.id = slh.rgp_id
328 AND slh.rule_information_category = 'LASLH'
329 AND TO_NUMBER(slh.object1_id1) = sty.id
330 AND sty.version = '1.0'
331 AND sty.id = styt.id
332 AND STYT.LANGUAGE = USERENV('LANG') -- Bug 4626837
333 AND TO_CHAR(slh.id) = sll.object2_id1
334 AND sll.rule_information_category = 'LASLL'
335 ORDER BY fnd_date.canonical_to_date(sll.rule_information2);
336
337 l_was_a_stub_payment VARCHAR2(1) := 'N';
338
339 l_day_convention_month VARCHAR2(30);
340 l_day_convention_year VARCHAR2(30);
341 l_days_in_year NUMBER;
342 BEGIN
343 IF (G_DEBUG_ENABLED = 'Y') THEN
344 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
345 END IF;
346
347 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
348 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'begin' );
349
350 END IF;
351 x_return_status := OKL_API.G_RET_STS_SUCCESS;
352 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
353 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' Investment ' || to_char( p_investment ));
354
355 END IF;
356 OPEN c_stub;
357 FETCH c_stub INTO l_stub_id;
358 CLOSE c_stub;
359
360 OPEN fee_strm_type_csr;
361 FETCH fee_strm_type_csr INTO l_stream_name;
362 CLOSE fee_strm_type_csr;
363
364 OPEN c_rent_slls( l_stream_name );
365 FETCH c_rent_slls INTO l_rent_sll;
366 CLOSE c_rent_slls;
367
368 l_start_date := l_rent_sll.start_date;
369 -- Fetch the day convention ..
370 OKL_PRICING_UTILS_PVT.get_day_convention(
371 p_id => p_khr_id,
372 p_source => 'ISG',
373 x_days_in_month => l_day_convention_month,
374 x_days_in_year => l_day_convention_year,
375 x_return_status => lx_return_status);
376 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
377 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
378 END IF;
379 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
380 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
381 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
382 RAISE OKL_API.G_EXCEPTION_ERROR;
383 END IF;
384
385 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
386 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'sll start date ' || l_start_date );
387 END IF;
388 FOR l_rent_flow IN c_rent_flows( l_stream_name ) LOOP
389
390 k := k + 1;
391
392 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
393 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'rent flow start date ' || l_rent_flow.se_date );
394 END IF;
395 asset_rents(k).se_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
396 p_days_in_month => l_day_convention_month,
397 p_days_in_year => l_day_convention_year,
398 p_end_date => l_rent_flow.se_date,
399 p_arrears => l_rent_flow.se_arrears,
400 x_return_status => lx_return_status);
401
402 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
403 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
404 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
405 RAISE OKL_API.G_EXCEPTION_ERROR;
406 END IF;
407
408 asset_rents(k).se_amount := l_rent_flow.se_amount;
409 asset_rents(k).se_date := l_rent_flow.se_date;
410 asset_rents(k).se_arrears := l_rent_flow.se_arrears;
411
412 l_start_date := l_rent_flow.se_date;
413
414 IF l_rent_flow.se_arrears = 'Y' THEN
415 l_start_date := l_start_date + 1;
416 END IF;
417
418 If ( nvl(l_rent_flow.se_sel_id, -1) = l_stub_id ) Then
419 asset_rents(k).se_stub := 'Y';
420 End If;
421
422 END LOOP;
423
424 l_interim_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_asset_start_date,
425 p_end_date => l_rent_sll.start_date,
426 p_days_in_month => l_day_convention_month,
427 p_days_in_year => l_day_convention_year,
428 p_arrears => 'N',
429 x_return_status => lx_return_status);
430
431 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
432 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
433 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
434 RAISE OKL_API.G_EXCEPTION_ERROR;
435 END IF;
436
437 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
438 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' asset rent count ' || to_char(asset_rents.COUNT));
439 END IF;
440 LOOP
441
442 i := i + 1;
443
444 l_interim_interest := p_investment * l_interim_days * l_iir/360;
445
446 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
447 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || i||' Implicit Rate '||l_iir||' Interim Interest '||l_interim_interest
448 ||' Interim Days = '||l_interim_days);
449
450 END IF;
451 l_open_book := p_investment;
452 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
453 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' Investment ' || to_char(l_open_book));
454
455 END IF;
456 FOR k IN 1..asset_rents.COUNT LOOP
457
458 l_payment := asset_rents(k).se_amount;
459 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
460 l_principal := l_payment - l_interest;
461 l_close_book := l_open_book - l_principal;
462 l_open_book := l_close_book;
463
464 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
465 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' '||TO_CHAR(asset_rents(k).se_date, 'DD-MON-YYYY')||' DAYS '||asset_rents(k).se_DAYS
466 || ' LOAN PAYMENT '||l_payment|| ' INTEREST '||ROUND(l_interest, 3)
467 || ' PRINCIPAL '||ROUND(l_principal, 3)||' Next OB '||ROUND(l_open_book, 3));
468
469 END IF;
470 END LOOP;
471
472 l_diff := l_open_book;
473
474 IF ROUND(l_diff, 4) = 0 THEN
475
476 l_open_book := p_investment;
477
478 FOR k IN asset_rents.FIRST .. asset_rents.LAST LOOP
479
480 l_payment := asset_rents(k).se_amount;
481 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
482 l_principal := l_payment - l_interest;
483 l_close_book := l_open_book - l_principal;
484
485 l_se_date := asset_rents(k).se_date;
486
487 x_principal_tbl(k).amount := l_principal;
488 x_interest_tbl(k).amount := l_interest;
489 x_prin_bal_tbl(k).amount := l_close_book;
490
491 x_principal_tbl(k).se_line_number := k;
492 x_interest_tbl(k).se_line_number := k;
493 x_prin_bal_tbl(k).se_line_number := k;
494
495 x_principal_tbl(k).stream_element_date := l_se_date;
496 x_interest_tbl(k).stream_element_date := l_se_date;
497 x_prin_bal_tbl(k).stream_element_date := l_se_date;
498
499 l_open_book := l_close_book;
500
501 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
502 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || asset_rents(k).se_days || ':' || l_close_book || ':' || l_interest || ':' || l_principal || ':' || l_se_date );
503 END IF;
504 END LOOP;
505
506 IF l_interim_interest > 0 THEN
507
508 IF l_rent_sll.arrears_yn = 'Y' THEN
509
510 x_principal_tbl(asset_rents.FIRST-1).amount := 0;
511 x_interest_tbl(asset_rents.FIRST-1).amount := l_interim_interest;
512 x_prin_bal_tbl(asset_rents.FIRST-1).amount := p_investment;
513
514 x_principal_tbl(asset_rents.FIRST-1).se_line_number := 0;
515 x_interest_tbl(asset_rents.FIRST-1).se_line_number := 0;
516 x_prin_bal_tbl(asset_rents.FIRST-1).se_line_number := 0;
517
518 x_principal_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
519 x_interest_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
520 x_prin_bal_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
521
522 ELSE
523
524 x_interest_tbl(asset_rents.FIRST).amount := l_interim_interest;
525
526 END IF;
527
528 END IF;
529
530 x_interim_interest := l_interim_interest;
531 x_interim_days := l_interim_days;
532 x_interim_dpp := l_rent_sll.dpp;
533 x_iir := l_iir;
534
535 EXIT;
536
537 END IF;
538
539 IF SIGN(l_diff) <> SIGN(l_prev_diff) AND l_crossed_zero = 'N' THEN
540 l_crossed_zero := 'Y';
541 END IF;
542
543 IF l_crossed_zero = 'Y' THEN
544 l_abs_incr := ABS(l_increment) / 2;
545 ELSE
546 l_abs_incr := ABS(l_increment);
547 END IF;
548
549 IF i > 1 THEN
550 IF SIGN(l_diff) <> l_prev_diff_sign THEN
551 IF l_prev_incr_sign = 1 THEN
552 l_increment := - l_abs_incr;
553 ELSE
554 l_increment := l_abs_incr;
555 END IF;
556 ELSE
557 IF l_prev_incr_sign = 1 THEN
558 l_increment := l_abs_incr;
559 ELSE
560 l_increment := - l_abs_incr;
561 END IF;
562 END IF;
563 ELSE
564 IF SIGN(l_diff) = 1 THEN
565 l_increment := -l_increment;
566 ELSE
567 l_increment := l_increment;
568 END IF;
569 END IF;
570
571 l_iir := l_iir + l_increment;
572
573 IF ABS(l_iir) > l_iir_limit THEN
574
575 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
576 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' irr ' || ABS(l_iir) );
577 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' irr limit ' || l_iir_limit );
578
579 END IF;
580 If k = 1 then
581
582 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
583 p_msg_name => 'OKL_CANNOT_CALC_IIR');
584 Else
585
586 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
587 p_msg_name => 'OKL_IIR_CALC_IIR_LIMIT',
588 p_token1 => 'IIR_LIMIT',
589 p_token1_value => l_iir_limit*100);
590 End If;
591
592 RAISE OKL_API.G_EXCEPTION_ERROR;
593 END IF;
594
595 l_prev_incr_sign := SIGN(l_increment);
596 l_prev_diff_sign := SIGN(l_diff);
597 l_prev_diff := l_diff;
598
599 END LOOP;
600
601 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
602 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' done with iir ' );
603
604 END IF;
605 -------------------------------------------
606 -- PRE-TAX INCOME
607 -------------------------------------------
608
609 -- Reset local variables
610
611 l_start_date := NULL;
612 l_se_date := NULL;
613 l_abs_incr := NULL;
614 l_prev_incr_sign := NULL;
615 l_crossed_zero := 'N';
616 l_diff := NULL;
617 l_prev_diff := NULL;
618 l_prev_diff_sign := NULL;
619 i := 0;
620 j := 0;
621 k := 0;
622 m := 0;
623
624 l_bk_yield := 0;
625 l_increment := 0.1;
626
627 -- handlig residual value at the last payment
628 --asset_rents(asset_rents.LAST).se_amount := asset_rents(asset_rents.LAST).se_amount + p_residual_value;
629 ---
630
631 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
632 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' start with bkg yld ' );
633 END IF;
634 LOOP
635
636 --DEBUG
637 --EXIT WHEN i = 2;
638
639 i := i + 1;
640
641 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
642 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '');
643 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Booking Yield Iteration # '||i||' Guess Value '||l_bk_yield);
644
645 END IF;
646 l_termination_val := p_investment;
647 k := 1;
648 j := 0;
649 m := 0;
650 l_start_date := l_rent_sll.start_date;
651 l_sll_start_date := TRUNC(asset_rents(asset_rents.FIRST).se_date);
652 l_term_complete := 'N';
653
654 LOOP
655
656 l_was_a_stub_payment := 'N';
657
658 j := j + 1;
659
660 l_se_date := asset_rents(k).se_date;
661
662 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
663 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' l_se_date ' || LAST_DAY(l_se_date) || ' l_start_date ' || LAST_DAY(l_start_date) );
664
665 END IF;
666 IF TRUNC(LAST_DAY(l_se_date)) <> TRUNC(LAST_DAY(l_start_date)) THEN -- NON payment month
667
668 l_end_date := LAST_DAY(l_start_date);
669
670 l_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
671 p_days_in_month => l_day_convention_month,
672 p_days_in_year => l_day_convention_year,
673 p_end_date => l_end_date,
674 p_arrears => 'Y',
675 x_return_status => lx_return_status);
676
677 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
678 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
679 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
680 RAISE OKL_API.G_EXCEPTION_ERROR;
681 END IF;
682
683 pre_tax_income(j).se_amount := l_termination_val*l_days*l_bk_yield/360;
684 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
685 termination_val(j).se_amount := l_termination_val;
686
687 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
688 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Non Payment Month '||TO_CHAR(l_start_date, 'MON-YYYY')|| ' DAYS '||l_days|| ' Income '
689 ||ROUND(pre_tax_income(j).se_amount, 3)|| ' Month Ending TV '
690 ||ROUND(termination_val(j).se_amount, 3));
691
692 END IF;
693 l_se_date := LAST_DAY(l_start_date);
694
695
696 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
697 l_se_date := l_se_date - 1;
698 END IF;
699
700
701 termination_val(j).se_date := l_se_date;
702 pre_tax_income(j).se_date := l_se_date;
703
704 ELSE -- payment month
705
706 -- first half of payment month
707
708 l_end_date := l_se_date;
709
710 l_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
711 p_days_in_month => l_day_convention_month,
712 p_days_in_year => l_day_convention_year,
713 p_end_date => l_end_date,
714 p_arrears => l_rent_sll.arrears_yn,
715 x_return_status => lx_return_status);
716
717 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
718 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
719 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
720 RAISE OKL_API.G_EXCEPTION_ERROR;
721 END IF;
722
723 IF j = 1 AND l_interim_interest > 0 THEN
724
725 l_days := 0;
726
727 END IF;
728
729
730 pre_tax_income(j).se_amount := l_termination_val*l_days*l_bk_yield/360;
731
732 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
733 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name ||
734 'PAY MO. '||TO_CHAR(l_start_date, 'MON-YYYY')||
735 ' Days pre-RENT '||l_days||
736 ' TV for CALC '||ROUND(l_termination_val, 3)||
737 ' ACC INT '||ROUND(pre_tax_income(j).se_amount, 3)||
738 ' TV after RENT '||ROUND(l_termination_val + pre_tax_income(j).se_amount - asset_rents(k).se_amount, 3));
739
740 END IF;
741 l_termination_val := l_termination_val + pre_tax_income(j).se_amount;
742 l_termination_val := l_termination_val - asset_rents(k).se_amount;
743
744 -- 2nd half of payment month
745
746 IF k = asset_rents.LAST THEN -- check for last payment
747
748 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
749 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '');
750 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Last RENT recieved '||TO_CHAR(asset_rents(k).se_date, 'DD-MON-YYYY'));
751 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '');
752
753 END IF;
754 l_start_date := l_se_date;
755
756 LOOP
757 --DEBUG
758 --EXIT WHEN m > 10;
759 m := m + 1;
760
761 IF TRUNC(LAST_DAY(l_start_date)) <> TRUNC(LAST_DAY(l_k_end_date)) THEN
762 l_end_date := LAST_DAY(l_start_date);
763 ELSE
764 l_end_date := l_k_end_date;
765 END IF;
766
767 l_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
768 p_days_in_month => l_day_convention_month,
769 p_days_in_year => l_day_convention_year,
770 p_end_date => l_end_date,
771 p_arrears => 'Y',
772 x_return_status => lx_return_status);
773
774 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
775 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
776 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
777 RAISE OKL_API.G_EXCEPTION_ERROR;
778 END IF;
779
780 IF (l_rent_sll.arrears_yn = 'Y') AND (m = 1) THEN
781 l_days := l_days - 1;
782 END IF;
783
784 IF m = 1 THEN
785 pre_tax_income(j).se_amount := pre_tax_income(j).se_amount+l_termination_val*l_days*l_bk_yield/360;
786 ELSE
787 pre_tax_income(j).se_amount := l_termination_val*l_days*l_bk_yield/360;
788 END IF;
789
790 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
791
792 IF TRUNC(l_end_date) = TRUNC(l_k_end_date) THEN
793 l_termination_val := l_termination_val - p_residual_value;
794 l_term_complete := 'Y';
795 END IF;
796
797 termination_val(j).se_amount := l_termination_val;
798
799 l_se_date := LAST_DAY(l_start_date);
800
801 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
802 l_se_date := l_se_date - 1;
803 END IF;
804
805 termination_val(j).se_date := l_se_date;
806 pre_tax_income(j).se_date := l_se_date;
807
808 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
809 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name ||
810 '('||TO_CHAR(l_start_date, 'DD-MON-YYYY')||
811 ' - '||TO_CHAR(l_end_date, 'DD-MON-YYYY')||
812 ') Days '||l_days||
813 ' Income '||ROUND(pre_tax_income(j).se_amount,3)||
814 ' T Val '||ROUND(termination_val(j).se_amount, 3));
815
816 END IF;
817 EXIT WHEN TRUNC(l_end_date) = TRUNC(l_k_end_date);
818
819 l_start_date := LAST_DAY(l_start_date) + 1;
820 j := j + 1;
821
822 END LOOP;
823
824 ELSE -- last payment has NOT occurred
825
826 IF NVL(asset_rents(k).se_stub,'N')='Y' THEN
827 -- Fetching the next payment date
828 -- interested only in the first record
829 l_sll_start_date := TRUNC(asset_rents(k+1).se_date);
830 END IF;
831 -- if the stub and next payment fall in the same month
832 -- then we use the below logic
833
834 IF NVL(asset_rents(k).se_stub,'N')='Y' AND
835 LAST_DAY(TRUNC(NVL(l_sll_start_date,l_end_date))) = LAST_DAY(TRUNC(l_end_date)) THEN
836
837 l_was_a_stub_payment := 'Y';
838 l_start_date := TRUNC(l_end_date);
839 l_end_date := TRUNC(NVL(l_sll_start_date,l_end_Date));
840 l_se_date := TRUNC(NVL(l_sll_start_date,l_end_Date));
841
842 l_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
843 p_days_in_month => l_day_convention_month,
844 p_days_in_year => l_day_convention_year,
845 p_end_date => l_end_date,
846 p_arrears => l_rent_sll.arrears_yn,
847 x_return_status => lx_return_status);
848
849 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
850 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
851 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
852 RAISE OKL_API.G_EXCEPTION_ERROR;
853 END IF;
854
855 IF j = 1 AND l_interim_interest > 0 THEN
856 l_days := 0;
857 END IF;
858
859
860 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
861 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name ||
862 'PAY MO. '||TO_CHAR(l_start_date, 'MON-YYYY')||
863 ' Days stub '||l_days||
864 ' TV for CALC '||ROUND(l_termination_val, 3)||
865 ' INC (stub) '||ROUND(l_termination_val*l_days*l_bk_yield/360, 3)||
866 ' ME TV '||ROUND(l_termination_val * ( 1 + l_days*l_bk_yield/360) -
867 asset_rents(k+1).se_amount));
868
869 END IF;
870 pre_tax_income(j).se_amount := pre_tax_income(j).se_amount+l_termination_val*l_days*l_bk_yield/360;
871 --l_termination_val := l_termination_val + pre_tax_income(j).se_amount;
872 l_termination_val := l_termination_val * ( 1 + l_days*l_bk_yield/360);
873 l_termination_val := l_termination_val - asset_rents(k+1).se_amount;
874
875
876 IF (k+1) = asset_rents.LAST THEN
877
878 l_start_date := l_se_date;
879 LOOP
880 m := m + 1;
881 IF LAST_DAY(l_start_date) <> LAST_DAY(l_k_end_date) THEN
882 l_end_date := LAST_DAY(l_start_date);
883 ELSE
884 l_end_date := l_k_end_date;
885 END IF;
886 l_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
887 p_days_in_month => l_day_convention_month,
888 p_days_in_year => l_day_convention_year,
889 p_end_date => l_end_date,
890 p_arrears => 'Y',
891 x_return_status => lx_return_status);
892
893 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
894 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
895 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
896 RAISE OKL_API.G_EXCEPTION_ERROR;
897 END IF;
898 IF (l_rent_sll.arrears_yn = 'Y') AND (m = 1) THEN
899 l_days := l_days - 1;
900 END IF;
901 IF m = 1 THEN
902 pre_tax_income(j).se_amount := pre_tax_income(j).se_amount+
903 l_termination_val*l_days*l_bk_yield/360;
904 ELSE
905 pre_tax_income(j).se_amount := l_termination_val*l_days*l_bk_yield/360;
906 END IF;
907 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
908 IF TRUNC(l_end_date) = TRUNC(l_k_end_date) THEN
909 l_termination_val := l_termination_val - p_residual_value;
910 l_term_complete := 'Y';
911 END IF;
912 termination_val(j).se_amount := l_termination_val;
913 l_se_date := LAST_DAY(l_start_date);
914 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
915 l_se_date := l_se_date - 1;
916 END IF;
917
918 termination_val(j).se_date := l_se_date;
919 pre_tax_income(j).se_date := l_se_date;
920
921 EXIT WHEN TRUNC(l_end_date) = TRUNC(l_k_end_date);
922 l_start_date := LAST_DAY(l_start_date) + 1;
923 j := j + 1;
924
925 END LOOP;
926
927 End If;
928
929 -- l_start_date := asset_rents(k).se_date+1;
930 k := k + 1;
931 l_se_date := asset_rents(k).se_date;
932
933 EXIT WHEN l_term_complete = 'Y';
934
935 ElsIF NVL(asset_rents(k+1).se_stub,'N')='Y' AND
936 LAST_DAY(TRUNC(asset_rents(k+1).se_date)) = LAST_DAY(TRUNC(asset_rents(k).se_date)) THEN
937
938 k := k + 1;
939 l_start_date := TRUNC(l_end_date);
940 l_end_date := TRUNC(asset_rents(k).se_date);
941 l_se_date := TRUNC(asset_rents(k).se_date);
942
943 l_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
944 p_days_in_month => l_day_convention_month,
945 p_days_in_year => l_day_convention_year,
946 p_end_date => l_end_date,
947 p_arrears => l_rent_sll.arrears_yn,
948 x_return_status => lx_return_status);
949
950 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
951 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
952 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
953 RAISE OKL_API.G_EXCEPTION_ERROR;
954 END IF;
955
956 IF j = 1 AND l_interim_interest > 0 THEN
957 l_days := 0;
958 END IF;
959
960
961 IF (l_rent_sll.arrears_yn = 'Y') AND
962 (TO_CHAR(l_end_date, 'DD') IN ('30', '31') OR
963 (TO_CHAR(l_end_date, 'MON') = 'FEB' AND
964 TO_CHAR(l_end_date, 'DD') IN ('28', '29')) ) THEN
965
966 l_days := l_days - 1;
967
968 END IF;
969
970 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
971 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name ||
972 'PAY MO. '||TO_CHAR(l_start_date, 'MON-YYYY')||
973 ' Days stub '||l_days||
974 ' TV for CALC '||ROUND(l_termination_val, 3)||
975 ' INC (stub) '||ROUND(l_termination_val*l_days*l_bk_yield/360, 3)||
976 ' ME TV '||ROUND(l_termination_val * ( 1 + l_days*l_bk_yield/360) -
977 asset_rents(k).se_amount));
978
979 END IF;
980 pre_tax_income(j).se_amount := pre_tax_income(j).se_amount+l_termination_val*l_days*l_bk_yield/360;
981 l_termination_val := l_termination_val * ( 1 + l_days*l_bk_yield/360);
982 l_termination_val := l_termination_val - asset_rents(k).se_amount;
983
984
985 IF k = asset_rents.LAST THEN
986
987 l_start_date := l_se_date;
988 LOOP
989 m := m + 1;
990 IF LAST_DAY(l_start_date) <> LAST_DAY(l_k_end_date) THEN
991 l_end_date := LAST_DAY(l_start_date);
992 ELSE
993 l_end_date := l_k_end_date;
994 END IF;
995
996 l_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
997 p_days_in_month => l_day_convention_month,
998 p_days_in_year => l_day_convention_year,
999 p_end_date => l_end_date,
1000 p_arrears => 'Y',
1001 x_return_status => lx_return_status);
1002
1003 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
1004 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1005 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
1006 RAISE OKL_API.G_EXCEPTION_ERROR;
1007 END IF;
1008 IF (l_rent_sll.arrears_yn = 'Y') AND (m = 1) THEN
1009 l_days := l_days - 1;
1010 END IF;
1011 IF m = 1 THEN
1012 pre_tax_income(j).se_amount := pre_tax_income(j).se_amount+
1013 l_termination_val*l_days*l_bk_yield/360;
1014 ELSE
1015 pre_tax_income(j).se_amount := l_termination_val*l_days*l_bk_yield/360;
1016 END IF;
1017 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
1018 IF TRUNC(l_end_date) = TRUNC(l_k_end_date) THEN
1019 l_termination_val := l_termination_val - p_residual_value;
1020 l_term_complete := 'Y';
1021 END IF;
1022 termination_val(j).se_amount := l_termination_val;
1023 l_se_date := LAST_DAY(l_start_date);
1024 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
1025 l_se_date := l_se_date - 1;
1026 END IF;
1027
1028 termination_val(j).se_date := l_se_date;
1029 pre_tax_income(j).se_date := l_se_date;
1030
1031 EXIT WHEN TRUNC(l_end_date) = TRUNC(l_k_end_date);
1032 l_start_date := LAST_DAY(l_start_date) + 1;
1033 j := j + 1;
1034
1035 END LOOP;
1036
1037 End If;
1038
1039 End If;
1040
1041 IF TO_CHAR(TRUNC(l_end_date),'MON') = 'FEB' THEN
1042 IF TO_CHAR(TRUNC(l_sll_start_date),'DD') IN (30,31) OR
1043 (TO_CHAR(TRUNC(l_sll_start_date),'DD') = 1 AND
1044 (l_was_a_stub_payment = 'Y' OR l_rent_sll.arrears_yn = 'Y')) OR
1045 (TO_CHAR(TRUNC(l_sll_start_date),'MON') = 'FEB' AND
1046 TO_CHAR(TRUNC(l_sll_start_date),'DD') = 29) OR
1047 (TO_CHAR(TRUNC(l_sll_start_date),'MON') = 'FEB' AND
1048 TO_CHAR(TRUNC(l_sll_start_date),'DD') = 28) THEN
1049 l_days := 0;
1050 ELSE
1051 l_days := 30 - TO_CHAR(TRUNC(l_end_date), 'DD');
1052 END IF;
1053 ELSE
1054 l_days := 30 - TO_CHAR(TRUNC(l_end_date), 'DD');
1055 END IF;
1056
1057 IF l_days <= 0 THEN
1058 IF l_rent_sll.arrears_yn = 'Y' THEN
1059 l_days := 0;
1060 ELSE
1061 l_days := 1;
1062 END IF;
1063 ELSIF l_rent_sll.arrears_yn = 'N' THEN
1064 l_days := l_days + 1;
1065 END IF;
1066
1067 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
1068 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name ||
1069 'PAY MO. '||TO_CHAR(l_start_date, 'MON-YYYY')||
1070 ' Days post-RENT '||l_days||
1071 ' TV for CALC '||ROUND(l_termination_val, 3)||
1072 ' INC (2nd half) '||ROUND(l_termination_val*l_days*l_bk_yield/360, 3)||
1073 ' ME TV '||ROUND(l_termination_val*(1 + l_days*l_bk_yield/360), 3));
1074
1075 END IF;
1076 pre_tax_income(j).se_amount := pre_tax_income(j).se_amount + l_termination_val*l_days*l_bk_yield/360;
1077
1078 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
1079 termination_val(j).se_amount := l_termination_val;
1080
1081 l_se_date := LAST_DAY(l_start_date);
1082
1083 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
1084 l_se_date := l_se_date - 1;
1085 END IF;
1086
1087 termination_val(j).se_date := l_se_date;
1088 pre_tax_income(j).se_date := l_se_date;
1089
1090 k := k + 1;
1091
1092 END IF; --------- END check last payment
1093
1094 EXIT WHEN l_term_complete = 'Y';
1095
1096 END IF; --------- END second half processing
1097
1098 l_start_date := LAST_DAY(l_start_date) + 1;
1099
1100 END LOOP;
1101
1102 --l_diff := l_termination_val - p_residual_value;
1103 l_diff := l_termination_val;
1104 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
1105 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' L_DIFF ' || l_diff );
1106
1107 END IF;
1108 IF ROUND(l_diff, 4) = 0 THEN
1109
1110 FOR j IN pre_tax_income.FIRST .. pre_tax_income.LAST LOOP
1111
1112 x_termination_tbl(j).stream_element_date := termination_val(j).se_date;
1113 x_pre_tax_inc_tbl(j).stream_element_date := pre_tax_income(j).se_date;
1114
1115 x_termination_tbl(j).amount := termination_val(j).se_amount;
1116 x_pre_tax_inc_tbl(j).amount := pre_tax_income(j).se_amount;
1117
1118 IF l_interim_interest > 0 AND
1119 (LAST_DAY(pre_tax_income(j).se_date) = LAST_DAY(l_rent_sll.start_date)) THEN
1120
1121 x_pre_tax_inc_tbl(j).amount := x_pre_tax_inc_tbl(j).amount + l_interim_interest;
1122
1123 END IF;
1124
1125 x_termination_tbl(j).se_line_number := j;
1126 x_pre_tax_inc_tbl(j).se_line_number := j;
1127 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
1128 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || x_pre_tax_inc_tbl(j).amount || ':' ||
1129 x_termination_tbl(j).amount || ':' || x_termination_tbl(j).stream_element_date );
1130
1131 END IF;
1132 END LOOP;
1133
1134 --For j in 1..l_rent_sll.mpp LOOP
1135 -- x_termination_tbl(x_termination_tbl.LAST-j+1).amount := p_residual_value;
1136 --END LOOP;
1137
1138 l_end_date := LAST_DAY(asset_rents(asset_rents.LAST).se_date);
1139 l_start_date := LAST_DAY(x_termination_tbl(x_termination_tbl.LAST).stream_element_date);
1140
1141 x_termination_tbl(x_termination_tbl.LAST).amount := p_residual_value;
1142
1143 x_booking_yield := l_bk_yield;
1144 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
1145 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' Booking yield ' || l_bk_yield );
1146
1147 END IF;
1148 RETURN;
1149
1150 END IF;
1151
1152 IF SIGN(l_diff) <> SIGN(l_prev_diff) AND l_crossed_zero = 'N' THEN
1153 l_crossed_zero := 'Y';
1154 END IF;
1155
1156 IF l_crossed_zero = 'Y' THEN
1157 l_abs_incr := ABS(l_increment) / 2;
1158 ELSE
1159 l_abs_incr := ABS(l_increment);
1160 END IF;
1161
1162 IF i > 1 THEN
1163 IF SIGN(l_diff) <> l_prev_diff_sign THEN
1164 IF l_prev_incr_sign = 1 THEN
1165 l_increment := - l_abs_incr;
1166 ELSE
1167 l_increment := l_abs_incr;
1168 END IF;
1169 ELSE
1170 IF l_prev_incr_sign = 1 THEN
1171 l_increment := l_abs_incr;
1172 ELSE
1173 l_increment := - l_abs_incr;
1174 END IF;
1175 END IF;
1176 ELSE
1177
1178 IF SIGN(l_diff) = 1 THEN
1179 l_increment := -l_increment;
1180 ELSE
1181 l_increment := l_increment;
1182 END IF;
1183 END IF;
1184
1185 l_bk_yield := l_bk_yield + l_increment;
1186 l_prev_incr_sign := SIGN(l_increment);
1187 l_prev_diff_sign := SIGN(l_diff);
1188 l_prev_diff := l_diff;
1189
1190 END LOOP;
1191
1192 x_return_status := lx_return_status;
1193 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
1194 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'end' );
1195
1196 END IF;
1197 EXCEPTION
1198
1199 WHEN OKL_API.G_EXCEPTION_ERROR THEN
1200
1201 x_return_status := G_RET_STS_ERROR;
1202
1203 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
1204
1205 x_return_status := G_RET_STS_UNEXP_ERROR;
1206
1207 WHEN OTHERS THEN
1208
1209 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
1210 p_msg_name => G_DB_ERROR,
1211 p_token1 => G_PROG_NAME_TOKEN,
1212 p_token1_value => l_prog_name,
1213 p_token2 => G_SQLCODE_TOKEN,
1214 p_token2_value => sqlcode,
1215 p_token3 => G_SQLERRM_TOKEN,
1216 p_token3_value => sqlerrm);
1217
1218 x_return_status := G_RET_STS_UNEXP_ERROR;
1219
1220 END get_quote_amortization;
1221
1222 ---------------------------------------------------------------------------
1223 -- PROCEDURE get_loan_amortization
1224 --
1225 -- Description
1226 -- Populates Stream Element arrays with loan specific streams
1227 ---------------------------------------------------------------------------
1228 -- bug 2992184. Added p_purpose_code parameter.
1229 -- Added input parameter p_se_id by prasjain for bug 5474827
1230 PROCEDURE get_loan_amortization (p_khr_id IN NUMBER,
1231 p_kle_id IN NUMBER,
1232 p_purpose_code IN VARCHAR2,
1233 p_investment IN NUMBER,
1234 p_residual_value IN NUMBER,
1235 p_start_date IN DATE,
1236 p_asset_start_date IN DATE,
1237 p_term_duration IN NUMBER,
1238 p_currency_code IN VARCHAR2, --USED?
1239 p_deal_type IN VARCHAR2, --USED?
1240 p_asset_iir_guess IN NUMBER DEFAULT NULL,
1241 p_bkg_yield_guess IN NUMBER DEFAULT NULL,
1242 x_principal_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
1243 x_interest_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
1244 x_prin_bal_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
1245 x_termination_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
1246 x_pre_tax_inc_tbl OUT NOCOPY okl_streams_pub.selv_tbl_type,
1247 x_interim_interest OUT NOCOPY NUMBER,
1248 x_interim_days OUT NOCOPY NUMBER,
1249 x_interim_dpp OUT NOCOPY NUMBER,
1250 x_iir OUT NOCOPY NUMBER,
1251 x_booking_yield OUT NOCOPY NUMBER,
1252 x_return_status OUT NOCOPY VARCHAR2,
1253 p_se_id IN NUMBER
1254 -- Params added for Prospective Rebooking
1255 ,p_during_rebook_yn IN VARCHAR2
1256 ,p_rebook_type IN VARCHAR2
1257 ,p_prosp_rebook_flag IN VARCHAR2
1258 ,p_rebook_date IN DATE
1259 ,p_income_strm_sty_id IN NUMBER
1260 ) IS
1261
1262 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'get_loan_amortization';
1263
1264 CURSOR c_rent_slls ( streamName VARCHAR2 ) IS
1265 SELECT FND_DATE.canonical_to_date(sll.rule_information2) start_date,
1266 TO_NUMBER(SLL.rule_information3) periods,
1267 DECODE(sll.object1_id1, 'M', 30, 'Q', 120, 'S', 180, 'A', 360) dpp,
1268 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) mpp,
1269 NVL(sll.rule_information10, 'N') arrears_yn,
1270 FND_NUMBER.canonical_to_number(sll.rule_information6) rent_amount
1271 FROM okc_rules_b sll,
1272 okc_rules_b slh,
1273 okc_rule_groups_b rgp,
1274 okl_strm_type_b sty,
1275 okl_strm_type_tl styt
1276 WHERE rgp.dnz_chr_id = p_khr_id
1277 AND rgp.cle_id = p_kle_id
1278 AND rgp.rgd_code= 'LALEVL'
1279 AND rgp.id = slh.rgp_id
1280 AND slh.rule_information_category = 'LASLH'
1281 AND TO_NUMBER(slh.object1_id1) = sty.id
1282 AND sty.version = '1.0'
1283 AND sty.id = styt.id
1284 AND STYT.LANGUAGE = USERENV('LANG') -- Bug 4626837
1285 AND styt.name = streamName
1286 AND TO_CHAR(slh.id) = sll.object2_id1
1287 AND sll.rule_information_category = 'LASLL'
1288 ORDER BY fnd_date.canonical_to_date(sll.rule_information2);
1289
1290 l_rent_sll c_rent_slls%ROWTYPE;
1291
1292 -- bug 2992184. Added where condition for multi-gaap reporting streams.
1293 CURSOR c_rent_flows ( streamName VARCHAR2 ) IS
1294 SELECT sel.id se_id,
1295 sel.amount se_amount,
1296 sel.stream_element_date se_date,
1297 sel.comments se_arrears,
1298 sel.sel_id se_sel_id,
1299 sty.stream_type_purpose,
1300 DECODE(sty.stream_type_purpose,
1301 'UNSCHEDULED_PRINCIPAL_PAYMENT','UPP',
1302 'UNSCHEDULED_INTEREST_PAYMENT','UIP',
1303 'DOWN_PAYMENT','DOWN_PMNT',
1304 'PRINCIPAL_PAYMENT', 'PRIN_PMNT',
1305 'RENT' ) cf_purpose
1306 FROM okl_strm_elements sel,
1307 okl_streams stm,
1308 okl_strm_type_b sty,
1309 okl_strm_type_tl styt
1310 WHERE stm.kle_id = p_kle_id
1311 AND stm.say_code = 'WORK'
1312 AND DECODE(stm.purpose_code, NULL, '-99', 'REPORT') = p_purpose_code
1313 AND stm.sty_id = sty.id
1314 AND sty.version = '1.0'
1315 AND sty.id = styt.id
1316 AND STYT.LANGUAGE = USERENV('LANG') -- Bug 4626837
1317 AND (styt.name = streamName OR
1318 sty.stream_type_purpose = 'UNSCHEDULED_PRINCIPAL_PAYMENT' OR
1319 sty.stream_type_purpose = 'UNSCHEDULED_INTEREST_PAYMENT' OR
1320 sty.stream_type_purpose = 'DOWN_PAYMENT' OR
1321 sty.stream_type_purpose = 'PRINCIPAL_PAYMENT')
1322 AND stm.id = sel.stm_id
1323 ORDER BY sel.stream_element_date;
1324
1325 /* Commented by prasjain for bug 5474827
1326 Cursor c_stub IS
1327 Select sel.id
1328 from okl_streams stm,
1329 okl_strm_elements sel
1330 where stm.khr_id = p_khr_id
1331 and stm.say_code = 'HIST'
1332 and stm.SGN_CODE = 'MANL'
1333 and stm.active_yn = 'N'
1334 and stm.purpose_code = 'STUBS'
1335 and stm.comments = 'STUB STREAMS'
1336 and sel.stm_id = stm.id;
1337 */
1338
1339 -- get payment next date after stub
1340 CURSOR c_date_pay_stub(p_khr_id NUMBER,
1341 p_kle_id NUMBER,
1342 p_date date)
1343 IS
1344 SELECT TRUNC(FND_DATE.canonical_to_date(crl.rule_information2))
1345 FROM okc_rule_groups_b crg,
1346 okc_rules_b crl
1347 WHERE crl.rgp_id = crg.id
1348 AND crg.rgd_code = 'LALEVL'
1349 AND crl.rule_information_category = 'LASLL'
1350 AND crg.dnz_chr_id = p_khr_id
1351 AND crg.cle_id = p_kle_id
1352 AND TRUNC(FND_DATE.canonical_to_date(crl.rule_information2)) > TRUNC(p_date)
1353 AND crl.rule_information2 IS NOT NULL
1354 AND crl.rule_information6 IS NOT NULL
1355 ORDER BY FND_DATE.canonical_to_date(crl.rule_information2);
1356
1357 l_stub_id NUMBER;
1358
1359 TYPE loan_rec IS RECORD (se_amount NUMBER,
1360 se_date DATE,
1361 se_days NUMBER,
1362 se_arrears VARCHAR2(1),
1363 se_stub VARCHAR2(1),
1364 se_purpose VARCHAR2(256)
1365 ,cf_purpose VARCHAR2(10)
1366 );
1367
1368 TYPE loan_tbl IS TABLE OF loan_rec INDEX BY BINARY_INTEGER;
1369
1370 asset_rents loan_tbl;
1371 loan_payment loan_tbl;
1372 pricipal_payment loan_tbl;
1373 interest_payment loan_tbl;
1374 pre_tax_income loan_tbl;
1375 termination_val loan_tbl;
1376
1377 l_iir_limit NUMBER := NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IIR_LIMIT')), 1000)/100;
1378
1379 l_start_date DATE;
1380 l_sll_start_date DATE;
1381 l_end_date DATE;
1382 l_interim_days NUMBER;
1383 l_interim_interest NUMBER;
1384 l_open_book NUMBER;
1385 l_close_book NUMBER;
1386 l_payment NUMBER;
1387 l_interest NUMBER;
1388 l_principal NUMBER;
1389 l_se_date DATE;
1390 l_termination_val NUMBER;
1391 l_days NUMBER;
1392 l_iir NUMBER := nvl(p_asset_iir_guess, 0);
1393 l_bk_yield NUMBER := nvl(p_bkg_yield_guess, 0);
1394
1395 --vthiruva..Fix for bug# 4060958
1396 --added NVL check on p_residual_value and using the local variable in the
1397 --calculations to prevent errors due to null being passed in p_residual_value
1398 l_residual_value NUMBER := nvl(p_residual_value, 0);
1399 l_rent_period_end DATE;
1400 l_k_end_date DATE := (ADD_MONTHS(p_start_date, p_term_duration) - 1);
1401 l_total_periods NUMBER := 0;
1402 l_term_complete VARCHAR2(1) := 'N';
1403
1404 l_increment NUMBER := 0.1;
1405 l_abs_incr NUMBER;
1406 l_prev_incr_sign NUMBER;
1407 l_crossed_zero VARCHAR2(1) := 'N';
1408
1409 l_diff NUMBER;
1410 l_prev_diff NUMBER;
1411 l_prev_diff_sign NUMBER;
1412
1413 i BINARY_INTEGER := 0;
1414 j BINARY_INTEGER := 0;
1415 l BINARY_INTEGER := 0;
1416 k BINARY_INTEGER := 0;
1417 m BINARY_INTEGER := 0;
1418
1419 lx_return_status VARCHAR2(1);
1420
1421 Cursor fee_type_csr IS
1422 Select 'Y' What
1423 from dual where Exists(
1424 SELECT nvl(kle.fee_type, 'XYZ'),
1425 nvl(lse.lty_code, 'XYZ')
1426 FROM okc_k_lines_b cle,
1427 okl_k_lines kle,
1428 okc_line_styles_b lse
1429 WHERE cle.dnz_chr_id = p_khr_id
1430 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
1431 AND cle.lse_id = lse.id
1432 AND (kle.fee_type = 'FINANCED' OR kle.fee_type = 'ROLLOVER' OR lse.lty_code = 'LINK_FEE_ASSET')
1433 AND cle.id = kle.id
1434 AND cle.id = p_kle_id);
1435
1436
1437 fee_type_rec fee_type_csr%ROWTYPe;
1438
1439
1440 l_stream_name VARCHAR2(256);
1441 l_sty_id NUMBER;
1442
1443 cursor fee_strm_type_csr is
1444 SELECT styt.name
1445 FROM okc_rules_b sll,
1446 okc_rules_b slh,
1447 okc_rule_groups_b rgp,
1448 okl_strm_type_b sty,
1449 okl_strm_type_tl styt
1450 WHERE rgp.dnz_chr_id = p_khr_id
1451 AND rgp.cle_id = p_kle_id
1452 AND rgp.rgd_code= 'LALEVL'
1453 AND rgp.id = slh.rgp_id
1454 AND slh.rule_information_category = 'LASLH'
1455 AND TO_NUMBER(slh.object1_id1) = sty.id
1456 AND sty.version = '1.0'
1457 AND sty.id = styt.id
1458 AND STYT.LANGUAGE = USERENV('LANG') -- Bug 4626837
1459 AND TO_CHAR(slh.id) = sll.object2_id1
1460 AND sll.rule_information_category = 'LASLL'
1461 ORDER BY fnd_date.canonical_to_date(sll.rule_information2);
1462
1463 CURSOR l_terminated_line_csr is
1464 SELECT kle.ID,
1465 sts.STE_CODE,
1466 trunc(nvl(kle.DATE_TERMINATED, sysdate)) date_terminated
1467 FROM okl_k_lines_full_v kle,
1468 okc_statuses_b sts
1469 WHERE kle.id = p_kle_id
1470 and kle.dnz_chr_id = p_khr_id
1471 and sts.code = kle.sts_code
1472 and sts.ste_code not in ('HOLD', 'EXPIRED', 'CANCELLED');
1473
1474 l_terminated_line_rec l_terminated_line_csr%ROWTYPE;
1475
1476 l_was_a_stub_payment VARCHAR2(1) := 'N';
1477
1478 -- Added by RGOOTY
1479 l_prev_iir NUMBER := 0;
1480 l_positive_diff_iir NUMBER := 0;
1481 l_negative_diff_iir NUMBER := 0;
1482 l_positive_diff NUMBER := 0;
1483 l_negative_diff NUMBER := 0;
1484
1485 l_prev_bk_yeild NUMBER := 0;
1486 l_positive_diff_bk_yeild NUMBER := 0;
1487 l_negative_diff_bk_yeild NUMBER := 0;
1488 l_day_convention_month VARCHAR2(30);
1489 l_day_convention_year VARCHAR2(30);
1490 l_days_in_year NUMBER;
1491
1492 -- Start : djanaswa : Bug 6274342
1493 l_arrears_pay_dates_option okl_st_gen_tmpt_sets_all.isg_arrears_pay_dates_option%type;
1494 -- End : djanaswa : Bug 6274342
1495 -- Start: Modifications done for the Prospective Rebooking Enhancement
1496 l_api_version CONSTANT NUMBER DEFAULT 1.0;
1497 l_api_name CONSTANT VARCHAR2(30) DEFAULT 'get_loan_amortization';
1498 l_day_count_method VARCHAR2(30);
1499 x_msg_count NUMBER;
1500 x_msg_data VARCHAR2(4000);
1501 lx_pricing_parameter_rec okl_pricing_utils_pvt.pricing_parameter_rec_type;
1502 l_cf_inflows okl_pricing_utils_pvt.cash_inflows_tbl_type;
1503 l_residuals okl_pricing_utils_pvt.cash_inflows_tbl_type;
1504 l_termination_tbl okl_pricing_utils_pvt.cash_inflows_tbl_type;
1505 l_pre_tax_inc_tbl okl_pricing_utils_pvt.cash_inflows_tbl_type;
1506 -- End: Modifications done for the Prospective Rebooking Enhancement
1507
1508 -- Variables declared for Prospective Rebooking
1509 -- Cursor to get the Original Contract Id and Line Id Details
1510 CURSOR get_orig_khr_dtls_csr (
1511 p_kle_id IN NUMBER )
1512 IS
1513 SELECT cle.orig_system_id1 orig_kle_id
1514 ,chr.orig_system_id1 orig_khr_id
1515 FROM okc_k_lines_b cle
1516 ,okc_k_headers_b chr
1517 WHERE cle.id = p_kle_id
1518 AND cle.dnz_chr_id = chr.id
1519 AND cle.orig_system_id1 IS NOT NULL;
1520
1521 CURSOR get_sub_pre_tax_yield_csr( p_kle_id NUMBER)
1522 IS
1523 SELECT ( sub_pre_tax_yield / 100 ) sub_pre_tax_yield
1524 FROM okl_k_lines kle
1525 WHERE kle.id = p_kle_id;
1526 -- Cursor to fetch the Stream Elements for a given Contract, Line, Stream and Purpose
1527 CURSOR get_strms_csr (
1528 p_khr_id IN NUMBER
1529 ,p_kle_id IN NUMBER
1530 ,p_sty_id IN NUMBER
1531 ,p_purpose_code IN VARCHAR2
1532 )
1533 IS
1534 SELECT sel.id se_id,
1535 sel.amount se_amount,
1536 sel.stream_element_date se_date,
1537 sel.comments se_arrears,
1538 sel.sel_id se_sel_id
1539 FROM okl_strm_elements sel,
1540 okl_streams stm
1541 WHERE stm.kle_id = p_kle_id
1542 AND stm.khr_id = p_khr_id
1543 AND stm.sty_id = p_sty_id
1544 AND DECODE(stm.purpose_code,
1545 NULL, '-99',
1546 'REPORT'
1547 ) = p_purpose_code
1548 AND stm.say_code = 'CURR'
1549 AND stm.id = sel.stm_id
1550 ORDER BY sel.stream_element_date;
1551
1552 -- Additional Variables added during Prospective Rebooking Enhancement
1553 l_prosp_rebook_flag VARCHAR2(30);
1554 l_rebook_date DATE;
1555 l_last_accrued_date DATE;
1556 l_orig_khr_id NUMBER;
1557 l_orig_kle_id NUMBER;
1558 cf_index NUMBER;
1559 l_flip_prb_rbk_reason VARCHAR2(100);
1560 l_orig_income_streams okl_pricing_utils_pvt.cash_inflows_tbl_type;
1561 l_rebook_type VARCHAR2(100);
1562 -- Bug 10207847
1563 slope NUMBER := 1;
1564
1565 BEGIN
1566 IF (G_DEBUG_ENABLED = 'Y') THEN
1567 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
1568 END IF;
1569
1570 -- print( l_prog_name, 'begin' );
1571
1572 OPEN l_terminated_line_csr;
1573 FETCH l_terminated_line_csr INTO l_terminated_line_rec;
1574 CLOSE l_terminated_line_csr;
1575 If ( l_terminated_line_rec.ste_code = 'TERMINATED') Then
1576 l_k_end_date := LAST_DAY(l_terminated_line_rec.date_terminated);
1577 End if;
1578
1579 --Added by prasjain for bug 5474827
1580 /*
1581 OPEN c_stub;
1582 FETCH c_stub INTO l_stub_id;
1583 CLOSE c_stub;
1584 */
1585 l_stub_id := p_se_id;
1586 --end prasjain
1587
1588
1589 OPEN fee_type_csr;
1590 FETCH fee_type_csr INTO fee_type_rec;
1591 CLOSE fee_type_csr;
1592
1593 -- Fetch the day convention ..
1594 OKL_PRICING_UTILS_PVT.get_day_convention(
1595 p_id => p_khr_id,
1596 p_source => 'ISG',
1597 x_days_in_month => l_day_convention_month,
1598 x_days_in_year => l_day_convention_year,
1599 x_return_status => lx_return_status);
1600 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
1601 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
1602 END IF;
1603 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
1604 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1605 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
1606 RAISE OKL_API.G_EXCEPTION_ERROR;
1607 END IF;
1608
1609 If nvl(fee_type_rec.What, 'N') = 'Y' Then
1610
1611 OPEN fee_strm_type_csr;
1612 FETCH fee_strm_type_csr INTO l_stream_name;
1613 CLOSE fee_strm_type_csr;
1614
1615 Else
1616 OKL_ISG_UTILS_PVT.get_primary_stream_type(
1617 p_khr_id => p_khr_id,
1618 p_deal_type => p_deal_type,
1619 p_primary_sty_purpose => 'RENT',
1620 x_return_status => x_return_status,
1621 x_primary_sty_id => l_sty_id,
1622 x_primary_sty_name => l_stream_name);
1623
1624 IF (x_return_status = G_RET_STS_UNEXP_ERROR) THEN
1625 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1626 ELSIF (x_return_status = G_RET_STS_ERROR) THEN
1627 RAISE OKL_API.G_EXCEPTION_ERROR;
1628 END IF;
1629 --l_stream_name := 'RENT';
1630 End If;
1631
1632 OPEN c_rent_slls( l_stream_name );
1633 FETCH c_rent_slls INTO l_rent_sll;
1634 CLOSE c_rent_slls;
1635
1636
1637 l_start_date := l_rent_sll.start_date;
1638
1639 -- Bug 6274342 DJANASWA begin
1640 IF l_rent_sll.arrears_yn = 'Y' THEN
1641 OKL_ISG_UTILS_PVT.get_arrears_pay_dates_option(
1642 p_khr_id => p_khr_id,
1643 x_arrears_pay_dates_option => l_arrears_pay_dates_option,
1644 x_return_status => lx_return_status);
1645
1646 IF(lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
1647 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1648 ELSIF (lx_return_status = OKL_API.G_RET_STS_ERROR) THEN
1649 RAISE OKL_API.G_EXCEPTION_ERROR;
1650 END IF;
1651 END IF;
1652 -- Bug 6274342 DJANASWA end
1653
1654
1655 -- print( l_prog_name, 'sll start date ' || l_start_date );
1656 FOR l_rent_flow IN c_rent_flows( l_stream_name ) LOOP
1657
1658 k := k + 1;
1659
1660 -- Bug 6274342 DJANASWA begin
1661 IF(l_rent_sll.arrears_yn = 'Y' AND l_arrears_pay_dates_option = 'FIRST_DAY_OF_NEXT_PERIOD') THEN
1662 l_rent_flow.se_date := l_rent_flow.se_date - 1;
1663 ELSE
1664 l_rent_flow.se_date := l_rent_flow.se_date;
1665 END IF;
1666 -- Bug 6274342 DJANASWA end
1667
1668
1669 -- print( l_prog_name, 'rent flow start date ' || l_rent_flow.se_date );
1670 asset_rents(k).se_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
1671 p_days_in_month => l_day_convention_month,
1672 p_days_in_year => l_day_convention_year,
1673 p_end_date => l_rent_flow.se_date,
1674 p_arrears => l_rent_flow.se_arrears,
1675 x_return_status => lx_return_status);
1676
1677 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
1678 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1679 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
1680 RAISE OKL_API.G_EXCEPTION_ERROR;
1681 END IF;
1682
1683 asset_rents(k).se_amount := l_rent_flow.se_amount;
1684 asset_rents(k).se_date := l_rent_flow.se_date;
1685 asset_rents(k).se_arrears := l_rent_flow.se_arrears;
1686
1687 if ( ( l_rent_flow.stream_type_purpose = 'UNSCHEDULED_PRINCIPAL_PAYMENT') OR
1688 ( l_rent_flow.stream_type_purpose = 'DOWN_PAYMENT') OR
1689 ( l_rent_flow.stream_type_purpose = 'PRINCIPAL_PAYMENT') ) Then
1690 asset_rents(k).se_purpose := 'P';
1691 Elsif ( l_rent_flow.stream_type_purpose = 'UNSCHEDULED_INTEREST_PAYMENT') Then
1692 asset_rents(k).se_purpose := 'I';
1693 Else
1694 asset_rents(k).se_purpose := 'B';
1695 end if;
1696 asset_rents(k).cf_purpose := l_rent_flow.cf_purpose;
1697 l_start_date := l_rent_flow.se_date;
1698
1699 IF l_rent_flow.se_arrears = 'Y' THEN
1700 l_start_date := l_start_date + 1;
1701 END IF;
1702
1703 If ( nvl(l_rent_flow.se_sel_id, -1) = l_stub_id ) Then
1704 asset_rents(k).se_stub := 'Y';
1705 End If;
1706
1707 END LOOP;
1708
1709 l_interim_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_asset_start_date,
1710 p_days_in_month => l_day_convention_month,
1711 p_days_in_year => l_day_convention_year,
1712 p_end_date => l_rent_sll.start_date,
1713 p_arrears => 'N',
1714 x_return_status => lx_return_status);
1715
1716 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
1717 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1718 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
1719 RAISE OKL_API.G_EXCEPTION_ERROR;
1720 END IF;
1721
1722 -- print( l_prog_name, ' asset rent count ' || to_char(asset_rents.COUNT));
1723 -- Bug 10207847: Start
1724 print( l_prog_name, 'p_investment=' || p_investment );
1725 print( l_prog_name, 'i | l_diff | l_prev_diff | l_positive_diff | l_negative_diff | l_positive_diff_iir | l_negative_idff_iir | l_crossed_zero | l_abs_incr | l_iir | l_prev_iir | l_prev_incr_sign | l_prev_diff_sign');
1726 slope := 1;
1727 -- Bug 10207847: End
1728 LOOP
1729
1730 i := i + 1;
1731
1732 l_interim_interest := p_investment * l_interim_days * l_iir/360;
1733
1734 -- print( l_prog_name, i||' Implicit Rate '||l_iir||' Interim Interest '||l_interim_interest
1735 -- ||' Interim Days = '||l_interim_days);
1736
1737 l_open_book := p_investment;
1738 -- print( l_prog_name, ' Investment ' || to_char(l_open_book));
1739
1740 FOR k IN 1..asset_rents.COUNT LOOP
1741 l_payment := asset_rents(k).se_amount;
1742
1743 If ( asset_rents(k).se_purpose = 'B' ) then
1744 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
1745 l_principal := l_payment - l_interest;
1746 elsIf ( asset_rents(k).se_purpose = 'P' ) then
1747 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
1748 l_principal := l_payment;
1749 elsIf ( asset_rents(k).se_purpose = 'I' ) then
1750 l_interest := l_payment;
1751 l_principal := 0;
1752 End if;
1753
1754 l_close_book := l_open_book - l_principal;
1755 l_open_book := l_close_book;
1756
1757 /* print( l_prog_name, ' '||TO_CHAR(asset_rents(k).se_date, 'DD-MON-YYYY')||' DAYS '||asset_rents(k).se_DAYS
1758 || ' LOAN PAYMENT '||l_payment|| ' INTEREST '||ROUND(l_interest, 3)
1759 || ' PRINCIPAL '||ROUND(l_principal, 3)||' Next OB '||ROUND(l_open_book, 3));
1760 */
1761 END LOOP;
1762
1763 -- udhenuko Bug 5046430 Fix -start for get_loan_amortization
1764 -- terminal value of the asset considered in the calculation of IIR
1765 l_payment := l_residual_value;
1766 l_days := OKL_PRICING_UTILS_PVT.get_day_count(
1767 p_start_date => asset_rents(asset_rents.LAST).se_date,
1768 p_days_in_month => l_day_convention_month,
1769 p_days_in_year => l_day_convention_year,
1770 p_end_date => l_k_end_date,
1771 p_arrears => 'Y',
1772 x_return_status => lx_return_status);
1773 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
1774 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
1775 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
1776 RAISE OKL_API.G_EXCEPTION_ERROR;
1777 END IF;
1778 l_interest := l_open_book*l_days*l_iir/360;
1779 l_principal := l_payment - l_interest;
1780 l_close_book := l_open_book - l_principal;
1781 l_open_book := l_close_book;
1782 -- udhenuko Bug 5046430 Fix -end for get_loan_amortization
1783
1784 l_diff := l_open_book;
1785
1786 IF ROUND(l_diff, 4) = 0 THEN
1787 l_open_book := p_investment;
1788 j := 0;
1789 FOR k IN asset_rents.FIRST .. asset_rents.LAST LOOP
1790 l_payment := asset_rents(k).se_amount;
1791
1792 If ( asset_rents(k).se_purpose = 'B' ) then
1793 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
1794 l_principal := l_payment - l_interest;
1795 elsIf ( asset_rents(k).se_purpose = 'P' ) then
1796 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
1797 l_principal := l_payment;
1798 elsIf ( asset_rents(k).se_purpose = 'I' ) then
1799 l_interest := l_payment;
1800 l_principal := 0;
1801 End if;
1802
1803 --l_principal := l_payment - l_interest;
1804 l_close_book := l_open_book - l_principal;
1805 l_se_date := asset_rents(k).se_date;
1806 If asset_rents(k).se_purpose = 'B' Then
1807 j := j + 1;
1808 x_principal_tbl(j).amount := l_principal;
1809 x_interest_tbl(j).amount := l_interest;
1810 x_prin_bal_tbl(j).amount := l_close_book;
1811 x_principal_tbl(j).se_line_number := j;
1812 x_interest_tbl(j).se_line_number := j;
1813 x_prin_bal_tbl(j).se_line_number := j;
1814 x_principal_tbl(j).stream_element_date := l_se_date;
1815 x_interest_tbl(j).stream_element_date := l_se_date;
1816 x_prin_bal_tbl(j).stream_element_date := l_se_date;
1817 End If;
1818 l_open_book := l_close_book;
1819 -- print( l_prog_name, asset_rents(k).se_days || ':' || l_close_book || ':' || l_interest || ':' || l_principal || ':' || l_se_date );
1820 END LOOP;
1821
1822 IF l_interim_interest > 0 THEN
1823 IF l_rent_sll.arrears_yn = 'Y' THEN
1824 x_principal_tbl(asset_rents.FIRST-1).amount := 0;
1825 x_interest_tbl(asset_rents.FIRST-1).amount := l_interim_interest;
1826 x_prin_bal_tbl(asset_rents.FIRST-1).amount := p_investment;
1827
1828 x_principal_tbl(asset_rents.FIRST-1).se_line_number := 0;
1829 x_interest_tbl(asset_rents.FIRST-1).se_line_number := 0;
1830 x_prin_bal_tbl(asset_rents.FIRST-1).se_line_number := 0;
1831
1832 x_principal_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
1833 x_interest_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
1834 x_prin_bal_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
1835 ELSE
1836 x_interest_tbl(asset_rents.FIRST).amount := l_interim_interest;
1837 END IF;
1838 END IF;
1839 x_interim_interest := l_interim_interest;
1840 x_interim_days := l_interim_days;
1841 x_interim_dpp := l_rent_sll.dpp;
1842 x_iir := l_iir;
1843 EXIT;
1844 END IF;
1845
1846 IF i > 1 AND SIGN(l_diff) <> SIGN(l_prev_diff) AND l_crossed_zero = 'N' THEN
1847 l_crossed_zero := 'Y';
1848
1849 -- Added by RGOOTY
1850 IF ( sign( l_diff) = 1 ) then
1851 l_positive_diff := l_diff;
1852 l_negative_diff := l_prev_diff;
1853 l_positive_diff_iir := l_iir;
1854 l_negative_diff_iir := l_prev_iir;
1855 ELSE
1856 l_positive_diff := l_prev_diff;
1857 l_negative_diff := l_diff;
1858 l_positive_diff_iir := l_prev_iir;
1859 l_negative_diff_iir := l_iir;
1860 END IF;
1861
1862 END IF;
1863
1864
1865 IF( sign(l_diff) = 1) THEN
1866 l_positive_diff := l_diff;
1867 l_positive_diff_iir := l_iir;
1868 ELSE
1869 l_negative_diff := l_diff;
1870 l_negative_diff_iir := l_iir;
1871 END IF;
1872
1873
1874 IF l_crossed_zero = 'Y' THEN
1875 -- Added by RGOOTY
1876 -- Means First time we have got two opposite signed
1877 IF i > 1 then
1878 l_abs_incr := abs(( l_positive_diff_iir - l_negative_diff_iir ) /
1879 ( l_positive_diff - l_negative_diff ) * l_diff);
1880 ELSE
1881 l_abs_incr := ABS(l_increment) / 2;
1882 END IF;
1883
1884 ELSE
1885 l_abs_incr := ABS(l_increment);
1886 END IF;
1887
1888 -- Bug 10207847: Start
1889 IF i = 2 THEN
1890 -- Check the curve behavior
1891 IF SIGN(l_prev_diff) = SIGN(l_diff) AND
1892 SIGN(l_prev_diff) = -1 AND
1893 l_prev_diff > l_diff -- Curve is still going down on incrementing the rate
1894 THEN
1895 -- Need to have the swap Logic
1896 -- In effect, if you want to take the l_diff near to zero, you have to decrease the l_iir
1897 -- this is against the standard assumption
1898 slope := -1;
1899 END IF;
1900 END IF;
1901 -- Bug 10207847: End
1902
1903 IF i > 1 THEN
1904 IF SIGN(l_diff) <> l_prev_diff_sign THEN
1905 IF l_prev_incr_sign = 1 THEN
1906 l_increment := - l_abs_incr;
1907 ELSE
1908 l_increment := l_abs_incr;
1909 END IF;
1910 /* start bug 14761040 */
1911 /* if the amounts are moving towards infinity +/-, reverse the sign of increment. */
1912 ELSIF ( ( l_diff > l_prev_diff and sign(l_diff) = 1 ) OR
1913 ( l_prev_diff > l_diff and sign(l_diff) = -1 )
1914 ) then
1915 IF l_prev_incr_sign = 1 then
1916 l_increment := -1 * l_abs_incr;
1917 slope := -1;
1918 ELSE
1919 l_increment := l_abs_incr;
1920 slope := 1;
1921 END IF;
1922 /* end bug 14761040 */
1923 ELSE
1924 l_increment := l_abs_incr * slope; -- Bug 10207847
1925 /*
1926 IF l_prev_incr_sign = 1 THEN
1927 l_increment := l_abs_incr;
1928 ELSE
1929 l_increment := - l_abs_incr;
1930 END IF;
1931 */
1932 END IF;
1933 ELSE
1934 IF SIGN(l_diff) = 1 THEN
1935 l_increment := -l_increment;
1936 ELSE
1937 l_increment := l_increment;
1938 END IF;
1939 END IF;
1940
1941
1942 -- Added by RGOOTY: Start
1943 l_prev_iir := l_iir;
1944
1945 l_iir := l_iir + l_increment;
1946
1947 print( l_prog_name,
1948 i || ' | ' || l_diff || '|' || l_prev_diff || '|' || l_positive_diff || '|' || l_negative_diff || '|' ||
1949 l_positive_diff_iir || '|' || l_negative_diff_iir || '|' || l_crossed_zero || '|' ||
1950 l_abs_incr || '|' || l_iir || '|' || l_prev_iir || '|' || l_prev_incr_sign || ' | ' || l_prev_diff_sign
1951 );
1952
1953 IF ABS(l_iir) > l_iir_limit OR
1954 i > 1000
1955 THEN
1956
1957 -- print( l_prog_name, ' irr ' || ABS(l_iir) );
1958 -- print( l_prog_name, ' irr limit ' || l_iir_limit );
1959
1960 If k = 1 then
1961 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
1962 p_msg_name => 'OKL_CANNOT_CALC_IIR');
1963 Else
1964 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
1965 p_msg_name => 'OKL_IIR_CALC_IIR_LIMIT',
1966 p_token1 => 'IIR_LIMIT',
1967 p_token1_value => l_iir_limit*100);
1968 End If;
1969 RAISE OKL_API.G_EXCEPTION_ERROR;
1970 END IF;
1971
1972 l_prev_incr_sign := SIGN(l_increment);
1973 l_prev_diff_sign := SIGN(l_diff);
1974 l_prev_diff := l_diff;
1975 END LOOP;
1976 -- print( l_prog_name, ' done with iir ' );
1977 -- Prospective Rebooking Enhancement
1978 print( l_prog_name, '----------------------------------------------------------');
1979 print( l_prog_name, '!! BOOKING YIELD CALCULATION USING NEW SALES ORIG LOGIC !!' );
1980 print( l_prog_name, '----------------------------------------------------------');
1981 print( l_prog_name, '(Contract ID | Asset ID) = ('
1982 || p_khr_id || ' | ' || p_kle_id || ' ) ' );
1983 -- Modifications done as part of the Prospective Rebooking Enhancement
1984 -- Logic:
1985 -- Instead of calling the following peice of code, switching to call
1986 -- the okl_pricing_utils_pvt.compute_bk_yield API to calculate the
1987 -- Booking Yield as well as to return the Pre-Tax Income and Termination
1988 -- value streams.
1989 -- Step 1:
1990 -- Need to populate the following in the px_pricing_parameter_rec :
1991 -- 1. (a) Asset Financed Amount
1992 lx_pricing_parameter_rec.line_type := 'FREE_FORM1';
1993 lx_pricing_parameter_rec.line_start_date := l_rent_sll.start_date;
1994 lx_pricing_parameter_rec.line_end_date := l_k_end_date; -- passing the end date as an existing value
1995 -- Pass the p_investment in the financed amount column
1996 lx_pricing_parameter_rec.financed_amount := p_investment;
1997
1998 -- No Need to pass the following:
1999 -- lx_pricing_parameter_rec.payment_type := NULL;
2000 -- lx_pricing_parameter_rec.trade_in := NULL;
2001 -- lx_pricing_parameter_rec.down_payment := NULL;
2002 -- lx_pricing_parameter_rec.subsidy := NULL;
2003 -- 1. (b) Asset Payment Rent Stream element details:
2004 -- Amount, Date, is Arrears flag
2005 print( l_prog_name, ' Handling the Asset Rent Stream Elements' );
2006 IF asset_rents IS NOT NULL
2007 AND asset_rents.count > 0
2008 THEN
2009 print( l_prog_name, 'Rent Stream Elements Count=' || asset_rents.COUNT );
2010 print( l_prog_name, 'Date | Amount | Arrears ' );
2011 FOR i in asset_rents.FIRST .. asset_rents.LAST
2012 LOOP
2013 l_cf_inflows(i).cf_amount := asset_rents(i).se_amount;
2014 l_cf_inflows(i).cf_date := asset_rents(i).se_date;
2015 l_cf_inflows(i).is_arrears := asset_rents(i).se_arrears;
2016 l_cf_inflows(i).cf_purpose := asset_rents(i).cf_purpose;
2017 print( l_prog_name, l_cf_inflows(i).cf_amount || ' | ' ||
2018 l_cf_inflows(i).cf_date || ' | ' || l_cf_inflows(i).is_arrears
2019 || ' | ' || l_cf_inflows(i).cf_purpose );
2020 END LOOP;
2021 END IF;
2022 -- 1. (c) Asset Residual Values
2023 print( l_prog_name, 'Handling the Residual Value Stream ');
2024 IF p_residual_value IS NOT NULL
2025 THEN
2026 -- Just need to populate the Amount, nothing else needed
2027 l_residuals(1).cf_amount := p_residual_value;
2028 END IF;
2029 -- Populate the Cash Inflows and Residual Inflows to the Pricing Param Table
2030 lx_pricing_parameter_rec.cash_inflows := l_cf_inflows;
2031 lx_pricing_parameter_rec.residual_inflows := l_residuals;
2032 -- Step 2:
2033 -- Get the Day Convention Method, as we have days in year and days in month
2034 -- Validations here ..
2035 okl_pricing_utils_pvt.get_day_count_method(
2036 p_days_in_month => l_day_convention_month,
2037 p_days_in_year => l_day_convention_year,
2038 x_day_count_method => l_day_count_method,
2039 x_return_status => lx_return_status );
2040 print( l_prog_name, 'After get_days_in_year_and_month ' || lx_return_status);
2041 IF(lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2042 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2043 ELSIF (lx_return_status = OKL_API.G_RET_STS_ERROR) THEN
2044 RAISE OKL_API.G_EXCEPTION_ERROR;
2045 END IF;
2046
2047 -- Prospective Rebooking Enhancement
2048 print( l_prog_name, 'p_prosp_rebook_flag | p_during_rebook_yn' );
2049 print( l_prog_name, p_prosp_rebook_flag || ' | ' || p_during_rebook_yn);
2050 l_prosp_rebook_flag := 'N';
2051 IF p_during_rebook_yn = 'Y' AND
2052 p_prosp_rebook_flag = 'Y'
2053 THEN
2054 l_prosp_rebook_flag := 'Y';
2055 END IF;
2056 print( l_prog_name, 'Prospective Rebooking : ' || l_prosp_rebook_flag );
2057 IF l_prosp_rebook_flag = 'Y'
2058 THEN
2059 print( l_prog_name, '-------------------------------------------------------');
2060 print( l_prog_name, '!!! Using Prospective Rebooking for Booking Yield !!! ');
2061 print( l_prog_name, '-------------------------------------------------------');
2062 -- Start with No Reason for flipping from Prospective Rebooking Approach
2063 l_flip_prb_rbk_reason := 'NO_REASON';
2064 -- Derieve the Rebook Effective Date
2065 l_rebook_date := TRUNC(p_rebook_date);
2066 print( l_prog_name, 'Rebook Date = ' || l_rebook_date );
2067 IF l_rebook_date IS NULL
2068 THEN
2069 l_flip_prb_rbk_reason := 'NO_REBOOK_DATE';
2070 END IF;
2071 l_rebook_type := p_rebook_type;
2072 print( l_prog_name, 'Rebook Type = ' || l_rebook_type );
2073 IF l_rebook_type IS NULL
2074 THEN
2075 l_flip_prb_rbk_reason := 'NO_REBOOK_TYPE_MENTIONED';
2076 END IF;
2077 -- Calculate the Last Accrued Date
2078 l_last_accrued_date := TRUNC( LAST_DAY(ADD_MONTHS(p_rebook_date, -1) ) );
2079 print( l_prog_name,'Contract Start Date | Rebook Date | Last Accrued Date');
2080 print( l_prog_name, p_start_date || ' | ' || l_rebook_date|| ' | ' || l_last_accrued_date);
2081 IF TRUNC(p_start_date) = TRUNC(p_rebook_date)
2082 THEN
2083 l_flip_prb_rbk_reason := 'REBOOK_DATE_EQUALS_CONTRACT_START_DATE';
2084 ELSIF l_last_accrued_date < TRUNC(p_start_date)
2085 THEN
2086 -- In cases where the immediately preceding Lease/Interest Income
2087 -- stream element does not exist, the Rebook is retrospective.
2088 -- This applies to contract lines where the rebook effective date
2089 -- is before or on the first calendar month end.
2090 l_flip_prb_rbk_reason := 'LAST_ACCRUED_DATE_LESS_THAN_CONTRACT_START_DATE';
2091 END IF;
2092
2093 -- Step: Fetch the Original Contract and Configuration Line ID
2094 IF l_flip_prb_rbk_reason = 'NO_REASON'
2095 THEN
2096 -- Only in case of Online Rebook, we need to fetch the
2097 -- Streams using the Original contract and Line Id
2098 IF l_rebook_type = 'ONLINE_REBOOK'
2099 THEN
2100 print( l_prog_name, 'Fetching Original Line and Contract Id. Rebook Type' || l_rebook_type );
2101 l_flip_prb_rbk_reason := 'ORIG_KHR_KLE_ID_NOT_FOUND';
2102 FOR t_rec IN get_orig_khr_dtls_csr (
2103 p_kle_id => p_kle_id )
2104 LOOP
2105 l_orig_khr_id := t_rec.orig_khr_id;
2106 l_orig_kle_id := t_rec.orig_kle_id;
2107 l_flip_prb_rbk_reason := 'NO_REASON';
2108 END LOOP;
2109 ELSE
2110 -- Mass Rebook flows
2111 print( l_prog_name, 'Using current Line and Contract Id. Rebook Type' || l_rebook_type );
2112 l_orig_khr_id := p_khr_id;
2113 l_orig_kle_id := p_kle_id;
2114 END IF;
2115 print( l_prog_name, 'Original Contract Id | Original Line Id ' );
2116 print( l_prog_name, l_orig_khr_id || ' | ' || l_orig_kle_id );
2117 END IF; -- IF l_flip_prb_rbk_reason = 'NO_REASON'
2118
2119 -- Step: Fetch the Pre-Tax Income Streams before Revision
2120 IF l_flip_prb_rbk_reason = 'NO_REASON'
2121 THEN
2122 l_flip_prb_rbk_reason := 'ORIG_INCOME_STREAMS_NOT_FOUND';
2123 print( l_prog_name, 'Fetching the Income Stream Elements Before Revision ' );
2124 print( l_prog_name, 'p_khr_id | p_kle_id | p_income_strm_sty_id | p_purpose_code' );
2125 print( l_prog_name, p_khr_id || ' | ' || p_kle_id || ' | ' ||
2126 p_income_strm_sty_id || ' | ' || p_purpose_code );
2127 print( l_prog_name, ' # | Date | amount ' );
2128 cf_index := 1;
2129 FOR cf_rec IN get_strms_csr(
2130 p_khr_id => l_orig_khr_id
2131 ,p_kle_id => l_orig_kle_id
2132 ,p_sty_id => p_income_strm_sty_id
2133 ,p_purpose_code => p_purpose_code )
2134 LOOP
2135 l_flip_prb_rbk_reason := 'NO_REASON';
2136 l_orig_income_streams(cf_index).cf_amount := cf_rec.se_amount;
2137 l_orig_income_streams(cf_index).cf_date := cf_rec.se_date;
2138 print( l_prog_name, cf_index || ' | ' ||
2139 l_orig_income_streams(cf_index).cf_date || ' | ' ||
2140 l_orig_income_streams(cf_index).cf_amount
2141 );
2142 -- Increment the cf_index
2143 cf_index := cf_index + 1;
2144 END LOOP;
2145 END IF; -- IF l_flip_prb_rbk_reason = 'NO_REASON'
2146 -- Finally decide whether to continue in Prospective Rebooking or not
2147 IF l_flip_prb_rbk_reason <> 'NO_REASON'
2148 THEN
2149 print( l_prog_name, '!!! **** Unable to proceed using Prospective Rebooking Approach **** !!! ' );
2150 print( l_prog_name, '!!! **** Reason : ' || l_flip_prb_rbk_reason );
2151 l_prosp_rebook_flag := 'N'; -- Use Retrospective Booking Logic only
2152 END IF;
2153 END IF;
2154 print( l_prog_name, 'Before calling okl_pricing_utils_pvt.compute_bk_yield: ');
2155 print( l_prog_name, 'p_start_date = ' || l_rent_sll.start_date );
2156 print( l_prog_name, 'l_day_count_method = ' || l_day_count_method );
2157 print( l_prog_name, 'p_bkg_yield_guess = ' || p_bkg_yield_guess );
2158 print( l_prog_name, 'p_term_duration = ' || p_term_duration );
2159 print( l_prog_name, 'p_prosp_rebook_flag= ' || p_prosp_rebook_flag);
2160 print( l_prog_name, 'p_rebook_date = ' || l_rebook_date);
2161 print( l_prog_name, 'l_orig_income_streams.count= ' || l_orig_income_streams.count);
2162 -- Call the Pricing API to calculate the Booking Yield
2163 -- and generate the Income Streams
2164 okl_pricing_utils_pvt.compute_bk_yield(
2165 p_api_version => l_api_version
2166 ,p_init_msg_list => 'T'
2167 ,x_return_status => lx_return_status
2168 ,x_msg_count => x_msg_count
2169 ,x_msg_data => x_msg_data
2170 ,p_start_date => l_rent_sll.start_date
2171 ,p_day_count_method => l_day_count_method
2172 ,p_pricing_method => 'SY' -- For Lease Contracts always pass Solve for Yields
2173 ,p_initial_guess => p_bkg_yield_guess
2174 ,p_term => p_term_duration
2175 ,px_pricing_parameter_rec => lx_pricing_parameter_rec
2176 ,x_bk_yield => x_booking_yield
2177 ,x_termination_tbl => l_termination_tbl
2178 ,x_pre_tax_inc_tbl => l_pre_tax_inc_tbl
2179 -- Params added for Prospective Rebooking Enhancement
2180 ,p_prosp_rebook_flag => l_prosp_rebook_flag
2181 ,p_rebook_date => l_rebook_date
2182 ,p_orig_income_streams => l_orig_income_streams
2183 );
2184 print( l_prog_name, 'After okl_pricing_utils_pvt.compute_bk_yield: ' || lx_return_status);
2185 IF(lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2186 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2187 ELSIF (lx_return_status = OKL_API.G_RET_STS_ERROR) THEN
2188 RAISE OKL_API.G_EXCEPTION_ERROR;
2189 END IF;
2190 print( l_prog_name, 'Computed Booking Yield = ' || x_booking_yield );
2191 print( l_prog_name, 'Copying Termination Value Streams ' );
2192 -- Termination Value Streams: Copy from l_termination_tbl to x_termination_tbl
2193 IF l_termination_tbl IS NOT NULL
2194 AND l_termination_tbl.COUNT > 0
2195 THEN
2196 FOR i IN l_termination_tbl.FIRST .. l_termination_tbl.LAST
2197 LOOP
2198 x_termination_tbl(i).stream_element_date := l_termination_tbl(i).cf_date;
2199 x_termination_tbl(i).amount := l_termination_tbl(i).cf_amount;
2200 x_termination_tbl(i).se_line_number := l_termination_tbl(i).line_number;
2201 print( l_prog_name, x_termination_tbl(i).stream_element_date
2202 || ' | ' || x_termination_tbl(i).amount
2203 || ' | ' || x_termination_tbl(i).se_line_number );
2204 END LOOP;
2205 END IF;
2206 print( l_prog_name, 'Copying Pre-Tax Income Streams ' );
2207 -- Pre-Tax Income Streams : Copy from l_pre_tax_inc_tbl to x_pre_tax_inc_tbl
2208 IF l_pre_tax_inc_tbl IS NOT NULL
2209 AND l_pre_tax_inc_tbl.COUNT > 0
2210 THEN
2211 FOR i IN l_pre_tax_inc_tbl.FIRST .. l_pre_tax_inc_tbl.LAST
2212 LOOP
2213 x_pre_tax_inc_tbl(i).stream_element_date := l_pre_tax_inc_tbl(i).cf_date;
2214 x_pre_tax_inc_tbl(i).amount := l_pre_tax_inc_tbl(i).cf_amount;
2215 x_pre_tax_inc_tbl(i).se_line_number := l_pre_tax_inc_tbl(i).line_number;
2216 print( l_prog_name, x_pre_tax_inc_tbl(i).stream_element_date
2217 || ' | ' || x_pre_tax_inc_tbl(i).amount
2218 || ' | ' || x_pre_tax_inc_tbl(i).se_line_number );
2219 END LOOP;
2220 END IF;
2221
2222 x_return_status := lx_return_status;
2223 print( l_prog_name, 'get_loan_amortization: end' );
2224
2225 EXCEPTION
2226
2227 WHEN OKL_API.G_EXCEPTION_ERROR THEN
2228
2229 x_return_status := G_RET_STS_ERROR;
2230
2231 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
2232
2233 x_return_status := G_RET_STS_UNEXP_ERROR;
2234
2235 WHEN OTHERS THEN
2236
2237 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
2238 p_msg_name => G_DB_ERROR,
2239 p_token1 => G_PROG_NAME_TOKEN,
2240 p_token1_value => l_prog_name,
2241 p_token2 => G_SQLCODE_TOKEN,
2242 p_token2_value => sqlcode,
2243 p_token3 => G_SQLERRM_TOKEN,
2244 p_token3_value => sqlerrm);
2245
2246 x_return_status := G_RET_STS_UNEXP_ERROR;
2247
2248 END get_loan_amortization;
2249
2250
2251 ---------------------------------------------------------------------------
2252 -- Start of Commnets
2253 -- Badrinath Kuchibholta
2254 -- Procedure Name : comp_so_bk_yd
2255 -- Description : This Procedure will calculate booking yield if the
2256 -- there is a amount given
2257 -- Business Rules : We need to consider the asset costfor
2258 -- this calculation and also will calculated for
2259 -- given contract id and so_payment line
2260 -- Parameters : p_khr_id -- contract_id
2261 -- p_kle_id -- So_payment line id
2262 -- p_target -- only RATE
2263 -- Version : 1.0
2264 -- History : 15-SEP-2003 BAKUHCIB CREATED for Bug# *****
2265 -- End of Comments
2266 ---------------------------------------------------------------------------
2267 PROCEDURE comp_so_bk_yd(p_api_version IN NUMBER,
2268 p_init_msg_list IN VARCHAR2 DEFAULT OKL_API.G_FALSE,
2269 x_return_status OUT NOCOPY VARCHAR2,
2270 x_msg_count OUT NOCOPY NUMBER,
2271 x_msg_data OUT NOCOPY VARCHAR2,
2272 p_khr_id IN NUMBER,
2273 p_kle_id IN NUMBER,
2274 p_target IN VARCHAR2,
2275 p_subside_yn IN VARCHAR2 DEFAULT 'N',
2276 x_booking_yield OUT NOCOPY NUMBER) IS
2277 l_api_name CONSTANT VARCHAR2(30) := 'COMP_SO_BK_YD';
2278 l_start_date DATE := NULL;
2279 l_end_date DATE := NULL;
2280 l_se_date DATE := NULL;
2281 l_termination_val NUMBER := NULL;
2282 l_asset_cost NUMBER := NULL;
2283 l_residual_value NUMBER := NULL;
2284 l_days NUMBER := NULL;
2285 l_bk_yield NUMBER := 0;
2286 l_k_end_date DATE;
2287 l_term_complete VARCHAR2(1) := 'N';
2288 l_increment NUMBER := 0.1;
2289 l_abs_incr NUMBER := NULL;
2290 l_prev_incr_sign NUMBER := NULL;
2291 l_crossed_zero VARCHAR2(1) := 'N';
2292 l_diff NUMBER := NULL;
2293 l_prev_diff NUMBER := NULL;
2294 l_prev_diff_sign NUMBER := NULL;
2295 i NUMBER := 0;
2296 j NUMBER := 0;
2297 k NUMBER := 0;
2298 m NUMBER := 0;
2299 ld_res_start_date DATE;
2300 ld_asset_start_date DATE;
2301 l_subside_yn VARCHAR2(1) := NVL(p_subside_yn,'N');
2302
2303 Cursor khr_type_csr IS
2304 Select SCS_CODE,
2305 START_DATE
2306 From okc_K_headers_b chr
2307 Where chr.id = p_khr_id;
2308
2309 khr_type_rec khr_type_csr%ROWTYPE;
2310 l_line_type VARCHAR2(256);
2311
2312 -- We here get the start date of the first SLL though there are
2313 -- more than one sll and we look for amount not null
2314 CURSOR c_rent_slls(p_khr_id okc_k_headers_b.id%TYPE,
2315 p_Kle_id okc_k_lines_b.id%TYPE,
2316 p_line_type VARCHAR2)
2317 IS
2318 SELECT trunc(FND_DATE.canonical_to_date(rul_sll.rule_information2)) start_date,
2319 NVL(rul_sll.rule_information10, 'Y') arrears_yn,
2320 khr_so.term_duration
2321 FROM okc_k_headers_b chr_so,
2322 okl_k_headers khr_so,
2323 okc_line_styles_b lse_so,
2324 okc_k_lines_b cle_so,
2325 okc_rule_groups_b rgp_pay,
2326 okc_rules_b rul_slh,
2327 okc_rules_b rul_sll,
2328 okl_strm_type_b sty
2329 WHERE cle_so.id = p_Kle_id
2330 AND cle_so.dnz_chr_id = p_khr_id
2331 AND cle_so.lse_id = lse_so.id
2332 AND cle_so.dnz_chr_id = chr_so.id
2333 AND khr_so.id = chr_so.id
2334 AND cle_so.START_DATE = chr_so.START_DATE
2335 AND lse_so.lty_code = p_line_type --'SO_PAYMENT'
2336 AND rgp_pay.cle_id = cle_so.id
2337 AND rgp_pay.dnz_chr_id = cle_so.dnz_chr_id
2338 AND rgp_pay.rgd_code = 'LALEVL'
2339 AND rgp_pay.id = rul_slh.rgp_id
2340 AND rul_slh.rule_information_category = 'LASLH'
2341 AND TO_CHAR(rul_slh.id) = rul_sll.object2_id1
2342 AND rul_sll.rule_information_category = 'LASLL'
2343 AND TO_NUMBER(rul_slh.object1_id1) = sty.id
2344 AND sty.stream_type_purpose = 'RENT'
2345 ORDER BY rul_sll.rule_information2;
2346 -- Since the above SLL information are broken down into
2347 -- Stream we are good enough to consider first start date of the
2348 -- SLL
2349 CURSOR c_rent_flows(p_kle_id okc_k_lines_b.id%TYPE,
2350 p_khr_id okc_k_headers_b.id%TYPE,
2351 p_line_type VARCHAR2)
2352 IS
2353 SELECT sel_amt.id se_id,
2354 sel_amt.amount se_amount,
2355 trunc(sel_amt.stream_element_date) se_date,
2356 DECODE(sel_amt.sel_id,NULL,'N','Y') stub,
2357 sel_amt.comments se_arrears,
2358 sel_rate.comments payment_missing_yn
2359 FROM okl_streams stm,
2360 okl_strm_type_b sty,
2361 okl_strm_elements sel_amt,
2362 okl_strm_elements sel_rate,
2363 okc_k_headers_b chr_so,
2364 okc_k_lines_b cle,
2365 okc_line_styles_b lse
2366 WHERE stm.khr_id = p_khr_id
2367 AND stm.kle_id = p_kle_id
2368 AND stm.say_code = 'WORK'
2369 AND stm.purpose_code = 'FLOW'
2370 AND stm.sty_id = sty.id
2371 AND stm.id = sel_amt.stm_id
2372 AND stm.kle_id = cle.id
2373 AND cle.dnz_chr_id = chr_so.id
2374 AND cle.START_DATE = chr_so.START_DATE
2375 AND cle.lse_id = lse.id
2376 AND sel_rate.comments = 'N' -- bug# 3381706
2377 AND lse.lty_code = p_line_type --'SO_PAYMENT'
2378 AND sel_amt.id = sel_rate.sel_id
2379 ORDER BY sel_amt.stream_element_date;
2380
2381
2382 TYPE loan_rec IS RECORD (se_amount NUMBER,
2383 se_date DATE,
2384 se_days NUMBER,
2385 stub_yn VARCHAR2(3),
2386 se_arrears VARCHAR2(1));
2387
2388 TYPE loan_tbl IS TABLE OF loan_rec INDEX BY BINARY_INTEGER;
2389 asset_rents loan_tbl;
2390 l_rent_sll c_rent_slls%ROWTYPE;
2391
2392 l_day_convention_month VARCHAR2(30);
2393 l_day_convention_year VARCHAR2(30);
2394 l_days_in_year NUMBER;
2395
2396
2397 BEGIN
2398 IF (G_DEBUG_ENABLED = 'Y') THEN
2399 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
2400 END IF;
2401 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2402 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' begin');
2403 END IF;
2404 x_return_status := OKL_API.G_RET_STS_SUCCESS;
2405 -- Call start_activity to create savepoint, check compatibility
2406 -- and initialize message list
2407 x_return_status := OKL_API.START_ACTIVITY (
2408 l_api_name
2409 ,p_init_msg_list
2410 ,'_PVT'
2411 ,x_return_status);
2412 -- Check if activity started successfully
2413 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
2414 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2415 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
2416 RAISE OKL_API.G_EXCEPTION_ERROR;
2417 END IF;
2418 IF p_target <> 'PMNT' THEN
2419 OKL_API.set_message(p_app_name => G_APP_NAME,
2420 p_msg_name => G_INVALID_VALUE,
2421 p_token1 => G_COL_NAME_TOKEN,
2422 p_token1_value => 'Target');
2423 RAISE OKL_API.G_EXCEPTION_ERROR;
2424 END IF;
2425
2426 OPEN khr_type_csr;
2427 FETCH khr_type_csr INTO khr_type_rec;
2428 CLOSE khr_type_csr;
2429
2430 IF (INSTR( khr_type_rec.scs_code, 'LEASE') > 0) THEN
2431 l_line_type := 'FREE_FORM1';
2432 Else
2433 l_line_type := 'SO_PAYMENT';
2434 End If;
2435
2436 -- Fetch the day convention ..
2437 OKL_PRICING_UTILS_PVT.get_day_convention(
2438 p_id => p_khr_id,
2439 p_source => 'ISG',
2440 x_days_in_month => l_day_convention_month,
2441 x_days_in_year => l_day_convention_year,
2442 x_return_status => x_return_status);
2443 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2444 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, 'comp_so_bk_yd Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
2445 END IF;
2446 IF (x_return_status = G_RET_STS_UNEXP_ERROR) THEN
2447 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2448 ELSIF (x_return_status = G_RET_STS_ERROR) THEN
2449 RAISE OKL_API.G_EXCEPTION_ERROR;
2450 END IF;
2451
2452 -- We are now calucuating Booking Yields
2453 -- Get the SLL payment info for a kle_id and khr_id
2454 -- We here get the start date of the first SLL though there are
2455 -- more than one sll and we look for amount not null
2456 OPEN c_rent_slls(p_khr_id => p_khr_id,
2457 p_kle_id => p_kle_id,
2458 p_line_type => l_line_type);
2459 FETCH c_rent_slls INTO l_rent_sll;
2460 IF c_rent_slls%NOTFOUND THEN
2461 OKL_API.set_message(p_app_name => G_APP_NAME,
2462 p_msg_name => G_INVALID_VALUE,
2463 p_token1 => G_COL_NAME_TOKEN,
2464 p_token1_value => 'khr_id/kle_id');
2465 RAISE OKL_API.G_EXCEPTION_ERROR;
2466 END IF;
2467 CLOSE c_rent_slls;
2468 l_start_date := l_rent_sll.START_DATE;
2469
2470 -- Get the stream information for the kle_id and purpose code
2471 -- So that we build the Asset_rents PL/SQL table.
2472 -- we can assume the rent flows is expanded picture of SLL payments
2473 -- Since the above SLL information are broken down into
2474 -- Stream we are good enough to consider first start date of the
2475 -- SLL
2476 FOR l_rent_flow IN c_rent_flows(p_khr_id => p_khr_id,
2477 p_kle_id => p_kle_id,
2478 p_line_type => l_line_type) LOOP
2479 k := k + 1;
2480 asset_rents(k).se_days := OKL_PRICING_UTILS_PVT.get_day_count(
2481 p_start_date => l_start_date,
2482 p_days_in_month => l_day_convention_month,
2483 p_days_in_year => l_day_convention_year,
2484 p_end_date => l_rent_flow.se_date,
2485 p_arrears => l_rent_flow.se_arrears,
2486 x_return_status => x_return_status);
2487 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2488 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
2489 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2490 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_ERROR);
2491 END IF;
2492 asset_rents(k).se_amount := l_rent_flow.se_amount;
2493 asset_rents(k).se_date := l_rent_flow.se_date;
2494 asset_rents(k).se_arrears := l_rent_flow.se_arrears;
2495 asset_rents(k).stub_yn := l_rent_flow.stub;
2496 l_start_date := l_rent_flow.se_date;
2497 IF l_rent_flow.se_arrears = 'Y' THEN
2498 l_start_date := l_start_date + 1;
2499 END IF;
2500 END LOOP;
2501 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2502 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2503 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2504 RAISE OKL_API.G_EXCEPTION_ERROR;
2505 END IF;
2506 -- Getting the asset cost
2507 OKL_LA_STREAM_PVT.get_so_asset_oec(
2508 p_khr_id => p_khr_id,
2509 p_kle_id => p_kle_id,
2510 p_subside_yn => l_subside_yn,
2511 x_return_status => x_return_status,
2512 x_asset_oec => l_asset_cost,
2513 x_start_date => ld_asset_start_date);
2514 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2515 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2516 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2517 RAISE OKL_API.G_EXCEPTION_ERROR;
2518 END IF;
2519 -- Getting the Residual value
2520 OKL_LA_STREAM_PVT.get_so_residual_value(
2521 p_khr_id => p_khr_id,
2522 p_kle_id => p_kle_id,
2523 p_subside_yn => l_subside_yn,
2524 x_return_status => x_return_status,
2525 x_residual_value => l_residual_value,
2526 x_start_date => ld_res_start_date);
2527 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2528 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2529 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2530 RAISE OKL_API.G_EXCEPTION_ERROR;
2531 END IF;
2532 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2533 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' cost ' || l_asset_cost || ' residual value ' || l_residual_value);
2534 END IF;
2535 l_k_end_date := (ADD_MONTHS(ld_asset_start_date, l_rent_sll.term_duration) - 1);
2536 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2537 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' # of payments '||TO_CHAR(asset_rents.COUNT));
2538 END IF;
2539 LOOP
2540 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2541 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' interation # '||TO_CHAR(i));
2542 END IF;
2543 i := i + 1;
2544 k := 1;
2545 j := 0;
2546 m := 0;
2547 l_start_date := l_rent_sll.START_DATE;
2548 l_term_complete := 'N';
2549 l_termination_val := l_asset_cost;
2550 LOOP
2551 j := j + 1;
2552 l_se_date := trunc(asset_rents(k).se_date);
2553 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2554 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'l_se_date '||TO_CHAR(l_se_date));
2555 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'l_start_date '||TO_CHAR(l_start_date));
2556 END IF;
2557 IF LAST_DAY(l_se_date) <> LAST_DAY(l_start_date) THEN
2558 l_end_date := LAST_DAY(l_start_date);
2559 l_days := OKL_PRICING_UTILS_PVT.get_day_count(
2560 p_start_date => l_start_date,
2561 p_days_in_month => l_day_convention_month,
2562 p_days_in_year => l_day_convention_year,
2563 p_end_date => l_end_date,
2564 p_arrears => 'Y',
2565 x_return_status => x_return_status);
2566 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2567 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' Status 5 '||x_return_status);
2568 END IF;
2569 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2570 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
2571 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2572 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_ERROR);
2573 END IF;
2574 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
2575 l_se_date := LAST_DAY(l_start_date);
2576 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
2577 l_se_date := l_se_date - 1;
2578 END IF;
2579 ELSE
2580 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2581 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' Status 6 '||x_return_status);
2582 END IF;
2583 l_end_date := l_se_date;
2584 l_days := OKL_PRICING_UTILS_PVT.get_day_count(
2585 p_start_date => l_start_date,
2586 p_days_in_month => l_day_convention_month,
2587 p_days_in_year => l_day_convention_year,
2588 p_end_date => l_end_date,
2589 p_arrears => l_rent_sll.arrears_yn,
2590 x_return_status => x_return_status);
2591 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2592 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
2593 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2594 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_ERROR);
2595 END IF;
2596 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2597 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' Status 7 '||x_return_status);
2598 END IF;
2599 --IF j = 1 THEN
2600 -- l_days := 0;
2601 --END IF;
2602 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
2603 l_termination_val := l_termination_val - asset_rents(k).se_amount;
2604 IF k = asset_rents.LAST THEN
2605 l_start_date := l_se_date;
2606 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2607 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_start_date::l_k_end_date '||l_start_date||'::'||l_k_end_date);
2608 END IF;
2609 LOOP
2610 m := m + 1;
2611 IF trunc(LAST_DAY(l_start_date)) <> trunc(LAST_DAY(l_k_end_date)) THEN
2612 l_end_date := LAST_DAY(l_start_date);
2613 ELSE
2614 l_end_date := l_k_end_date;
2615 END IF;
2616 l_days := OKL_PRICING_UTILS_PVT.get_day_count(
2617 p_start_date => l_start_date,
2618 p_days_in_month => l_day_convention_month,
2619 p_days_in_year => l_day_convention_year,
2620 p_end_date => l_end_date,
2621 p_arrears => 'Y',
2622 x_return_status => x_return_status);
2623 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2624 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' # of days '||to_char(l_days));
2625 END IF;
2626 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2627 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
2628 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2629 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_ERROR);
2630 END IF;
2631 IF (l_rent_sll.arrears_yn = 'Y') AND (m = 1) THEN
2632 l_days := l_days - 1;
2633 END IF;
2634 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
2635 --l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
2636 IF trunc(l_end_date) = trunc(l_k_end_date) THEN
2637 l_termination_val := l_termination_val - l_residual_value;
2638 l_term_complete := 'Y';
2639 END IF;
2640 l_se_date := LAST_DAY(l_start_date);
2641 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
2642 l_se_date := l_se_date - 1;
2643 END IF;
2644 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2645 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_end_date::l_k_end_date '||l_end_date||'::'||l_k_end_date);
2646 END IF;
2647 EXIT WHEN TRUNC(l_end_date) = TRUNC(l_k_end_date);
2648 l_start_date := LAST_DAY(l_start_date) + 1;
2649 j := j + 1;
2650 END LOOP;
2651 ELSE
2652
2653 IF asset_rents(k).stub_yn = 'Y' AND
2654 LAST_DAY(asset_rents(k).se_date) = LAST_DAY(asset_rents(k+1).se_date) THEN
2655 k := k + 1;
2656 l_se_date := trunc(asset_rents(k).se_date);
2657 l_end_date := l_se_date;
2658 l_days := OKL_PRICING_UTILS_PVT.get_day_count(
2659 p_start_date => l_start_date,
2660 p_days_in_month => l_day_convention_month,
2661 p_days_in_year => l_day_convention_year,
2662 p_end_date => l_end_date,
2663 p_arrears => l_rent_sll.arrears_yn,
2664 x_return_status => x_return_status);
2665 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2666 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' Status 9 '||x_return_status);
2667 END IF;
2668 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2669 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
2670 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2671 EXIT WHEN(x_return_status = OKL_API.G_RET_STS_ERROR);
2672 END IF;
2673 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
2674 l_termination_val := l_termination_val - asset_rents(k).se_amount;
2675 END IF;
2676 l_days := 30 - TO_CHAR(l_end_date, 'DD');
2677 IF l_days <= 0 THEN
2678 IF l_rent_sll.arrears_yn = 'Y' THEN
2679 l_days := 0;
2680 ELSE
2681 l_days := 1;
2682 END IF;
2683 ELSIF l_rent_sll.arrears_yn = 'N' THEN
2684 l_days := l_days + 1;
2685 END IF;
2686 l_termination_val := l_termination_val*(1 + l_days*l_bk_yield/360);
2687 l_se_date := LAST_DAY(l_start_date);
2688 IF TO_CHAR(LAST_DAY(l_se_date), 'DD') = '31' THEN
2689 l_se_date := l_se_date - 1;
2690 END IF;
2691 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2692 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' arrears/advanced '|| l_rent_sll.arrears_yn);
2693 END IF;
2694 k := k + 1;
2695 END IF;
2696 EXIT WHEN l_term_complete = 'Y';
2697 END IF;
2698 l_start_date := LAST_DAY(l_start_date) + 1;
2699 END LOOP;
2700 l_diff := l_termination_val;
2701 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
2702 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' changed precision ' || l_bk_yield || '::' || l_diff );
2703 END IF;
2704 IF ROUND(l_diff, 5) = 0 THEN
2705 x_booking_yield := l_bk_yield;
2706 EXIT;
2707 END IF;
2708 IF SIGN(l_diff) <> SIGN(l_prev_diff) AND l_crossed_zero = 'N' THEN
2709 l_crossed_zero := 'Y';
2710 END IF;
2711 IF l_crossed_zero = 'Y' THEN
2712 l_abs_incr := ABS(l_increment) / 2;
2713 ELSE
2714 l_abs_incr := ABS(l_increment);
2715 END IF;
2716 IF i > 1 THEN
2717 IF SIGN(l_diff) <> l_prev_diff_sign THEN
2718 IF l_prev_incr_sign = 1 THEN
2719 l_increment := - l_abs_incr;
2720 ELSE
2721 l_increment := l_abs_incr;
2722 END IF;
2723 ELSE
2724 IF l_prev_incr_sign = 1 THEN
2725 l_increment := l_abs_incr;
2726 ELSE
2727 l_increment := - l_abs_incr;
2728 END IF;
2729 END IF;
2730 ELSE
2731 IF SIGN(l_diff) = -1 THEN
2732 l_increment := l_increment;
2733 ELSIF SIGN(l_diff) = 1 THEN
2734 l_increment := -l_increment;
2735 END IF;
2736 END IF;
2737 l_bk_yield := l_bk_yield + l_increment;
2738 l_prev_incr_sign := SIGN(l_increment);
2739 l_prev_diff_sign := SIGN(l_diff);
2740 l_prev_diff := l_diff;
2741 END LOOP;
2742 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
2743 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
2744 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
2745 RAISE OKL_API.G_EXCEPTION_ERROR;
2746 END IF;
2747 OKL_API.END_ACTIVITY (x_msg_count,
2748 x_msg_data );
2749 EXCEPTION
2750 WHEN OKL_API.G_EXCEPTION_ERROR THEN
2751 IF c_rent_slls%ISOPEN THEN
2752 CLOSE c_rent_slls;
2753 END IF;
2754 IF c_rent_flows%ISOPEN THEN
2755 CLOSE c_rent_flows;
2756 END IF;
2757 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
2758 l_api_name,
2759 G_PKG_NAME,
2760 'OKL_API.G_RET_STS_ERROR',
2761 x_msg_count,
2762 x_msg_data,
2763 '_PVT');
2764 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
2765 IF c_rent_slls%ISOPEN THEN
2766 CLOSE c_rent_slls;
2767 END IF;
2768 IF c_rent_flows%ISOPEN THEN
2769 CLOSE c_rent_flows;
2770 END IF;
2771 x_return_status :=OKL_API.HANDLE_EXCEPTIONS(
2772 l_api_name,
2773 G_PKG_NAME,
2774 'OKL_API.G_RET_STS_UNEXP_ERROR',
2775 x_msg_count,
2776 x_msg_data,
2777 '_PVT');
2778 WHEN OTHERS THEN
2779 IF c_rent_slls%ISOPEN THEN
2780 CLOSE c_rent_slls;
2781 END IF;
2782 IF c_rent_flows%ISOPEN THEN
2783 CLOSE c_rent_flows;
2784 END IF;
2785 x_return_status :=OKL_API.HANDLE_EXCEPTIONS(
2786 l_api_name,
2787 G_PKG_NAME,
2788 'OTHERS',
2789 x_msg_count,
2790 x_msg_data,
2791 '_PVT');
2792 END comp_so_bk_yd;
2793 ---------------------------------------------------------------------------
2794 -- Start of Commnets
2795 -- Badrinath Kuchibholta
2796 -- Procedure Name : comp_so_pre_tax_irr
2797 -- Description : This Procedure will calculate pre_tax_irr if the
2798 -- there is a amount given and also will calculate
2799 -- payment amount when a pre_tax_irr is given
2800 -- Business Rules : We need to consider the asset cost and fee cost for
2801 -- this calculation and also will calculated for
2802 -- given contract id and so_payment line
2803 -- Parameters : p_khr_id -- contract_id
2804 -- p_kle_id -- So_payment line id
2805 -- p_target -- Either RATE/PMNT
2806 -- Version :1.0
2807 -- History : 07-SEP-2003 BAKUHCIB CREATED for Bug# *****
2808 -- End of Comments
2809 ---------------------------------------------------------------------------
2810 PROCEDURE comp_so_pre_tax_irr(p_api_version IN NUMBER,
2811 p_init_msg_list IN VARCHAR2 DEFAULT OKL_API.G_FALSE,
2812 x_return_status OUT NOCOPY VARCHAR2,
2813 x_msg_count OUT NOCOPY NUMBER,
2814 x_msg_data OUT NOCOPY VARCHAR2,
2815 p_khr_id IN NUMBER,
2816 p_kle_id IN NUMBER,
2817 p_target IN VARCHAR2,
2818 p_subside_yn IN VARCHAR2 DEFAULT 'N',
2819 p_interim_tbl IN interim_interest_tbl_type,
2820 x_payment OUT NOCOPY NUMBER,
2821 x_rate OUT NOCOPY NUMBER)
2822 IS
2823 l_api_name CONSTANT VARCHAR2(30) := 'COMP_SO_PRE_IRR';
2824 i BINARY_INTEGER := 0;
2825 m BINARY_INTEGER := 0;
2826 n BINARY_INTEGER := 0;
2827 p BINARY_INTEGER := 0;
2828 q BINARY_INTEGER := 0;
2829 r BINARY_INTEGER := 0;
2830 s BINARY_INTEGER := 0;
2831 l_time_zero_cost NUMBER := 0;
2832 l_cost NUMBER;
2833 l_adv_payment NUMBER := 0;
2834 l_currency_code VARCHAR2(15);
2835 l_precision NUMBER(1);
2836 l_cf_dpp NUMBER;
2837 l_cf_ppy NUMBER;
2838 l_cf_amount NUMBER;
2839 l_cf_date DATE;
2840 l_cf_arrear VARCHAR2(1);
2841 l_days_in_future NUMBER;
2842 l_periods NUMBER;
2843 l_irr NUMBER := 0;
2844 l_npv_rate NUMBER;
2845 l_npv_pay NUMBER;
2846 l_irr_limit NUMBER := NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000)/100;
2847 l_prev_npv_pay NUMBER;
2848 l_prev_npv_sign_pay NUMBER;
2849 l_crossed_zero_pay VARCHAR2(1) := 'N';
2850 l_increment_pay NUMBER := 0.1; -- 10% increment
2851 l_abs_incr_pay NUMBER;
2852 l_prev_incr_sign_pay NUMBER;
2853 l_prev_npv_rate NUMBER;
2854 l_prev_npv_sign_rate NUMBER;
2855 l_crossed_zero_rate VARCHAR2(1) := 'N';
2856 l_increment_rate NUMBER := 0.1; -- 10% increment
2857 l_abs_incr_rate NUMBER;
2858 l_prev_incr_sign_rate NUMBER;
2859 l_payment_inflow NUMBER := 0;
2860 l_payment_inter NUMBER := 0;
2861 l_asset_cost NUMBER := 0;
2862 l_residual_value NUMBER := 0;
2863 ld_res_pay_start_date DATE;
2864 ld_asset_start_date DATE;
2865 l_subside_yn VARCHAR2(1) := NVL(p_subside_yn,'N');
2866 l_khr_start_date DATE;
2867
2868 Cursor khr_type_csr IS
2869 Select SCS_CODE,
2870 START_DATE
2871 From okc_K_headers_b chr
2872 Where chr.id = p_khr_id;
2873
2874 khr_type_rec khr_type_csr%ROWTYPE;
2875 l_line_type VARCHAR2(256);
2876
2877 -- Gets all the Payment inflow over the SO_PAYMENT lines and Fee Lines
2878 CURSOR c_security_deposit
2879 IS
2880 SELECT DISTINCT
2881 sel_amt.id id,
2882 sel_amt.amount cf_amount,
2883 sel_amt.stream_element_date cf_date,
2884 sel_rate.amount rate,
2885 sel_rate.comments miss_amt,
2886 sel_amt.comments cf_arrear,
2887 sty.stream_type_purpose cf_purpose,
2888 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
2889 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
2890 chr_so.start_date,
2891 chr_so.end_date
2892 FROM okl_streams stm,
2893 okl_strm_type_b sty,
2894 okl_strm_elements sel_rate,
2895 okl_strm_elements sel_amt,
2896 okc_k_headers_b chr_so,
2897 okc_k_lines_b cle,
2898 okl_k_lines kle,
2899 okc_line_styles_b lse,
2900 okc_rules_b sll,
2901 okc_rules_b slh,
2902 okc_rule_groups_b rgp
2903 WHERE stm.khr_id = p_khr_id
2904 --AND stm.kle_id = p_kle_id
2905 AND stm.say_code = 'WORK'
2906 AND stm.purpose_code = 'FLOW'
2907 AND stm.sty_id = sty.id
2908 AND stm.id = sel_amt.stm_id
2909 AND sel_amt.comments IS NOT NULL
2910 AND stm.id = sel_rate.stm_id
2911 AND sel_rate.sel_id = sel_amt.id
2912 AND stm.kle_id = cle.id
2913 AND cle.dnz_chr_id = chr_so.id
2914 AND kle.id = cle.id
2915 AND trunc(cle.START_DATE) = trunc(chr_so.START_DATE)
2916 AND cle.lse_id = lse.id
2917 AND lse.lty_code = 'FEE'
2918 AND kle.fee_type = 'SECDEPOSIT'
2919 AND sty.stream_type_purpose = 'SECURITY_DEPOSIT'
2920 AND cle.id = rgp.cle_id
2921 AND rgp.rgd_code = 'LALEVL'
2922 AND rgp.id = slh.rgp_id
2923 AND slh.rule_information_category = 'LASLH'
2924 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
2925 AND TO_CHAR(slh.id) = sll.object2_id1
2926 AND sll.rule_information_category = 'LASLL';
2927
2928 l_security_deposit c_security_deposit%ROWTYPE;
2929
2930 -- Gets all the Payment inflow over the Fee Lines
2931 CURSOR c_fee_inflows(p_khr_id NUMBER) IS
2932 SELECT DISTINCT
2933 sel_amt.id id,
2934 sel_amt.amount cf_amount,
2935 sel_amt.stream_element_date cf_date,
2936 sel_rate.amount rate,
2937 sel_rate.comments miss_amt,
2938 sel_amt.comments cf_arrear,
2939 sty.stream_type_purpose cf_purpose,
2940 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
2941 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
2942 chr_so.start_date,
2943 lse.lty_code
2944 FROM okl_streams stm,
2945 okl_strm_type_b sty,
2946 okl_strm_elements sel_rate,
2947 okl_strm_elements sel_amt,
2948 okc_k_headers_b chr_so,
2949 okc_k_lines_b cle,
2950 okl_k_lines kle,
2951 okc_line_styles_b lse,
2952 okc_rules_b sll,
2953 okc_rules_b slh,
2954 okc_rule_groups_b rgp
2955 WHERE stm.khr_id = p_khr_id
2956 AND stm.kle_id = cle.id
2957 AND stm.kle_id = kle.id
2958 AND stm.say_code = 'WORK'
2959 AND stm.purpose_code = 'FLOW'
2960 AND stm.sty_id = sty.id
2961 AND stm.id = sel_amt.stm_id
2962 AND sel_amt.comments IS NOT NULL
2963 AND stm.id = sel_rate.stm_id
2964 AND sel_rate.sel_id = sel_amt.id
2965 AND stm.kle_id = cle.id
2966 AND kle.id = cle.id
2967 AND cle.dnz_chr_id = chr_so.id
2968 AND trunc(cle.START_DATE) = trunc(chr_so.START_DATE)
2969 AND cle.lse_id = lse.id
2970 AND lse.lty_code = 'FEE'
2971 AND kle.fee_type NOT IN ('SECDEPOSIT', 'PASSTHROUGH' )
2972 AND cle.id = rgp.cle_id
2973 AND rgp.rgd_code = 'LALEVL'
2974 AND rgp.id = slh.rgp_id
2975 AND slh.rule_information_category = 'LASLH'
2976 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
2977 AND TO_CHAR(slh.id) = sll.object2_id1
2978 AND sll.rule_information_category = 'LASLL';
2979
2980 -- Gets all the Payment inflow over the SO_PAYMENT/FREE_FORM1 lines
2981 CURSOR c_inflows(p_khr_id NUMBER,
2982 p_kle_id NUMBER,
2983 p_line_type VARCHAR2)
2984 IS
2985 SELECT DISTINCT
2986 sel_amt.id id,
2987 sel_amt.amount cf_amount,
2988 sel_amt.stream_element_date cf_date,
2989 sel_rate.amount rate,
2990 sel_rate.comments miss_amt,
2991 sel_amt.comments cf_arrear,
2992 sty.stream_type_purpose cf_purpose,
2993 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
2994 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
2995 chr_so.start_date
2996 FROM okl_streams stm,
2997 okl_strm_type_b sty,
2998 okl_strm_elements sel_rate,
2999 okl_strm_elements sel_amt,
3000 okc_k_headers_b chr_so,
3001 okc_k_lines_b cle,
3002 okc_line_styles_b lse,
3003 okc_rules_b sll,
3004 okc_rules_b slh,
3005 okc_rule_groups_b rgp
3006 WHERE stm.khr_id = p_khr_id
3007 AND stm.kle_id = p_kle_id
3008 AND stm.kle_id = cle.id
3009 AND stm.say_code = 'WORK'
3010 AND stm.purpose_code = 'FLOW'
3011 AND stm.sty_id = sty.id
3012 AND stm.id = sel_amt.stm_id
3013 AND sel_amt.comments IS NOT NULL
3014 AND stm.id = sel_rate.stm_id
3015 AND sel_rate.sel_id = sel_amt.id
3016 AND stm.kle_id = cle.id
3017 AND cle.dnz_chr_id = chr_so.id
3018 AND trunc(cle.START_DATE) = trunc(chr_so.START_DATE)
3019 AND cle.lse_id = lse.id
3020 AND lse.lty_code = p_line_type --'SO_PAYMENT'
3021 AND cle.id = rgp.cle_id
3022 AND rgp.rgd_code = 'LALEVL'
3023 AND rgp.id = slh.rgp_id
3024 AND slh.rule_information_category = 'LASLH'
3025 AND TO_NUMBER(slh.object1_id1) = stm.sty_id
3026 AND TO_CHAR(slh.id) = sll.object2_id1
3027 AND sll.rule_information_category = 'LASLL';
3028 -- Gets the Asset residual value
3029 CURSOR c_asset_rvs(p_khr_id NUMBER,
3030 p_kle_id NUMBER,
3031 p_line_type VARCHAR2)
3032 IS
3033 SELECT DISTINCT DECODE(rul_sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
3034 DECODE(rul_sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
3035 DECODE(rul_sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
3036 cle_so.END_DATE
3037 FROM okc_k_headers_b chr_so,
3038 okc_line_styles_b lse_so,
3039 okc_k_lines_b cle_so,
3040 okc_rule_groups_b rgp_pay,
3041 okc_rules_b rul_slh,
3042 okc_rules_b rul_sll,
3043 okl_strm_type_b sty
3044 WHERE cle_so.id = p_kle_id
3045 AND cle_so.dnz_chr_id = p_khr_id
3046 AND cle_so.lse_id = lse_so.id
3047 AND cle_so.dnz_chr_id = chr_so.id
3048 AND trunc(cle_so.START_DATE) = trunc(chr_so.START_DATE )
3049 AND lse_so.lty_code = p_line_type --'SO_PAYMENT'
3050 AND cle_so.id = rgp_pay.cle_id
3051 AND rgp_pay.dnz_chr_id = cle_so.dnz_chr_id
3052 AND rgp_pay.rgd_code = 'LALEVL'
3053 AND rgp_pay.id = rul_slh.rgp_id
3054 AND rul_slh.rule_information_category = 'LASLH'
3055 AND TO_CHAR(rul_slh.id) = rul_sll.object2_id1
3056 AND rul_sll.rule_information_category = 'LASLL'
3057 AND TO_NUMBER(rul_slh.object1_id1) = sty.id
3058 AND sty.stream_type_purpose = 'RENT';
3059 -- to get the fee cost
3060 CURSOR c_fee_cost(p_khr_id NUMBER)
3061 IS
3062 SELECT NVL(kle.amount, 0) amount,
3063 cle.start_date
3064 FROM okc_k_headers_b chr_so,
3065 okl_k_lines kle,
3066 okc_k_lines_b cle,
3067 okc_line_styles_b lse
3068 WHERE cle.chr_id = p_khr_id
3069 AND cle.lse_id = lse.id
3070 AND nvl(kle.fee_type, 'XXX') not in ( 'SECDEPOSIT', 'INCOME', 'CAPITALIZED' )
3071 AND lse.lty_code = 'FEE'
3072 AND cle.id = kle.id
3073 AND chr_so.id = cle.dnz_chr_id
3074 AND trunc(chr_so.START_DATE) = trunc(cle.START_DATE)
3075 AND NOT EXISTS (SELECT 1
3076 FROM okc_rule_groups_b rgp
3077 WHERE rgp.cle_id = cle.id
3078 AND rgp.rgd_code = 'LAPSTH')
3079 AND NOT EXISTS (SELECT 1
3080 FROM okc_rule_groups_b rgp,
3081 okc_rules_b rul,
3082 okc_rules_b rul2
3083 WHERE rgp.cle_id = cle.id
3084 AND rgp.rgd_code = 'LAFEXP'
3085 AND rgp.id = rul.rgp_id
3086 AND rgp.id = rul2.rgp_id
3087 AND rul.rule_information_category = 'LAFEXP'
3088 AND rul2.rule_information_category = 'LAFREQ'
3089 AND rul.rule_information1 IS NOT NULL
3090 AND rul.rule_information2 IS NOT NULL
3091 AND rul2.object1_id1 IS NOT NULL);
3092 -- get Pass through Fee info
3093 CURSOR c_pass_th(p_khr_id NUMBER)
3094 IS
3095 SELECT DISTINCT
3096 sel_amt.id id,
3097 sel_amt.amount cf_amount,
3098 sel_amt.stream_element_date cf_date,
3099 sel.amount rate,
3100 sel.comments miss_amt,
3101 sel.comments cf_arrear,
3102 sty.stream_type_purpose cf_purpose,
3103 chr_so.START_DATE,
3104 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
3105 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
3106 NVL(TO_NUMBER(laptpr.rule_information1), 100) pass_through_percentage,
3107 sll.rule_information10 arrears_yn
3108 FROM okl_streams stm,
3109 okl_strm_type_b sty,
3110 okl_strm_elements sel_amt,
3111 okl_strm_elements sel,
3112 okc_k_headers_b chr_so,
3113 okc_k_lines_b cle,
3114 okc_line_styles_b lse,
3115 okl_k_lines kle,
3116 okc_rules_b sll,
3117 okc_rules_b slh,
3118 okc_rule_groups_b rgp,
3119 okc_rule_groups_b rgp2,
3120 okc_rules_b laptpr
3121 WHERE stm.khr_id = p_khr_id
3122 AND stm.say_code = 'WORK'
3123 AND stm.purpose_code = 'FLOW'
3124 AND stm.sty_id = sty.id
3125 AND stm.id = sel.stm_id
3126 AND sel.comments IS NOT NULL
3127 AND stm.kle_id = cle.id
3128 AND cle.lse_id = lse.id
3129 AND chr_so.id = cle.dnz_chr_id
3130 AND trunc(chr_so.START_DATE) = trunc(cle.START_DATE)
3131 AND lse.lty_code = 'FEE'
3132 AND cle.id = kle.id
3133 AND stm.id = sel_amt.stm_id
3134 AND sel_amt.comments IS NOT NULL
3135 AND stm.id = sel.stm_id
3136 AND sel.sel_id = sel_amt.id
3137 AND cle.id = rgp.cle_id
3138 AND rgp.rgd_code = 'LALEVL'
3139 AND rgp.id = slh.rgp_id
3140 AND slh.rule_information_category = 'LASLH'
3141 AND TO_CHAR(slh.id) = sll.object2_id1
3142 AND sll.rule_information_category = 'LASLL'
3143 AND stm.kle_id = rgp2.cle_id
3144 AND rgp2.rgd_code = 'LAPSTH'
3145 AND rgp2.id = laptpr.rgp_id
3146 AND laptpr.rule_information_category = 'LAPTPR';
3147 -- Get recurring expense streams
3148 CURSOR c_rec_exp(p_khr_id NUMBER)
3149 IS
3150 SELECT TO_NUMBER(rul.rule_information1) periods,
3151 TO_NUMBER(rul.rule_information2) cf_amount,
3152 DECODE(rul2.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) cf_dpp,
3153 DECODE(rul2.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) cf_ppy,
3154 DECODE(rul2.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) cf_mpp,
3155 cle.start_date start_date
3156 FROM okc_rules_b rul,
3157 okc_rules_b rul2,
3158 okc_rule_groups_b rgp,
3159 okc_k_headers_b chr_so,
3160 okc_k_lines_b cle,
3161 okc_line_styles_b lse
3162 WHERE cle.chr_id = p_khr_id
3163 AND cle.lse_id = lse.id
3164 AND lse.lty_code = 'FEE'
3165 AND cle.id = rgp.cle_id
3166 AND rgp.rgd_code = 'LAFEXP'
3167 AND rgp.id = rul.rgp_id
3168 AND rgp.id = rul2.rgp_id
3169 AND rul.rule_information_category = 'LAFEXP'
3170 AND rul2.rule_information_category = 'LAFREQ'
3171 AND rul.rule_information1 IS NOT NULL
3172 AND rul.rule_information2 IS NOT NULL
3173 AND rul2.object1_id1 IS NOT NULL
3174 AND cle.dnz_chr_id = chr_so.id
3175 AND trunc(chr_so.START_DATE) = trunc(cle.START_DATE)
3176 AND NOT EXISTS (SELECT 1
3177 FROM okc_rule_groups_b rgp
3178 WHERE rgp.cle_id = cle.id
3179 AND rgp.rgd_code = 'LAPSTH');
3180 -- To get the Currency code and Precision
3181 CURSOR get_curr_code_pre(p_khr_id NUMBER)
3182 IS
3183 SELECT NVL(a.precision,0) precision
3184 FROM fnd_currencies a,
3185 okc_k_headers_b b
3186 WHERE b.currency_code = a.currency_code
3187 AND b.id = p_khr_id;
3188 -- To get the Contract Start date
3189 CURSOR get_start_date(p_khr_id NUMBER)
3190 IS
3191 SELECT start_date
3192 FROM okc_k_headers_b b
3193 WHERE b.id = p_khr_id;
3194
3195 TYPE cash_flow_rec_type IS RECORD (cf_amount NUMBER,
3196 cf_date DATE,
3197 cf_purpose VARCHAR2(150),
3198 cf_dpp NUMBER,
3199 cf_ppy NUMBER,
3200 cf_days NUMBER,
3201 rate NUMBER,
3202 miss_amt okl_strm_elements.comments%TYPE);
3203 TYPE cash_flow_tbl_type IS TABLE OF cash_flow_rec_type INDEX BY BINARY_INTEGER;
3204 hdr_inflow_tbl cash_flow_tbl_type;
3205 inflow_tbl cash_flow_tbl_type;
3206 rv_tbl cash_flow_tbl_type;
3207 outflow_tbl cash_flow_tbl_type;
3208 pass_th_tbl cash_flow_tbl_type;
3209 rec_exp_tbl cash_flow_tbl_type;
3210
3211 l_term NUMBER;
3212
3213 l_day_convention_month VARCHAR2(30);
3214 l_day_convention_year VARCHAR2(30);
3215 l_days_in_year NUMBER;
3216
3217 BEGIN
3218 IF (G_DEBUG_ENABLED = 'Y') THEN
3219 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
3220 END IF;
3221
3222 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3223 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'begin' );
3224
3225 END IF;
3226 x_return_status := OKL_API.G_RET_STS_SUCCESS;
3227 -- Call start_activity to create savepoint, check compatibility
3228 -- and initialize message list
3229 x_return_status := OKL_API.START_ACTIVITY (
3230 l_api_name
3231 ,p_init_msg_list
3232 ,'_PVT'
3233 ,x_return_status);
3234 -- Check if activity started successfully
3235 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
3236 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3237 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
3238 RAISE OKL_API.G_EXCEPTION_ERROR;
3239 END IF;
3240 -- check if the target is correctly given
3241 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3242 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'check if the target is correctly given' || ' ' || p_target );
3243
3244 END IF;
3245 IF p_target NOT IN ('RATE','PMNT') THEN
3246 OKL_API.set_message(p_app_name => G_APP_NAME,
3247 p_msg_name => G_INVALID_VALUE,
3248 p_token1 => G_COL_NAME_TOKEN,
3249 p_token1_value => 'Target');
3250 RAISE OKL_API.G_EXCEPTION_ERROR;
3251 END IF;
3252
3253 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3254 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'check if the target is correctly given - done');
3255 END IF;
3256 -- Fetch the day convention ..
3257 OKL_PRICING_UTILS_PVT.get_day_convention(
3258 p_id => p_khr_id,
3259 p_source => 'ISG',
3260 x_days_in_month => l_day_convention_month,
3261 x_days_in_year => l_day_convention_year,
3262 x_return_status => x_return_status);
3263 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3264 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, 'comp_so_pre_tax_irr Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
3265 END IF;
3266 IF (x_return_status = G_RET_STS_UNEXP_ERROR) THEN
3267 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3268 ELSIF (x_return_status = G_RET_STS_ERROR) THEN
3269 RAISE OKL_API.G_EXCEPTION_ERROR;
3270 END IF;
3271 OPEN get_start_date(P_khr_id => p_khr_id);
3272 FETCH get_start_date INTO l_khr_start_date;
3273 IF get_start_date%NOTFOUND THEN
3274 RAISE OKL_API.G_EXCEPTION_ERROR;
3275 END IF;
3276 CLOSE get_start_date;
3277 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3278 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'got start date');
3279
3280 END IF;
3281 -- Summing up Asset cost
3282 -- And since the input is a so_payment line we sum up the asset's cost
3283 -- to the so_payment line, assuming the start date of the so_payment
3284 -- and Asset start date are same.
3285 OKL_LA_STREAM_PVT.get_so_asset_oec(p_khr_id => p_khr_id,
3286 p_kle_id => p_kle_id,
3287 p_subside_yn => l_subside_yn,
3288 x_return_status => x_return_status,
3289 x_asset_oec => l_cost,
3290 x_start_date => ld_asset_start_date);
3291 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3292 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' get_so_asset_oec '|| x_return_status);
3293 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' get_so_asset_oec - again '|| x_return_status);
3294 END IF;
3295 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3296 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3297 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3298 RAISE OKL_API.G_EXCEPTION_ERROR;
3299 END IF;
3300 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3301 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_time_zero '|| x_return_status);
3302 END IF;
3303 l_time_zero_cost := l_time_zero_cost + NVL(l_cost, 0);
3304 -- Summing up Fee cost
3305 -- Here the fee are attached to the contract header
3306 -- We do not include, security deposit fee, capiatlized fees, Pass through fee
3307 -- and also expense fees.
3308 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3309 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'before fee cost '|| x_return_status);
3310 END IF;
3311 FOR l_fee_cost IN c_fee_cost(p_khr_id => p_khr_id) LOOP
3312 IF l_fee_cost.start_date IS NOT NULL OR
3313 l_fee_cost.start_date <> OKL_API.G_MISS_DATE THEN
3314 l_time_zero_cost := l_time_zero_cost + l_fee_cost.amount;
3315 END IF;
3316 END LOOP;
3317
3318 OPEN khr_type_csr;
3319 FETCH khr_type_csr INTO khr_type_rec;
3320 CLOSE khr_type_csr;
3321
3322 IF (INSTR( khr_type_rec.scs_code, 'LEASE') > 0) THEN
3323 l_line_type := 'FREE_FORM1';
3324 Else
3325 l_line_type := 'SO_PAYMENT';
3326 End If;
3327
3328 -- Collecting the inflow amounts
3329 -- from the strm elements table since where the payment associated to the
3330 -- So_payment lines are broken into stream elements data
3331 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3332 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'before inflows '|| x_return_status);
3333 END IF;
3334 FOR l_inflow IN c_inflows(p_khr_id => p_khr_id,
3335 p_kle_id => p_kle_id,
3336 p_line_type => l_line_type) LOOP
3337 n := n + 1;
3338 inflow_tbl(n).cf_amount := l_inflow.cf_amount;
3339 inflow_tbl(n).miss_amt := l_inflow.miss_amt;
3340 inflow_tbl(n).cf_date := l_inflow.cf_date;
3341 inflow_tbl(n).cf_purpose := l_inflow.cf_purpose;
3342 inflow_tbl(n).cf_dpp := l_inflow.days_per_period;
3343 inflow_tbl(n).cf_ppy := l_inflow.periods_per_year;
3344 inflow_tbl(n).rate := l_inflow.rate;
3345 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3346 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' start date::end date ' || l_inflow.start_date || '::' || l_inflow.cf_date|| x_return_status);
3347 END IF;
3348 inflow_tbl(n).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
3349 p_start_date => l_inflow.start_date,
3350 p_days_in_month => l_day_convention_month,
3351 p_days_in_year => l_day_convention_year,
3352 p_end_date => l_inflow.cf_date,
3353 p_arrears => l_inflow.cf_arrear,
3354 x_return_status => x_return_status);
3355 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3356 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3357 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3358 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3359 END IF;
3360 IF (inflow_tbl(n).rate IS NULL OR
3361 inflow_tbl(n).rate = OKL_API.G_MISS_NUM) AND
3362 p_target = 'RATE' THEN
3363 OKL_API.set_message(
3364 p_app_name => G_APP_NAME,
3365 p_msg_name => G_INVALID_VALUE,
3366 p_token1 => G_COL_NAME_TOKEN,
3367 p_token1_value => 'Rate');
3368 x_return_status := OKL_API.G_RET_STS_ERROR;
3369 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3370 END IF;
3371 END LOOP;
3372
3373 FOR l_inflow IN c_fee_inflows(p_khr_id => p_khr_id ) LOOP
3374
3375 n := n + 1;
3376 inflow_tbl(n).cf_amount := l_inflow.cf_amount;
3377 inflow_tbl(n).miss_amt := l_inflow.miss_amt;
3378 inflow_tbl(n).cf_date := l_inflow.cf_date;
3379 inflow_tbl(n).cf_purpose := l_inflow.cf_purpose;
3380 inflow_tbl(n).cf_dpp := l_inflow.days_per_period;
3381 inflow_tbl(n).cf_ppy := l_inflow.periods_per_year;
3382 inflow_tbl(n).rate := l_inflow.rate;
3383 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3384 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' start date::end date ' || l_inflow.start_date || '::' || l_inflow.cf_date|| x_return_status);
3385 END IF;
3386 inflow_tbl(n).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
3387 p_start_date => l_inflow.start_date,
3388 p_days_in_month => l_day_convention_month,
3389 p_days_in_year => l_day_convention_year,
3390 p_end_date => l_inflow.cf_date,
3391 p_arrears => l_inflow.cf_arrear,
3392 x_return_status => x_return_status);
3393 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3394 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3395 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3396 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3397 END IF;
3398 IF (inflow_tbl(n).rate IS NULL OR
3399 inflow_tbl(n).rate = OKL_API.G_MISS_NUM) AND
3400 p_target = 'RATE' THEN
3401 OKL_API.set_message(
3402 p_app_name => G_APP_NAME,
3403 p_msg_name => G_INVALID_VALUE,
3404 p_token1 => G_COL_NAME_TOKEN,
3405 p_token1_value => 'Rate');
3406 x_return_status := OKL_API.G_RET_STS_ERROR;
3407 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3408 END IF;
3409
3410 END LOOP;
3411
3412 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3413 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'after inflows # ' || n|| x_return_status);
3414 END IF;
3415 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3416 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3417 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3418 RAISE OKL_API.G_EXCEPTION_ERROR;
3419 END IF;
3420 -- Collecting the Residual Value amount
3421 -- Here since the Assets are associated to one so_payment line
3422 -- we sum up to get actual residual value , residual value percent
3423 -- are stored in rules
3424 FOR l_asset_rv IN c_asset_rvs(p_khr_id => p_khr_id,
3425 p_kle_id => p_kle_id,
3426 p_line_type => l_line_type) LOOP
3427 p := p + 1;
3428 OKL_LA_STREAM_PVT.get_so_residual_value(p_khr_id => p_khr_id,
3429 p_kle_id => p_kle_id,
3430 p_subside_yn => l_subside_yn,
3431 x_return_status => x_return_status,
3432 x_residual_value => rv_tbl(p).cf_amount,
3433 x_start_date => ld_res_pay_start_date);
3434 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3435 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3436 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3437 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3438 END IF;
3439 l_residual_value := rv_tbl(p).cf_amount;
3440 rv_tbl(p).cf_date := l_asset_rv.end_date;
3441 rv_tbl(p).cf_dpp := l_asset_rv.days_per_period;
3442 rv_tbl(p).cf_ppy := l_asset_rv.periods_per_year;
3443 OKL_PRICING_PVT.get_rate(p_khr_id => p_khr_id,
3444 p_date => rv_tbl(p).cf_date,
3445 x_rate => rv_tbl(p).rate,
3446 x_return_status => x_return_status);
3447 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3448 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3449 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3450 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3451 END IF;
3452 IF (rv_tbl(p).rate IS NULL OR
3453 rv_tbl(p).rate = OKL_API.G_MISS_NUM) AND
3454 p_target = 'RATE' THEN
3455 OKL_API.set_message(
3456 p_app_name => G_APP_NAME,
3457 p_msg_name => G_INVALID_VALUE,
3458 p_token1 => G_COL_NAME_TOKEN,
3459 p_token1_value => 'Rate');
3460 x_return_status := OKL_API.G_RET_STS_ERROR;
3461 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3462 END IF;
3463 rv_tbl(p).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
3464 p_start_date => ld_res_pay_start_date,
3465 p_days_in_month => l_day_convention_month,
3466 p_days_in_year => l_day_convention_year,
3467 p_end_date => rv_tbl(p).cf_date,
3468 p_arrears => 'Y',
3469 x_return_status => x_return_status);
3470 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3471 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3472 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3473 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3474 END IF;
3475 END LOOP;
3476 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3477 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'after residual values #' || p|| x_return_status);
3478 END IF;
3479 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3480 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3481 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3482 RAISE OKL_API.G_EXCEPTION_ERROR;
3483 END IF;
3484 -- Collecting the Outflow amounts of Fee
3485 -- Here the fee are attached to the contract header
3486 -- We do not include, security deposit fee, capiatlized fees, Pass through fee
3487 -- and also expense fees.
3488 FOR l_outflow IN c_fee_cost(p_khr_id => p_khr_id) LOOP
3489 IF l_outflow.start_date > l_khr_start_date THEN
3490 q := q + 1;
3491 outflow_tbl(q).cf_amount := -(l_outflow.amount);
3492 outflow_tbl(q).cf_date := l_outflow.start_date;
3493 outflow_tbl(q).cf_dpp := 1;
3494 outflow_tbl(q).cf_ppy := 360;
3495 OKL_PRICING_PVT.get_rate(p_khr_id => p_khr_id,
3496 p_date => outflow_tbl(q).cf_date,
3497 x_rate => outflow_tbl(q).rate,
3498 x_return_status => x_return_status);
3499 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3500 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3501 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3502 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3503 END IF;
3504 IF (outflow_tbl(q).rate IS NULL OR
3505 outflow_tbl(q).rate = OKL_API.G_MISS_NUM) AND
3506 p_target = 'RATE' THEN
3507 OKL_API.set_message(
3508 p_app_name => G_APP_NAME,
3509 p_msg_name => G_INVALID_VALUE,
3510 p_token1 => G_COL_NAME_TOKEN,
3511 p_token1_value => 'Rate');
3512 x_return_status := OKL_API.G_RET_STS_ERROR;
3513 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3514 END IF;
3515 outflow_tbl(q).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
3516 p_start_date => l_outflow.start_date,
3517 p_days_in_month => l_day_convention_month,
3518 p_days_in_year => l_day_convention_year,
3519 p_end_date => l_outflow.start_date,
3520 p_arrears => 'N',
3521 x_return_status => x_return_status);
3522 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3523 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3524 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3525 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3526 END IF;
3527 END IF;
3528 END LOOP;
3529 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3530 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'after outflows ' || q|| x_return_status);
3531 END IF;
3532 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3533 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3534 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3535 RAISE OKL_API.G_EXCEPTION_ERROR;
3536 END IF;
3537 -- Collecting the Outflow amounts of asset
3538 -- Since we are summing up to the so_payment line
3539 -- We would have one asset cost
3540 IF ld_asset_start_date > l_khr_start_date THEN
3541 q := q + 1;
3542 OKL_LA_STREAM_PVT.get_so_asset_oec(
3543 p_khr_id => p_khr_id,
3544 p_kle_id => p_kle_id,
3545 p_subside_yn => l_subside_yn,
3546 x_return_status => x_return_status,
3547 x_asset_oec => outflow_tbl(q).cf_amount,
3548 x_start_date => ld_asset_start_date);
3549 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3550 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3551 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3552 RAISE OKL_API.G_EXCEPTION_ERROR;
3553 END IF;
3554 outflow_tbl(q).cf_amount := -(outflow_tbl(q).cf_amount);
3555 outflow_tbl(q).cf_date := ld_asset_start_date;
3556 outflow_tbl(q).cf_dpp := 1;
3557 outflow_tbl(q).cf_ppy := 360;
3558 OKL_PRICING_PVT.get_rate(p_khr_id => p_khr_id,
3559 p_date => outflow_tbl(q).cf_date,
3560 x_rate => outflow_tbl(q).rate,
3561 x_return_status => x_return_status);
3562 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3563 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3564 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3565 RAISE OKL_API.G_EXCEPTION_ERROR;
3566 END IF;
3567 IF (outflow_tbl(q).rate IS NULL OR
3568 outflow_tbl(q).rate = OKL_API.G_MISS_NUM) AND
3569 p_target = 'RATE' THEN
3570 OKL_API.set_message(
3571 p_app_name => G_APP_NAME,
3572 p_msg_name => G_INVALID_VALUE,
3573 p_token1 => G_COL_NAME_TOKEN,
3574 p_token1_value => 'Rate');
3575 x_return_status := OKL_API.G_RET_STS_ERROR;
3576 RAISE OKL_API.G_EXCEPTION_ERROR;
3577 END IF;
3578 outflow_tbl(q).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
3579 p_start_date => ld_asset_start_date,
3580 p_days_in_month => l_day_convention_month,
3581 p_days_in_year => l_day_convention_year,
3582 p_end_date => ld_asset_start_date,
3583 p_arrears => 'N',
3584 x_return_status => x_return_status);
3585 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3586 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3587 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3588 RAISE OKL_API.G_EXCEPTION_ERROR;
3589 END IF;
3590 END IF;
3591 -- Collecting Pass-through Amounts
3592 FOR l_pass_th IN c_pass_th(p_khr_id => p_khr_id) LOOP
3593
3594 If ( l_pass_th.pass_through_percentage < 100 ) Then
3595
3596 r := r + 1;
3597 pass_th_tbl(r).cf_amount := l_pass_th.cf_amount*(1 - l_pass_th.pass_through_percentage/100);
3598 pass_th_tbl(r).cf_date := l_pass_th.cf_date;
3599 pass_th_tbl(r).cf_purpose := l_pass_th.cf_purpose;
3600 pass_th_tbl(r).cf_dpp := l_pass_th.days_per_period;
3601 pass_th_tbl(r).cf_ppy := l_pass_th.periods_per_year;
3602 pass_th_tbl(r).rate := l_pass_th.rate;
3603 IF (pass_th_tbl(r).rate IS NULL OR
3604 pass_th_tbl(r).rate = OKL_API.G_MISS_NUM) AND
3605 p_target = 'RATE' THEN
3606 OKL_API.set_message(
3607 p_app_name => G_APP_NAME,
3608 p_msg_name => G_INVALID_VALUE,
3609 p_token1 => G_COL_NAME_TOKEN,
3610 p_token1_value => 'Rate');
3611 x_return_status := OKL_API.G_RET_STS_ERROR;
3612 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3613 END IF;
3614 pass_th_tbl(r).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
3615 p_start_date => l_pass_th.start_date,
3616 p_days_in_month => l_day_convention_month,
3617 p_days_in_year => l_day_convention_year,
3618 p_end_date => l_pass_th.cf_date,
3619 p_arrears => l_pass_th.arrears_yn,
3620 --l_pass_th.cf_arrear,
3621 x_return_status => x_return_status);
3622 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3623 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3624 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3625 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3626 END IF;
3627
3628 END If;
3629
3630 END LOOP;
3631 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3632 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3633 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3634 RAISE OKL_API.G_EXCEPTION_ERROR;
3635 END IF;
3636 -- Collecting Reccuring Amounts
3637 FOR l_rec_exp IN c_rec_exp(p_khr_id => p_khr_id) LOOP
3638 FOR s1 in 1..l_rec_exp.periods LOOP
3639 s := s + 1;
3640 rec_exp_tbl(s).cf_amount := -(l_rec_exp.cf_amount);
3641 rec_exp_tbl(s).cf_date := ADD_MONTHS(l_rec_exp.start_date, (s1 -1)*l_rec_exp.cf_mpp);
3642 rec_exp_tbl(s).cf_dpp := l_rec_exp.cf_dpp;
3643 rec_exp_tbl(s).cf_ppy := l_rec_exp.cf_ppy;
3644 OKL_PRICING_PVT.get_rate(p_khr_id => p_khr_id,
3645 p_date =>l_rec_exp.start_date,
3646 x_rate => rec_exp_tbl(s).rate,
3647 x_return_status => x_return_status);
3648 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3649 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3650 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3651 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3652 END IF;
3653 IF (rec_exp_tbl(s).rate IS NULL OR
3654 rec_exp_tbl(s).rate = OKL_API.G_MISS_NUM) AND
3655 p_target = 'RATE' THEN
3656 OKL_API.set_message(
3657 p_app_name => G_APP_NAME,
3658 p_msg_name => G_INVALID_VALUE,
3659 p_token1 => G_COL_NAME_TOKEN,
3660 p_token1_value => 'Rate');
3661 x_return_status := OKL_API.G_RET_STS_ERROR;
3662 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3663 END IF;
3664 rec_exp_tbl(s).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
3665 p_start_date => l_rec_exp.start_date,
3666 p_days_in_month => l_day_convention_month,
3667 p_days_in_year => l_day_convention_year,
3668 p_end_date => rec_exp_tbl(s).cf_date,
3669 p_arrears => 'N',
3670 x_return_status => x_return_status);
3671 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3672 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
3673 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3674 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3675 END IF;
3676 END LOOP;
3677 END LOOP;
3678 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3679 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'after expenses '|| x_return_status);
3680 END IF;
3681 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3682 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3683 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3684 RAISE OKL_API.G_EXCEPTION_ERROR;
3685 END IF;
3686 -- Validating Sum of all the inflow do not exceed the Total Time zero cost
3687 IF n > 0 THEN
3688 FOR n1 IN inflow_tbl.FIRST..inflow_tbl.LAST LOOP
3689 IF inflow_tbl(n1).cf_date <= ld_asset_start_date THEN
3690 l_adv_payment := l_adv_payment + inflow_tbl(n1).cf_amount;
3691 END IF;
3692 END LOOP;
3693 END IF;
3694 IF r > 0 THEN
3695 FOR r1 IN pass_th_tbl.FIRST..pass_th_tbl.LAST LOOP
3696 IF pass_th_tbl(r1).cf_date <= ld_asset_start_date THEN
3697 l_adv_payment := l_adv_payment + pass_th_tbl(r1).cf_amount;
3698 END IF;
3699 END LOOP;
3700 END IF;
3701 IF l_adv_payment >= l_time_zero_cost THEN
3702 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3703 p_msg_name => 'OKL_IRR_CALC_INF_LOOP',
3704 p_token1 => 'ADV_AMOUNT',
3705 p_token1_value => l_adv_payment,
3706 p_token2 => 'CAPITAL_AMOUNT',
3707 p_token2_value => l_time_zero_cost);
3708 RAISE OKL_API.G_EXCEPTION_ERROR;
3709 END IF;
3710 -- To get the Currency code and Precision
3711 OPEN get_curr_code_pre(p_khr_id => p_khr_id);
3712 FETCH get_curr_code_pre INTO l_precision;
3713 IF get_curr_code_pre%NOTFOUND THEN
3714 OKL_API.set_message(p_app_name => G_APP_NAME,
3715 p_msg_name => G_REQUIRED_VALUE,
3716 p_token1 => G_COL_NAME_TOKEN,
3717 p_token1_value => 'Currency Code ');
3718 RAISE OKL_API.G_EXCEPTION_ERROR;
3719 END IF;
3720 CLOSE get_curr_code_pre;
3721 -- Setting the IRR limit
3722 l_irr_limit := ROUND(NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000), 0)/100;
3723 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3724 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'l_irr_limit ' ||l_irr_limit);
3725 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'b4 getting into the loop '|| x_return_status);
3726 END IF;
3727 LOOP
3728 i := i + 1;
3729 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3730 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ### ITERATION ### | ### PVALUE ### | ### IRR ### ');
3731 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || i || ' | ' || l_npv_rate || ' | ' || l_irr);
3732 END IF;
3733 l_npv_rate := -(l_time_zero_cost);
3734 l_npv_pay := -(l_time_zero_cost);
3735
3736 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3737 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' time zero : ' || l_npv_pay );
3738
3739 END IF;
3740 -------------------------------------------
3741 -- FEE COST CASH OUTFLOWS
3742 -------------------------------------------
3743 IF q > 0 THEN
3744 FOR w IN outflow_tbl.FIRST..outflow_tbl.LAST LOOP
3745 l_cf_dpp := outflow_tbl(w).cf_dpp;
3746 l_cf_ppy := outflow_tbl(w).cf_ppy;
3747 l_cf_amount := outflow_tbl(w).cf_amount;
3748 l_cf_date := outflow_tbl(w).cf_date;
3749 l_days_in_future := outflow_tbl(w).cf_days;
3750 l_periods := l_days_in_future / l_cf_dpp;
3751 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
3752 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3753 p_msg_name => 'OKL_IRR_ZERO_DIV');
3754 x_return_status := OKL_API.G_RET_STS_ERROR;
3755 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3756 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide outflows '|| x_return_status);
3757 END IF;
3758 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3759 END IF;
3760 IF p_target = 'RATE' THEN
3761 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + outflow_tbl(w).rate/(l_cf_ppy*100)), l_periods));
3762 ELSIF p_target = 'PMNT' THEN
3763 l_npv_rate := l_npv_rate + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
3764 END IF;
3765 END LOOP;
3766 END IF;
3767
3768 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3769 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' outflow : ' || l_npv_pay );
3770 END IF;
3771 -------------------------------------------
3772 -- PASSTHROUGH CASH INFLOWS
3773 -------------------------------------------
3774 IF r > 0 THEN
3775 FOR v IN pass_th_tbl.FIRST..pass_th_tbl.LAST LOOP
3776 l_cf_dpp := pass_th_tbl(v).cf_dpp;
3777 l_cf_ppy := pass_th_tbl(v).cf_ppy;
3778 l_cf_amount := pass_th_tbl(v).cf_amount;
3779 l_cf_date := pass_th_tbl(v).cf_date;
3780 l_days_in_future := pass_th_tbl(v).cf_days;
3781 l_periods := l_days_in_future / l_cf_dpp;
3782 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
3783 --IF (l_irr/l_cf_ppy = -1) THEN
3784 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3785 p_msg_name => 'OKL_IRR_ZERO_DIV');
3786 x_return_status := OKL_API.G_RET_STS_ERROR;
3787 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3788 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide passthru '|| x_return_status);
3789 END IF;
3790 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3791 END IF;
3792
3793 IF p_target = 'RATE' THEN
3794 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + pass_th_tbl(v).rate/(l_cf_ppy*100)), l_periods));
3795 ELSIF p_target = 'PMNT' THEN
3796 l_npv_rate := l_npv_rate + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
3797 END IF;
3798 END LOOP;
3799 END IF;
3800
3801 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3802 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' pass thru : ' || l_npv_pay );
3803
3804 END IF;
3805 -------------------------------------------
3806 -- FEE RECURRING EXPENSE CASH OUTFLOWS
3807 -------------------------------------------
3808 IF s > 0 THEN
3809 FOR t IN rec_exp_tbl.FIRST..rec_exp_tbl.LAST LOOP
3810 l_cf_ppy := rec_exp_tbl(t).cf_ppy;
3811 l_cf_dpp := rec_exp_tbl(t).cf_dpp;
3812 l_cf_amount := rec_exp_tbl(t).cf_amount;
3813 l_cf_date := rec_exp_tbl(t).cf_date;
3814 l_days_in_future := rec_exp_tbl(t).cf_days;
3815 l_periods := l_days_in_future / l_cf_dpp;
3816 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
3817 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3818 p_msg_name => 'OKL_IRR_ZERO_DIV');
3819 x_return_status := OKL_API.G_RET_STS_ERROR;
3820 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3821 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide expenses '|| x_return_status);
3822 END IF;
3823 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3824 END IF;
3825 IF p_target = 'RATE' THEN
3826 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + rec_exp_tbl(t).rate/(l_cf_ppy*100)), l_periods));
3827 ELSIF p_target = 'PMNT' THEN
3828 l_npv_rate := l_npv_rate + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
3829 END IF;
3830 END LOOP;
3831 END IF;
3832 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3833 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' exp : ' || l_npv_pay );
3834 END IF;
3835 -------------------------------------------
3836 -- RV CASH INFLOWS
3837 -------------------------------------------
3838 IF p > 0 THEN
3839 FOR z IN rv_tbl.FIRST..rv_tbl.LAST LOOP
3840 l_cf_dpp := rv_tbl(z).cf_dpp;
3841 l_cf_ppy := rv_tbl(z).cf_ppy;
3842 l_cf_amount := rv_tbl(z).cf_amount;
3843 l_cf_date := rv_tbl(z).cf_date;
3844 l_days_in_future := rv_tbl(z).cf_days;
3845 l_periods := l_days_in_future / l_cf_dpp;
3846 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
3847 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3848 p_msg_name => 'OKL_IRR_ZERO_DIV');
3849 x_return_status := OKL_API.G_RET_STS_ERROR;
3850 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3851 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide rvs '|| x_return_status);
3852 END IF;
3853 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3854 END IF;
3855 IF p_target = 'RATE' THEN
3856 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + rv_tbl(z).rate/(l_cf_ppy*100)), l_periods));
3857 ELSIF p_target = 'PMNT' THEN
3858 l_npv_rate := l_npv_rate + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
3859 END IF;
3860 END LOOP;
3861 END IF;
3862 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3863 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' rv : ' || l_npv_pay );
3864 END IF;
3865 ----------------------------------------------
3866 -- SECURITY DEPOSIT
3867 ----------------------------------------------
3868 OPEN c_security_deposit;
3869 FETCH c_security_deposit INTO l_security_deposit;
3870 If ( c_security_deposit%FOUND ) Then
3871
3872 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_khr_start_date,
3873 p_days_in_month => l_day_convention_month,
3874 p_days_in_year => l_day_convention_year,
3875 p_end_date => l_security_deposit.cf_date,
3876 p_arrears => 'N' ,
3877 x_return_status => x_return_status);
3878
3879 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3880 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3881 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3882 RAISE OKL_API.G_EXCEPTION_ERROR;
3883 END IF;
3884
3885 l_periods := l_days_in_future / l_security_deposit.days_per_period;
3886 IF p_target = 'RATE' THEN
3887 l_npv_pay := l_npv_pay +
3888 (l_security_deposit.cf_amount/POWER((1+l_security_deposit.rate/l_security_deposit.periods_per_year),l_periods));
3889 ELSIF p_target = 'PMNT' THEN
3890 l_npv_rate := l_npv_rate +
3891 (l_security_deposit.cf_amount / POWER((1 + l_irr/l_security_deposit.periods_per_year), l_periods));
3892 End If;
3893
3894 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_khr_start_date,
3895 p_days_in_month => l_day_convention_month,
3896 p_days_in_year => l_day_convention_year,
3897 p_end_date => l_security_deposit.end_date,
3898 p_arrears => 'N' ,
3899 x_return_status => x_return_status);
3900
3901 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
3902 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
3903 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
3904 RAISE OKL_API.G_EXCEPTION_ERROR;
3905 END IF;
3906
3907 l_periods := l_days_in_future / l_security_deposit.days_per_period;
3908 IF p_target = 'RATE' THEN
3909 l_npv_pay := l_npv_pay -
3910 (l_security_deposit.cf_amount/POWER((1+l_security_deposit.rate/l_security_deposit.periods_per_year),l_periods));
3911 ELSIF p_target = 'PMNT' THEN
3912 l_npv_rate := l_npv_rate -
3913 (l_security_deposit.cf_amount / POWER((1 + l_irr/l_security_deposit.periods_per_year), l_periods));
3914 End If;
3915
3916 END If;
3917 CLOSE c_security_deposit;
3918
3919 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3920 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' sec dep : ' || l_npv_pay );
3921 END IF;
3922 -------------------------------------------
3923 -- LINE LEVEL CASH INFLOWS
3924 -------------------------------------------
3925 IF p_target = 'RATE' THEN
3926 l_term := 0;
3927 FOR y IN inflow_tbl.FIRST..inflow_tbl.LAST
3928 LOOP
3929 l_cf_dpp := inflow_tbl(y).cf_dpp;
3930 l_cf_ppy := inflow_tbl(y).cf_ppy;
3931 l_days_in_future := inflow_tbl(y).cf_days;
3932 l_periods := l_days_in_future / l_cf_dpp;
3933 IF inflow_tbl(y).miss_amt = 'Y' THEN
3934 l_term := l_term + (1 / POWER((1 + inflow_tbl(y).rate/(l_cf_ppy*100)), l_periods));
3935 ELSIF inflow_tbl(y).miss_amt = 'N' THEN
3936 l_cf_amount := inflow_tbl(y).cf_amount;
3937 l_cf_date := inflow_tbl(y).cf_date;
3938 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
3939 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3940 p_msg_name => 'OKL_IRR_ZERO_DIV');
3941 x_return_status := OKL_API.G_RET_STS_ERROR;
3942 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3943 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide indlows '|| x_return_status);
3944 END IF;
3945 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3946 END IF;
3947 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + inflow_tbl(y).rate/(l_cf_ppy*100)), l_periods));
3948 END IF;
3949 END LOOP;
3950
3951 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3952 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' inflo : ' || l_npv_pay );
3953 END IF;
3954 If (l_term <> 0 ) Then
3955 l_payment_inflow := (-1 * l_npv_pay ) / l_term;
3956 else
3957 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3958 p_msg_name => 'OKL_IRR_ZERO_DIV');
3959 x_return_status := OKL_API.G_RET_STS_ERROR;
3960 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3961 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide indlows '|| x_return_status);
3962 END IF;
3963 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3964 end if;
3965
3966 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3967 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_npv_pay ' || l_npv_pay );
3968 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_term ' || l_term );
3969
3970 END IF;
3971 l_npv_pay := 0;
3972
3973 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3974 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_payment_inflow ' || l_payment_inflow );
3975 END IF;
3976 Else
3977
3978 IF n > 0 THEN
3979 FOR y IN inflow_tbl.FIRST..inflow_tbl.LAST LOOP
3980 l_cf_dpp := inflow_tbl(y).cf_dpp;
3981 l_cf_ppy := inflow_tbl(y).cf_ppy;
3982 IF inflow_tbl(y).miss_amt = 'Y' AND p_target = 'RATE' THEN
3983 l_cf_amount := l_payment_inflow;
3984 ELSIF inflow_tbl(y).miss_amt = 'N' THEN
3985 l_cf_amount := inflow_tbl(y).cf_amount;
3986 END IF;
3987 l_cf_date := inflow_tbl(y).cf_date;
3988 l_days_in_future := inflow_tbl(y).cf_days;
3989 l_periods := l_days_in_future / l_cf_dpp;
3990 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
3991 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
3992 p_msg_name => 'OKL_IRR_ZERO_DIV');
3993 x_return_status := OKL_API.G_RET_STS_ERROR;
3994 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
3995 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide indlows '|| x_return_status);
3996 END IF;
3997 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
3998 END IF;
3999 IF p_target = 'RATE' THEN
4000 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + inflow_tbl(y).rate/(l_cf_ppy*100)), l_periods));
4001 ELSIF p_target = 'PMNT' THEN
4002 l_npv_rate := l_npv_rate + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
4003 END IF;
4004 END LOOP;
4005 END IF;
4006
4007 End If;
4008
4009 IF p_target = 'RATE' THEN
4010 IF ROUND(l_npv_pay, l_precision+4) = 0 THEN
4011 x_payment := l_payment_inflow;
4012 EXIT;
4013 END IF;
4014 ELSIF p_target = 'PMNT' THEN
4015 IF ROUND(l_npv_rate, l_precision+4) = 0 THEN
4016 x_rate := l_irr;
4017 EXIT;
4018 END IF;
4019 END IF;
4020 IF p_target = 'RATE' THEN
4021 IF SIGN(l_npv_pay) <> SIGN(l_prev_npv_pay) AND l_crossed_zero_pay = 'N' THEN
4022 l_crossed_zero_pay := 'Y';
4023 END IF;
4024 IF l_crossed_zero_pay = 'Y' THEN
4025 l_abs_incr_pay := ABS(l_increment_pay) / 2;
4026 ELSE
4027 l_abs_incr_pay := ABS(l_increment_pay);
4028 END IF;
4029 IF i > 1 THEN
4030 IF SIGN(l_npv_pay) <> l_prev_npv_sign_pay THEN
4031 IF l_prev_incr_sign_pay = 1 THEN
4032 l_increment_pay := - l_abs_incr_pay;
4033 ELSE
4034 l_increment_pay := l_abs_incr_pay;
4035 END IF;
4036 ELSE
4037 IF l_prev_incr_sign_pay = 1 THEN
4038 l_increment_pay := l_abs_incr_pay;
4039 ELSE
4040 l_increment_pay := - l_abs_incr_pay;
4041 END IF;
4042 END IF;
4043 ELSE
4044 IF SIGN(l_npv_pay) = -1 THEN
4045 l_increment_pay := l_increment_pay;
4046 ELSIF SIGN(l_npv_pay) = 1 THEN
4047 l_increment_pay := -l_increment_pay;
4048 END IF;
4049 END IF;
4050 l_payment_inflow := l_payment_inflow + l_increment_pay;
4051 l_prev_incr_sign_pay := SIGN(l_increment_pay);
4052 l_prev_npv_sign_pay := SIGN(l_npv_pay);
4053 l_prev_npv_pay := l_npv_pay;
4054 ELSIF p_target = 'PMNT' THEN
4055 IF SIGN(l_npv_rate) <> SIGN(l_prev_npv_rate) AND l_crossed_zero_rate = 'N' THEN
4056 l_crossed_zero_rate := 'Y';
4057 END IF;
4058 IF l_crossed_zero_rate = 'Y' THEN
4059 l_abs_incr_rate := ABS(l_increment_rate) / 2;
4060 ELSE
4061 l_abs_incr_rate := ABS(l_increment_rate);
4062 END IF;
4063 IF i > 1 THEN
4064 IF SIGN(l_npv_rate) <> l_prev_npv_sign_rate THEN
4065 IF l_prev_incr_sign_rate = 1 THEN
4066 l_increment_rate := - l_abs_incr_rate;
4067 ELSE
4068 l_increment_rate := l_abs_incr_rate;
4069 END IF;
4070 ELSE
4071 IF l_prev_incr_sign_rate = 1 THEN
4072 l_increment_rate := l_abs_incr_rate;
4073 ELSE
4074 l_increment_rate := - l_abs_incr_rate;
4075 END IF;
4076 END IF;
4077 ELSE
4078 IF SIGN(l_npv_rate) = -1 THEN
4079 l_increment_rate := -l_increment_rate;
4080 END IF;
4081 END IF;
4082 l_irr := l_irr + l_increment_rate;
4083 IF ABS(l_irr) > l_irr_limit THEN
4084 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
4085 p_msg_name => 'OKL_IRR_CALC_IRR_LIMIT',
4086 p_token1 => 'IRR_LIMIT',
4087 p_token1_value => l_irr_limit*100);
4088 x_return_status := OKL_API.G_RET_STS_ERROR;
4089 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4090 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' 100000% '|| x_return_status);
4091 END IF;
4092 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
4093 END IF;
4094 l_prev_incr_sign_rate := SIGN(l_increment_rate);
4095 l_prev_npv_sign_rate := SIGN(l_npv_rate);
4096 l_prev_npv_rate := l_npv_rate;
4097 END IF;
4098 END LOOP;
4099 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4100 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4101 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
4102 RAISE OKL_API.G_EXCEPTION_ERROR;
4103 END IF;
4104 OKL_API.END_ACTIVITY (x_msg_count,
4105 x_msg_data );
4106 EXCEPTION
4107 WHEN OKL_API.G_EXCEPTION_ERROR THEN
4108 IF get_curr_code_pre%ISOPEN THEN
4109 CLOSE get_curr_code_pre;
4110 END IF;
4111 IF c_rec_exp%ISOPEN THEN
4112 CLOSE c_rec_exp;
4113 END IF;
4114 IF c_pass_th%ISOPEN THEN
4115 CLOSE c_pass_th;
4116 END IF;
4117 IF c_fee_cost%ISOPEN THEN
4118 CLOSE c_fee_cost;
4119 END IF;
4120 IF c_asset_rvs%ISOPEN THEN
4121 CLOSE c_asset_rvs;
4122 END IF;
4123 IF c_inflows%ISOPEN THEN
4124 CLOSE c_inflows;
4125 END IF;
4126 IF get_start_date%ISOPEN THEN
4127 CLOSE get_start_date;
4128 END IF;
4129 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
4130 l_api_name,
4131 G_PKG_NAME,
4132 'OKL_API.G_RET_STS_ERROR',
4133 x_msg_count,
4134 x_msg_data,
4135 '_PVT');
4136 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
4137 IF get_curr_code_pre%ISOPEN THEN
4138 CLOSE get_curr_code_pre;
4139 END IF;
4140 IF c_rec_exp%ISOPEN THEN
4141 CLOSE c_rec_exp;
4142 END IF;
4143 IF c_pass_th%ISOPEN THEN
4144 CLOSE c_pass_th;
4145 END IF;
4146 IF c_fee_cost%ISOPEN THEN
4147 CLOSE c_fee_cost;
4148 END IF;
4149 IF c_asset_rvs%ISOPEN THEN
4150 CLOSE c_asset_rvs;
4151 END IF;
4152 IF c_inflows%ISOPEN THEN
4153 CLOSE c_inflows;
4154 END IF;
4155 IF get_start_date%ISOPEN THEN
4156 CLOSE get_start_date;
4157 END IF;
4158 x_return_status :=OKL_API.HANDLE_EXCEPTIONS(
4159 l_api_name,
4160 G_PKG_NAME,
4161 'OKL_API.G_RET_STS_UNEXP_ERROR',
4162 x_msg_count,
4163 x_msg_data,
4164 '_PVT');
4165 WHEN OTHERS THEN
4166 IF get_curr_code_pre%ISOPEN THEN
4167 CLOSE get_curr_code_pre;
4168 END IF;
4169 IF c_rec_exp%ISOPEN THEN
4170 CLOSE c_rec_exp;
4171 END IF;
4172 IF c_pass_th%ISOPEN THEN
4173 CLOSE c_pass_th;
4174 END IF;
4175 IF c_fee_cost%ISOPEN THEN
4176 CLOSE c_fee_cost;
4177 END IF;
4178 IF c_asset_rvs%ISOPEN THEN
4179 CLOSE c_asset_rvs;
4180 END IF;
4181 IF c_inflows%ISOPEN THEN
4182 CLOSE c_inflows;
4183 END IF;
4184 IF get_start_date%ISOPEN THEN
4185 CLOSE get_start_date;
4186 END IF;
4187 x_return_status :=OKL_API.HANDLE_EXCEPTIONS(
4188 l_api_name,
4189 G_PKG_NAME,
4190 'OTHERS',
4191 x_msg_count,
4192 x_msg_data,
4193 '_PVT');
4194 END comp_so_pre_tax_irr;
4195
4196
4197
4198 ---------------------------------------------------------------------------
4199 -- PROCEDURE compute_irr
4200 --
4201 -- Description
4202 --
4203 ---------------------------------------------------------------------------
4204 PROCEDURE compute_irr (p_khr_id IN NUMBER,
4205 p_start_date IN DATE,
4206 p_term_duration IN NUMBER,
4207 p_interim_tbl IN interim_interest_tbl_type,
4208 p_subsidies_yn IN VARCHAR2,
4209 p_initial_irr IN NUMBER,
4210 x_irr OUT NOCOPY NUMBER,
4211 x_return_status OUT NOCOPY VARCHAR2) IS
4212
4213 CURSOR c_hdr_inflows IS
4214 SELECT DISTINCT
4215 sel.id id,
4216 sel.amount cf_amount,
4217 sel.stream_element_date cf_date,
4218 sel.comments cf_arrear,
4219 sty.stream_type_purpose cf_purpose,
4220 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
4221 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year
4222 FROM okl_streams stm,
4223 okl_strm_type_b sty,
4224 okl_strm_elements sel,
4225 okc_rules_b sll,
4226 okc_rules_b slh,
4227 okc_rule_groups_b rgp
4228 WHERE stm.khr_id = p_khr_id
4229 AND stm.say_code = 'WORK'
4230 AND stm.purpose_code IS NULL
4231 AND stm.sty_id = sty.id
4232 AND stm.id = sel.stm_id
4233 AND sel.comments IS NOT NULL
4234 AND stm.khr_id = rgp.dnz_chr_id
4235 AND rgp.cle_id IS NULL
4236 AND rgp.rgd_code = 'LALEVL'
4237 AND rgp.id = slh.rgp_id
4238 AND slh.rule_information_category = 'LASLH'
4239 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
4240 AND TO_CHAR(slh.id) = sll.object2_id1
4241 AND sll.rule_information_category = 'LASLL';
4242
4243 Cursor c_link_pmnts( chrId NUMBER, kleId NUMBER ) IS
4244 Select 'Y' What
4245 from dual
4246 Where Exists(Select crl.id slh_id
4247 From OKC_RULE_GROUPS_B crg,
4248 OKC_RULES_B crl,
4249 okc_K_lines_b cle_lnk,
4250 okl_K_lines kle_roll
4251 Where crl.rgp_id = crg.id
4252 and crg.RGD_CODE = 'LALEVL'
4253 and crl.RULE_INFORMATION_CATEGORY = 'LASLL'
4254 and crg.dnz_chr_id = chrId
4255 and crg.cle_id = kleId
4256 and crg.cle_id = cle_lnk.id
4257 and cle_lnk.cle_id = kle_roll.id
4258 and kle_roll.fee_type in ('MISCELLANEOUS', 'FINANCED', 'ROLLOVER', 'PASSTHROUGH'));
4259
4260 r_link_pmnts c_link_pmnts%ROWTYPE;
4261
4262 CURSOR c_inflows IS
4263 SELECT DISTINCT
4264 sel.id id,
4265 sel.amount cf_amount,
4266 sel.stream_element_date cf_date,
4267 sel.comments cf_arrear,
4268 sty.stream_type_purpose cf_purpose,
4269 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
4270 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
4271 cle.id kleId,
4272 lse.lty_code
4273 FROM okl_streams stm,
4274 okl_strm_type_b sty,
4275 okl_strm_elements sel,
4276 okc_k_lines_b cle,
4277 okc_line_styles_b lse,
4278 okc_rules_b sll,
4279 okc_rules_b slh,
4280 okc_rule_groups_b rgp
4281 WHERE stm.khr_id = p_khr_id
4282 AND stm.say_code = 'WORK'
4283 AND stm.purpose_code IS NULL
4284 AND stm.sty_id = sty.id
4285 AND sty.stream_type_purpose NOT LIKE 'ESTIMATED_PROPERTY_TAX'
4286 AND stm.id = sel.stm_id
4287 AND sel.comments IS NOT NULL
4288 AND stm.kle_id = cle.id
4289 AND NOT EXISTS (SELECT 1
4290 FROM okc_rule_groups_b rgp2
4291 WHERE rgp2.dnz_chr_id = p_khr_id
4292 AND rgp2.cle_id = cle.id
4293 AND rgp2.rgd_code = 'LAPSTH')
4294 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
4295 AND cle.lse_id = lse.id
4296 AND lse.lty_code IN ('FREE_FORM1', 'FEE', 'LINK_FEE_ASSET')
4297 AND cle.id = rgp.cle_id
4298 AND rgp.rgd_code = 'LALEVL'
4299 AND rgp.id = slh.rgp_id
4300 AND slh.rule_information_category = 'LASLH'
4301 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
4302 AND TO_CHAR(slh.id) = sll.object2_id1
4303 AND sll.rule_information_category = 'LASLL';
4304
4305 -- Cursor definition implies RENT must be defined at Asset Level
4306
4307 CURSOR c_asset_rvs IS
4308 SELECT DISTINCT
4309 kle.id,
4310 NVL(kle.residual_value, 0) cf_amount,
4311 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
4312 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
4313 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
4314 cle.start_date,
4315 cle.date_terminated,
4316 cle.sts_code
4317 FROM okl_k_lines kle,
4318 okc_k_lines_b cle,
4319 okc_line_styles_b lse,
4320 okc_rule_groups_b rgp,
4321 okc_rules_b slh,
4322 okc_rules_b sll,
4323 okl_strm_type_b styt
4324 WHERE cle.chr_id = p_khr_id
4325 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
4326 AND cle.lse_id = lse.id
4327 AND lse.lty_code = 'FREE_FORM1'
4328 AND cle.id = kle.id
4329 AND kle.id = rgp.cle_id
4330 AND rgp.rgd_code = 'LALEVL'
4331 AND rgp.id = slh.rgp_id
4332 AND slh.rule_information_category = 'LASLH'
4333 AND TO_CHAR(slh.id) = sll.object2_id1
4334 AND sll.rule_information_category = 'LASLL'
4335 AND slh.object1_id1 = TO_CHAR(styt.id)
4336 AND styt.stream_type_purpose = 'RENT';
4337
4338 CURSOR c_deposit_date IS
4339 SELECT FND_DATE.canonical_to_date(rule_information5)
4340 FROM okc_rules_b
4341 WHERE dnz_chr_id = p_khr_id
4342 AND rule_information_category = 'LASDEP';
4343
4344 /* CURSOR c_asset_cost IS
4345 SELECT cle.id id,
4346 cle.start_date start_date,
4347 kle.capital_amount,
4348 kle.capitalized_interest,
4349 kle.date_funding_expected
4350 FROM okc_k_lines_b cle,
4351 okl_K_lines kle,
4352 okc_line_styles_b lse
4353 WHERE cle.chr_id = p_khr_id
4354 AND cle.id = kle.id
4355 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
4356 AND cle.lse_id = lse.id
4357 AND lse.lty_code = 'FREE_FORM1';
4358 */
4359 -- Bug 5287279 : 08-Jun-2006 : kbbhavsa
4360 -- c_asset_cost cursor modified by including distinct
4361 CURSOR c_asset_cost IS
4362 SELECT DISTINCT cle.id id,
4363 cle.start_date start_date,
4364 kle.capital_amount,
4365 kle.capitalized_interest,
4366 kle.date_funding_expected,
4367 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
4368 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
4369 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
4370 cle.date_terminated,
4371 cle.sts_code
4372 FROM okl_k_lines kle,
4373 okc_k_lines_b cle,
4374 okc_line_styles_b lse,
4375 okc_rule_groups_b rgp,
4376 okc_rules_b slh,
4377 okc_rules_b sll,
4378 okl_strm_type_b sty
4379 WHERE cle.chr_id = p_khr_id
4380 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED') -- Bug 5011438
4381 AND cle.lse_id = lse.id
4382 AND lse.lty_code = 'FREE_FORM1'
4383 AND cle.id = kle.id
4384 AND kle.id = rgp.cle_id
4385 AND rgp.rgd_code = 'LALEVL'
4386 AND rgp.id = slh.rgp_id
4387 AND slh.rule_information_category = 'LASLH'
4388 AND TO_CHAR(slh.id) = sll.object2_id1
4389 AND sll.rule_information_category = 'LASLL'
4390 AND slh.object1_id1 = TO_CHAR(sty.id)
4391 AND sty.stream_type_purpose = 'RENT';
4392 --Modified by dkagrawa on 06-Oct-2005 for Bug 4654516
4393 --Added the nvl check to the capitalise_yn flag
4394 CURSOR c_fee_cost IS
4395 SELECT NVL(kle.amount, 0) amount,
4396 cle.start_date,
4397 cle.id kleId,
4398 lse.lty_code
4399 FROM okl_k_lines kle,
4400 okc_k_lines_b cle,
4401 okc_line_styles_b lse,
4402 okc_k_items cim,
4403 okl_strm_type_b sty
4404 WHERE cle.chr_id = p_khr_id
4405 AND cle.lse_id = lse.id
4406 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
4407 AND kle.fee_type not in ( 'SECDEPOSIT', 'INCOME' )
4408 AND lse.lty_code in ( 'FEE', 'LINK_FEE_ASSET')
4409 AND cle.id = kle.id
4410 AND cle.id = cim.cle_id
4411 AND cim.jtot_object1_code = 'OKL_STRMTYP'
4412 AND cim.object1_id1 = sty.id
4413 AND sty.version = '1.0'
4414 AND NVL(sty.capitalize_yn,'N') <> 'Y'
4415 AND NOT EXISTS (SELECT 1
4416 FROM okc_rule_groups_b rgp
4417 WHERE rgp.cle_id = cle.id
4418 AND rgp.rgd_code = 'LAPSTH')
4419 AND NOT EXISTS (SELECT 1
4420 FROM okc_rule_groups_b rgp,
4421 okc_rules_b rul,
4422 okc_rules_b rul2
4423 WHERE rgp.cle_id = cle.id
4424 AND rgp.rgd_code = 'LAFEXP'
4425 AND rgp.id = rul.rgp_id
4426 AND rgp.id = rul2.rgp_id
4427 AND rul.rule_information_category = 'LAFEXP'
4428 AND rul2.rule_information_category = 'LAFREQ'
4429 AND rul.rule_information1 IS NOT NULL
4430 AND rul.rule_information2 IS NOT NULL
4431 AND rul2.object1_id1 IS NOT NULL);
4432
4433 CURSOR c_pass_th IS
4434 SELECT DISTINCT
4435 cle.id cleId,
4436 sel.id id,
4437 sel.amount cf_amount,
4438 sel.stream_element_date cf_date,
4439 sel.comments cf_arrear,
4440 sty.stream_type_purpose cf_purpose,
4441 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
4442 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
4443 NVL(TO_NUMBER(laptpr.rule_information1), 100) pass_through_percentage
4444 FROM okl_streams stm,
4445 okl_strm_type_b sty,
4446 okl_strm_elements sel,
4447 okc_k_lines_b cle,
4448 okc_line_styles_b lse,
4449 okc_rules_b sll,
4450 okc_rules_b slh,
4451 okc_rule_groups_b rgp,
4452 okc_rule_groups_b rgp2,
4453 okc_rules_b laptpr
4454 WHERE stm.khr_id = p_khr_id
4455 AND stm.say_code = 'WORK'
4456 AND stm.purpose_code IS NULL
4457 AND stm.sty_id = sty.id
4458 AND stm.id = sel.stm_id
4459 AND sel.comments IS NOT NULL
4460 AND stm.kle_id = cle.id
4461 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
4462 AND cle.lse_id = lse.id
4463 AND lse.lty_code in ('FEE', 'LINK_FEE_ASSET')
4464 AND cle.id = rgp.cle_id
4465 AND rgp.rgd_code = 'LALEVL'
4466 AND rgp.id = slh.rgp_id
4467 AND slh.rule_information_category = 'LASLH'
4468 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
4469 AND TO_CHAR(slh.id) = sll.object2_id1
4470 AND sll.rule_information_category = 'LASLL'
4471 AND stm.kle_id = rgp2.cle_id
4472 AND rgp2.rgd_code = 'LAPSTH'
4473 AND rgp2.id = laptpr.rgp_id
4474 AND laptpr.rule_information_category = 'LAPTPR';
4475
4476 CURSOR c_rec_exp IS
4477 SELECT TO_NUMBER(rul.rule_information1) periods,
4478 TO_NUMBER(rul.rule_information2) cf_amount,
4479 DECODE(rul2.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) cf_dpp,
4480 DECODE(rul2.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) cf_ppy,
4481 DECODE(rul2.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) cf_mpp,
4482 cle.start_date start_date
4483 FROM okc_rules_b rul,
4484 okc_rules_b rul2,
4485 okc_rule_groups_b rgp,
4486 okc_k_lines_b cle,
4487 okc_line_styles_b lse
4488 WHERE cle.chr_id = p_khr_id
4489 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
4490 AND cle.lse_id = lse.id
4491 AND lse.lty_code = 'FEE'
4492 AND NOT EXISTS (SELECT 1
4493 FROM okc_rule_groups_b rgp
4494 WHERE rgp.cle_id = cle.id
4495 AND rgp.rgd_code = 'LAPSTH')
4496 AND cle.id = rgp.cle_id
4497 AND rgp.rgd_code = 'LAFEXP'
4498 AND rgp.id = rul.rgp_id
4499 AND rgp.id = rul2.rgp_id
4500 AND rul.rule_information_category = 'LAFEXP'
4501 AND rul2.rule_information_category = 'LAFREQ'
4502 AND rul.rule_information1 IS NOT NULL
4503 AND rul.rule_information2 IS NOT NULL
4504 AND rul2.object1_id1 IS NOT NULL;
4505
4506 --------------------------
4507 -- PERFORMANCE ENHANCEMENT SECTION
4508 --------------------------
4509 TYPE cash_flow_rec_type IS RECORD (cf_amount NUMBER,
4510 cf_date DATE,
4511 cf_purpose VARCHAR2(150),
4512 cf_dpp NUMBER,
4513 cf_ppy NUMBER,
4514 cf_days NUMBER,
4515 kleId NUMBER);
4516
4517 TYPE cash_flow_tbl_type IS TABLE OF cash_flow_rec_type INDEX BY BINARY_INTEGER;
4518
4519 hdr_inflow_tbl cash_flow_tbl_type;
4520 inflow_tbl cash_flow_tbl_type;
4521 subs_inflow_tbl cash_flow_tbl_type;
4522 rv_tbl cash_flow_tbl_type;
4523 outflow_tbl cash_flow_tbl_type;
4524 pass_th_tbl cash_flow_tbl_type;
4525 rec_exp_tbl cash_flow_tbl_type;
4526 subsidies_tbl cash_flow_tbl_type;
4527
4528 m BINARY_INTEGER := 0;
4529 n BINARY_INTEGER := 0;
4530 p BINARY_INTEGER := 0;
4531 q BINARY_INTEGER := 0;
4532 r BINARY_INTEGER := 0;
4533 s BINARY_INTEGER := 0;
4534
4535 --------------------------
4536 -- END PERFORMANCE ENHANCEMENT SECTION
4537 --------------------------
4538 lx_msg_count NUMBER;
4539 lx_msg_data VARCHAR2(4000);
4540 l_end_date DATE := ADD_MONTHS(p_start_date, p_term_duration) - 1;
4541 l_time_zero_cost NUMBER := 0;
4542 l_cost NUMBER;
4543 l_residual_value NUMBER;
4544 l_adv_payment NUMBER := 0;
4545 l_subsidy_amount NUMBER := 0;
4546 l_currency_code VARCHAR2(15);
4547 l_precision NUMBER(1);
4548
4549 l_cf_dpp NUMBER;
4550 l_cf_ppy NUMBER;
4551 l_cf_amount NUMBER;
4552 l_cf_date DATE;
4553 l_cf_arrear VARCHAR2(1);
4554 l_days_in_future NUMBER;
4555 l_periods NUMBER;
4556 l_deposit_date DATE;
4557
4558 i BINARY_INTEGER := 0;
4559 l_irr NUMBER := nvl( p_initial_irr, 0 );
4560 l_npv NUMBER;
4561
4562 l_irr_limit NUMBER := NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000)/100;
4563
4564 l_prev_npv NUMBER;
4565 l_prev_npv_sign NUMBER;
4566
4567 l_crossed_zero VARCHAR2(1) := 'N';
4568
4569 l_increment NUMBER := 0.11;
4570 l_abs_incr NUMBER;
4571 l_prev_incr_sign NUMBER;
4572
4573 --DEBUG
4574 a binary_integer := 0;
4575 b binary_integer := 0;
4576
4577 lx_return_status VARCHAR2(1);
4578
4579 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'compute_irr';
4580
4581 l_additional_parameters OKL_EXECUTE_FORMULA_PUB.ctxt_val_tbl_type;
4582
4583 l_secdep_sty_id NUMBER;
4584 l_secdep_stream_name VARCHAR2(256);
4585
4586 Cursor c_pass ( khrId NUMBER, cleId NUMBER) IS
4587 select vDtls.DISBURSEMENT_BASIS,
4588 vDtls.DISBURSEMENT_FIXED_AMOUNT,
4589 vDtls.DISBURSEMENT_PERCENT,
4590 vDtls.PROCESSING_FEE_BASIS,
4591 vDtls.PROCESSING_FEE_FIXED_AMOUNT,
4592 vDtls.PROCESSING_FEE_PERCENT
4593 from okl_party_payment_hdr vHdr,
4594 okl_party_payment_dtls vDtls
4595 where vDtls.payment_hdr_id = vHdr.id
4596 and vHdr.CLE_ID = cleId
4597 and vHdr.DNZ_CHR_ID = khrId;
4598
4599 r_pass c_pass%ROWTYPE;
4600
4601 pass_thru_amount NUMBER;
4602 pass_thru_pro_fee NUMBER;
4603
4604 -- Added by RGOOTY
4605 l_prev_irr NUMBER := 0;
4606 l_positive_npv_irr NUMBER := 0;
4607 l_negative_npv_irr NUMBER := 0;
4608 l_positive_npv NUMBER := 0;
4609 l_negative_npv NUMBER := 0;
4610 l_irr_decided VARCHAR2(1) := 'F';
4611
4612 l_day_convention_month VARCHAR2(30);
4613 l_day_convention_year VARCHAR2(30);
4614 l_days_in_year NUMBER;
4615
4616 l_link_yn VARCHAR2(1);
4617
4618 CURSOR top_svc_csr ( chrId NUMBER, linkId NUMBER ) IS
4619 select to_char(kle1.id) top_svc_id,
4620 kle1.amount top_amount,
4621 kle.amount link_amount
4622 from okl_k_lines_full_v kle,
4623 okl_k_lines_full_v kle1,
4624 okc_line_styles_b lse,
4625 okc_statuses_b sts
4626 where KLE1.LSE_ID = LSE.ID
4627 and ((lse.lty_code = 'SOLD_SERVICE') OR (lse.lty_code = 'FEE'and kle1.fee_type ='PASSTHROUGH'))
4628 and kle.dnz_chr_id = chrId
4629 and kle1.dnz_chr_id = kle.dnz_chr_id
4630 and sts.code = kle1.sts_code
4631 and kle.id = linkId
4632 and kle.cle_id = kle1.id
4633 and sts.ste_code not in ('HOLD', 'TERMINATED', 'EXPIRED', 'CANCELLED');
4634
4635 top_svc_rec top_svc_csr%ROWTYPE;
4636 pass_thru_id NUMBER;
4637
4638 BEGIN
4639 IF (G_DEBUG_ENABLED = 'Y') THEN
4640 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
4641 END IF;
4642
4643 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4644 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'begin' );
4645 END IF;
4646 x_return_status := G_RET_STS_SUCCESS;
4647
4648 lx_return_status := G_RET_STS_ERROR;
4649 -- Fetch the day convention ..
4650 OKL_PRICING_UTILS_PVT.get_day_convention(
4651 p_id => p_khr_id,
4652 p_source => 'ISG',
4653 x_days_in_month => l_day_convention_month,
4654 x_days_in_year => l_day_convention_year,
4655 x_return_status => lx_return_status);
4656 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4657 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
4658 END IF;
4659 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
4660 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4661 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
4662 RAISE OKL_API.G_EXCEPTION_ERROR;
4663 END IF;
4664 FOR l_asset_cost IN c_asset_cost LOOP
4665
4666 --Modified IF clause by rgooty for bug 7577105
4667 IF(NVL(l_asset_cost.date_funding_expected, l_asset_cost.start_date) = p_start_date)
4668 THEN
4669 l_cost := nvl(l_asset_cost.capital_amount, 0) + nvl(l_asset_cost.capitalized_interest,0);
4670
4671 l_time_zero_cost := l_time_zero_cost + NVL(l_cost, 0);
4672
4673 -- Added for approximation of IRR
4674 G_TOT_CAP_AMT := G_TOT_CAP_AMT + l_cost;
4675
4676 END IF;
4677 END LOOP;
4678 --print( ' Total Asset Cost ' || G_TOT_CAP_AMT );
4679 -- print( l_prog_name, ' time zero cost ' || l_time_zero_cost );
4680 FOR l_fee_cost IN c_fee_cost LOOP
4681
4682 If l_fee_cost.lty_code = 'LINK_FEE_ASSET' THEN
4683 OPEN c_link_pmnts( p_khr_id, l_fee_cost.kleid);
4684 FETCH c_link_pmnts INTO r_link_pmnts;
4685 CLOSE c_link_pmnts;
4686 ENd If;
4687
4688 If ( l_fee_cost.lty_code <> 'LINK_FEE_ASSET' OR
4689 (l_fee_cost.lty_code = 'LINK_FEE_ASSET' and nvl(r_link_pmnts.What,'N')='Y') ) THen
4690 IF l_fee_cost.start_date <= p_start_date THEN
4691
4692 l_time_zero_cost := l_time_zero_cost + l_fee_cost.amount;
4693
4694 END IF;
4695 END IF;
4696
4697 END LOOP;
4698 -- print( l_prog_name, ' time zero cost | fee cost ' || l_time_zero_cost );
4699
4700 FOR l_hdr_inflow IN c_hdr_inflows LOOP
4701
4702 m := m + 1;
4703 hdr_inflow_tbl(m).cf_amount := l_hdr_inflow.cf_amount;
4704 hdr_inflow_tbl(m).cf_date := l_hdr_inflow.cf_date;
4705 hdr_inflow_tbl(m).cf_purpose := l_hdr_inflow.cf_purpose;
4706 hdr_inflow_tbl(m).cf_dpp := l_hdr_inflow.days_per_period;
4707 hdr_inflow_tbl(m).cf_ppy := l_hdr_inflow.periods_per_year;
4708
4709 hdr_inflow_tbl(m).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
4710 p_days_in_month => l_day_convention_month,
4711 p_days_in_year => l_day_convention_year,
4712 p_end_date => l_hdr_inflow.cf_date,
4713 p_arrears => l_hdr_inflow.cf_arrear,
4714 x_return_status => lx_return_status);
4715
4716 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4717 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4718 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4719 RAISE OKL_API.G_EXCEPTION_ERROR;
4720 END IF;
4721 -- Added for approximation
4722 G_TOT_INFLOW_AMT := G_TOT_INFLOW_AMT + l_hdr_inflow.cf_amount;
4723 --print( 'Header Inflows amount ' || l_hdr_inflow.cf_amount );
4724 END LOOP;
4725
4726 -- print( l_prog_name, ' hdr flows ' || m );
4727
4728 FOR l_inflow IN c_inflows LOOP
4729
4730 If l_inflow.lty_code = 'LINK_FEE_ASSET' THEN
4731 OPEN c_link_pmnts( p_khr_id, l_inflow.kleid);
4732 FETCH c_link_pmnts INTO r_link_pmnts;
4733 CLOSE c_link_pmnts;
4734 ENd If;
4735
4736 If ( l_inflow.lty_code <> 'LINK_FEE_ASSET' OR
4737 (l_inflow.lty_code = 'LINK_FEE_ASSET' and nvl(r_link_pmnts.What,'N')='Y') ) THen
4738
4739 n := n + 1;
4740 inflow_tbl(n).cf_amount := l_inflow.cf_amount;
4741 inflow_tbl(n).cf_date := l_inflow.cf_date;
4742 inflow_tbl(n).cf_purpose := l_inflow.cf_purpose;
4743 inflow_tbl(n).cf_dpp := l_inflow.days_per_period;
4744 inflow_tbl(n).cf_ppy := l_inflow.periods_per_year;
4745
4746 inflow_tbl(n).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
4747 p_days_in_month => l_day_convention_month,
4748 p_days_in_year => l_day_convention_year,
4749 p_end_date => l_inflow.cf_date,
4750 p_arrears => l_inflow.cf_arrear,
4751 x_return_status => lx_return_status);
4752
4753 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4754 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4755 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4756 RAISE OKL_API.G_EXCEPTION_ERROR;
4757 END IF;
4758
4759 END IF;
4760 -- Added for approximation
4761 G_TOT_INFLOW_AMT := G_TOT_INFLOW_AMT + l_inflow.cf_amount;
4762 --print( 'Inflows amount ' || l_inflow.cf_amount);
4763 END LOOP;
4764 --print( 'Total Inflows amount ' || G_TOT_INFLOW_AMT );
4765
4766 -- print( l_prog_name, ' infl flows ' || n );
4767
4768 FOR l_asset_rv IN c_asset_rvs LOOP
4769
4770 p := p + 1;
4771 If l_asset_rv.sts_code = 'TERMINATED' Then
4772 rv_tbl(p).cf_amount := OKL_AM_UTIL_PVT.get_actual_asset_residual(p_khr_id => p_khr_id,
4773 p_kle_id => l_asset_rv.id); --bug# 4184579
4774 rv_tbl(p).cf_date := l_asset_rv.date_terminated;
4775
4776 rv_tbl(p).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
4777 p_days_in_month => l_day_convention_month,
4778 p_days_in_year => l_day_convention_year,
4779 p_end_date => l_asset_rv.date_terminated,
4780 p_arrears => 'Y',
4781 x_return_status => lx_return_status);
4782
4783 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4784 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4785 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4786 RAISE OKL_API.G_EXCEPTION_ERROR;
4787 END IF;
4788
4789 Else
4790 rv_tbl(p).cf_amount := l_asset_rv.cf_amount;
4791 rv_tbl(p).cf_date := l_end_date;
4792
4793 rv_tbl(p).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
4794 p_days_in_month => l_day_convention_month,
4795 p_days_in_year => l_day_convention_year,
4796 p_end_date => l_end_date,
4797 p_arrears => 'Y',
4798 x_return_status => lx_return_status);
4799
4800 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4801 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4802 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4803 RAISE OKL_API.G_EXCEPTION_ERROR;
4804 END IF;
4805
4806 End If;
4807
4808 rv_tbl(p).cf_dpp := l_asset_rv.days_per_period;
4809 rv_tbl(p).cf_ppy := l_asset_rv.periods_per_year;
4810
4811 -- Added for approximation
4812 G_TOT_RV_AMT := G_TOT_RV_AMT + rv_tbl(p).cf_amount;
4813 --print( 'Residual Value amount ' || rv_tbl(p).cf_amount);
4814 END LOOP;
4815 --print( 'Total Inflows amount ' || G_TOT_RV_AMT );
4816
4817 -- print( l_prog_name, ' asset rvs ' || p );
4818
4819 FOR l_outflow IN c_fee_cost LOOP
4820
4821 IF l_outflow.start_date > p_start_date THEN
4822
4823 q := q + 1;
4824 outflow_tbl(q).cf_amount := -(l_outflow.amount);
4825 outflow_tbl(q).cf_date := l_outflow.start_date;
4826 outflow_tbl(q).cf_dpp := 1;
4827 outflow_tbl(q).cf_ppy := 360;
4828
4829 outflow_tbl(q).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
4830 p_days_in_month => l_day_convention_month,
4831 p_days_in_year => l_day_convention_year,
4832 p_end_date => l_outflow.start_date,
4833 p_arrears => 'N',
4834 x_return_status => lx_return_status);
4835
4836 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4837 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4838 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4839 RAISE OKL_API.G_EXCEPTION_ERROR;
4840 END IF;
4841
4842 END IF;
4843
4844 END LOOP;
4845 -- print( l_prog_name, ' out flows ' || q );
4846
4847 If ( p_subsidies_yn = 'Y' ) Then
4848 subsidies_tbl(1).cf_amount := 0;
4849 End If;
4850
4851 FOR l_outflow IN c_asset_cost LOOP
4852 -- Handling the case when contract rebooking has happened and an asset has been
4853 -- added after the start date of the contract but whose funding starts on the revision date.
4854 --Modified IF clause by rgooty for bug 7577105
4855 IF NVL(l_outflow.date_funding_expected, l_outflow.start_date) > p_start_date
4856 THEN
4857 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4858 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '!!! Handling the Assets who are in effect later than the start date !!!');
4859 END IF;
4860 q := q + 1;
4861 outflow_tbl(q).cf_amount := nvl(l_outflow.capital_amount, 0);
4862 outflow_tbl(q).cf_amount := -(outflow_tbl(q).cf_amount);
4863 outflow_tbl(q).cf_date := nvl(l_outflow.date_funding_expected, l_outflow.start_date);
4864 outflow_tbl(q).cf_dpp := l_outflow.days_per_period;
4865 outflow_tbl(q).cf_ppy := l_outflow.periods_per_year;
4866 outflow_tbl(q).cf_days :=
4867 OKL_PRICING_UTILS_PVT.get_day_count(
4868 p_start_date => p_start_date,
4869 p_days_in_month => l_day_convention_month,
4870 p_days_in_year => l_day_convention_year,
4871 p_end_date => outflow_tbl(q).cf_date,
4872 p_arrears => 'N',
4873 x_return_status => lx_return_status);
4874 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4875 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4876 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4877 RAISE OKL_API.G_EXCEPTION_ERROR;
4878 END IF;
4879 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4880 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || outflow_tbl(q).cf_date || '| ' || outflow_tbl(q).cf_days || ' | ' ||
4881 outflow_tbl(q).cf_amount ||' | ' || outflow_tbl(q).cf_dpp || ' | ' || outflow_tbl(q).cf_ppy );
4882 END IF;
4883 ELSIF l_outflow.date_funding_expected < p_start_date THEN
4884 --Removed = in the above if clause by RGOOTY for bug 7577105
4885 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4886 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '!!!!! Handling the Assets who are in effect earlier than the start date !!!!');
4887 END IF;
4888 q := q + 1;
4889 outflow_tbl(q).cf_amount := nvl(l_outflow.capital_amount, 0);
4890 outflow_tbl(q).cf_amount := -(outflow_tbl(q).cf_amount);
4891 outflow_tbl(q).cf_date := l_outflow.date_funding_expected;
4892 outflow_tbl(q).cf_dpp := l_outflow.days_per_period;
4893 outflow_tbl(q).cf_ppy := l_outflow.periods_per_year;
4894 outflow_tbl(q).cf_days :=
4895 OKL_PRICING_UTILS_PVT.get_day_count(
4896 p_start_date => l_outflow.date_funding_expected,
4897 p_days_in_month => l_day_convention_month,
4898 p_days_in_year => l_day_convention_year,
4899 p_end_date => p_start_date,
4900 p_arrears => 'N',
4901 x_return_status => lx_return_status);
4902 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4903 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4904 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4905 RAISE OKL_API.G_EXCEPTION_ERROR;
4906 END IF;
4907 outflow_tbl(q).cf_days := -1 * outflow_tbl(q).cf_days;
4908 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4909 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || outflow_tbl(q).cf_date || '| ' || outflow_tbl(q).cf_days || ' | ' ||
4910 outflow_tbl(q).cf_amount ||' | ' || outflow_tbl(q).cf_dpp || ' | ' || outflow_tbl(q).cf_ppy );
4911 END IF;
4912 END IF;
4913
4914 If ( p_subsidies_yn = 'Y' ) Then
4915 -- Subsidies Begin
4916 OKL_SUBSIDY_PROCESS_PVT.get_asset_subsidy_amount(
4917 p_api_version => G_API_VERSION,
4918 p_init_msg_list => G_FALSE,
4919 x_return_status => lx_return_status,
4920 x_msg_data => lx_msg_data,
4921 x_msg_count => lx_msg_count,
4922 p_asset_cle_id => l_outflow.id,
4923 x_subsidy_amount=> l_subsidy_amount);
4924
4925 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4926 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4927 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4928 RAISE OKL_API.G_EXCEPTION_ERROR;
4929 END IF;
4930
4931 subsidies_tbl(1).cf_amount := nvl(subsidies_tbl(1).cf_amount, 0) + nvl(l_subsidy_amount,0);
4932
4933 End If;
4934
4935 END LOOP;
4936
4937 If ( p_subsidies_yn = 'Y' ) Then
4938
4939 subsidies_tbl(1).cf_date := p_start_date;
4940 subsidies_tbl(1).cf_dpp := 1;
4941 subsidies_tbl(1).cf_ppy := 360;
4942
4943 subsidies_tbl(1).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
4944 p_days_in_month => l_day_convention_month,
4945 p_days_in_year => l_day_convention_year,
4946 p_end_date => p_start_date,
4947 p_arrears => 'N',
4948 x_return_status => lx_return_status);
4949
4950 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
4951 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
4952 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
4953 RAISE OKL_API.G_EXCEPTION_ERROR;
4954 END IF;
4955 -- Subsidies End
4956
4957 End if;
4958
4959
4960 FOR l_pass_th IN c_pass_th LOOP
4961
4962 r := r + 1;
4963
4964 l_link_yn := 'N';
4965 OPEN top_svc_csr( p_khr_id, l_pass_th.cleId );
4966 FETCH top_svc_csr INTO top_svc_rec;
4967 If ( top_svc_csr%FOUND ) Then
4968 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4969 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' found top svc line ' || to_char( l_pass_th.cleId ));
4970 END IF;
4971 pass_thru_id := top_svc_rec.top_svc_id;
4972 l_link_yn := 'Y';
4973 Else
4974 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
4975 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' not found top svc line ' || to_char( l_pass_th.cleId ));
4976 END IF;
4977 l_link_yn := 'N';
4978 pass_thru_id := l_pass_th.cleId;
4979 End If;
4980 CLOSE top_svc_csr;
4981
4982 pass_thru_amount := 0;
4983 pass_thru_pro_fee := 0;
4984
4985 -- RGOOTY: 9218201: Start
4986 For r_pass in c_pass( p_khr_id, pass_thru_id )
4987 LOOP
4988
4989 If ( r_pass.disbursement_basis = 'PERCENT' ) Then
4990 pass_thru_amount := pass_thru_amount +
4991 NVL( l_pass_th.cf_amount*(r_pass.disbursement_percent/100), 0);
4992 Else
4993 If (l_link_yn = 'Y') Then
4994 pass_thru_amount := pass_thru_amount +
4995 NVL( (r_pass.disbursement_fixed_amount*top_svc_rec.link_amount)/top_svc_rec.top_amount, 0);
4996 Else
4997 pass_thru_amount := pass_thru_amount +
4998 NVL(r_pass.disbursement_fixed_amount, 0);
4999 End If;
5000 End If;
5001
5002 --If ( r_pass.INCLUDE_IN_YIELD_FLAG = 'Y' ) Then -- Always equal to 'Y'
5003 If ( r_pass.processing_fee_basis = 'PERCENT') Then
5004 pass_thru_pro_fee := pass_thru_pro_fee +
5005 NVL( l_pass_th.cf_amount*(r_pass.processing_fee_percent/100), 0);
5006 Else
5007 If (l_link_yn = 'Y') Then
5008 pass_thru_pro_fee := pass_thru_pro_fee +
5009 NVL( (r_pass.processing_fee_fixed_amount*top_svc_rec.link_amount)/top_svc_rec.top_amount, 0);
5010 Else
5011 pass_thru_pro_fee := pass_thru_pro_fee +
5012 NVL( r_pass.processing_fee_fixed_amount, 0);
5013 End If;
5014 End If;
5015 --End If;
5016
5017 END LOOP;
5018 -- RGOOTY: 9218201: End
5019
5020 pass_th_tbl(r).cf_amount := l_pass_th.cf_amount - pass_thru_amount + pass_thru_pro_fee;
5021 pass_th_tbl(r).cf_date := l_pass_th.cf_date;
5022 pass_th_tbl(r).cf_purpose := l_pass_th.cf_purpose;
5023 pass_th_tbl(r).cf_dpp := l_pass_th.days_per_period;
5024 pass_th_tbl(r).cf_ppy := l_pass_th.periods_per_year;
5025
5026 pass_th_tbl(r).cf_days :=OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
5027 p_days_in_month => l_day_convention_month,
5028 p_days_in_year => l_day_convention_year,
5029 p_end_date => l_pass_th.cf_date,
5030 p_arrears => l_pass_th.cf_arrear,
5031 x_return_status => lx_return_status);
5032
5033 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
5034 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5035 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
5036 RAISE OKL_API.G_EXCEPTION_ERROR;
5037 END IF;
5038
5039 END LOOP;
5040 -- print( l_prog_name, ' pass thru ' || r );
5041
5042 FOR l_rec_exp IN c_rec_exp LOOP
5043
5044 FOR s1 in 1..l_rec_exp.periods LOOP
5045
5046 s := s + 1;
5047
5048 rec_exp_tbl(s).cf_amount := -(l_rec_exp.cf_amount);
5049 rec_exp_tbl(s).cf_date := ADD_MONTHS(l_rec_exp.start_date, (s1 -1)*l_rec_exp.cf_mpp);
5050 rec_exp_tbl(s).cf_dpp := l_rec_exp.cf_dpp;
5051 rec_exp_tbl(s).cf_ppy := l_rec_exp.cf_ppy;
5052
5053 rec_exp_tbl(s).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
5054 p_days_in_month => l_day_convention_month,
5055 p_days_in_year => l_day_convention_year,
5056 p_end_date => rec_exp_tbl(s).cf_date,
5057 p_arrears => 'N',
5058 x_return_status => lx_return_status);
5059
5060 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
5061 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5062 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
5063 RAISE OKL_API.G_EXCEPTION_ERROR;
5064 END IF;
5065
5066 END LOOP;
5067
5068 END LOOP;
5069 -- print( l_prog_name, ' recu exp ' || s );
5070
5071 IF m > 0 THEN
5072 FOR m1 IN 1..hdr_inflow_tbl.COUNT LOOP
5073 IF hdr_inflow_tbl(m1).cf_date <= p_start_date THEN
5074 l_adv_payment := l_adv_payment + hdr_inflow_tbl(m1).cf_amount;
5075 -- print( l_prog_name, hdr_inflow_tbl(m1).cf_date || ':::' || p_start_date || ':::' || l_adv_payment);
5076 END IF;
5077 END LOOP;
5078 END IF;
5079
5080 IF n > 0 THEN
5081 FOR n1 IN 1..inflow_tbl.COUNT LOOP
5082 IF inflow_tbl(n1).cf_date <= p_start_date THEN
5083 l_adv_payment := l_adv_payment + inflow_tbl(n1).cf_amount;
5084 -- print( l_prog_name, inflow_tbl(n1).cf_date || ':::' || p_start_date || ':::' || l_adv_payment);
5085 END IF;
5086 END LOOP;
5087 END IF;
5088
5089 IF r > 0 THEN
5090 FOR r1 IN 1..pass_th_tbl.COUNT LOOP
5091 IF pass_th_tbl(r1).cf_date <= p_start_date THEN
5092 l_adv_payment := l_adv_payment + pass_th_tbl(r1).cf_amount;
5093 -- print( l_prog_name, pass_th_tbl(r1).cf_date || ':::' || p_start_date || ':::' || l_adv_payment);
5094 END IF;
5095 END LOOP;
5096 END IF;
5097
5098 -- print( l_prog_name, 'TIME ZERO OUTFLOW '||l_time_zero_cost);
5099 -- print( l_prog_name, 'INFLOWS ON OR BEFORE TIME ZERO '||l_adv_payment);
5100
5101 --Commented by RGOOTY for bug 7577105
5102 /*
5103 IF l_adv_payment >= l_time_zero_cost THEN
5104
5105 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5106 p_msg_name => 'OKL_IRR_CALC_INF_LOOP',
5107 p_token1 => 'ADV_AMOUNT',
5108 p_token1_value => l_adv_payment,
5109 p_token2 => 'CAPITAL_AMOUNT',
5110 p_token2_value => l_time_zero_cost);
5111
5112 RAISE OKL_API.G_EXCEPTION_ERROR;
5113
5114 END IF; */
5115
5116 SELECT currency_code
5117 INTO l_currency_code
5118 FROM okc_k_headers_b
5119 WHERE id = p_khr_id;
5120
5121 SELECT NVL(precision,0)
5122 INTO l_precision
5123 FROM fnd_currencies
5124 WHERE currency_code = l_currency_code;
5125
5126
5127 l_precision := 4;
5128
5129 l_irr_limit := ROUND(NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000), 0)/100;
5130
5131
5132 -- Added for IRR Approximation
5133 -- Appr. IRR based on Simple Interest Calculation
5134 IF ( G_TOT_CAP_AMT <> G_TOT_RV_AMT )
5135 THEN
5136 l_irr := ( G_TOT_INFLOW_AMT + G_TOT_RV_AMT - G_TOT_CAP_AMT )
5137 / ( G_TOT_CAP_AMT - G_TOT_RV_AMT );
5138 ELSE
5139 l_irr := 0;
5140 END IF;
5141 /*
5142 print( 'G_TOT_INFLOW_AMT ' || G_TOT_INFLOW_AMT );
5143 print( 'G_TOT_RV_AMT ' || G_TOT_RV_AMT );
5144 print( 'G_TOT_CAP_AMT ' || G_TOT_CAP_AMT );
5145 print( 'Approximated IRR' || l_irr );
5146 print( 'IRR Passing actually ' || l_irr);
5147 */
5148 LOOP
5149
5150 i := i + 1;
5151 l_npv := -(l_time_zero_cost);
5152 l_deposit_date := NULL;
5153
5154 /*
5155 print( l_prog_name, ' PRECISION ' || nvl(l_precision, 0) || ' time cost ' || nvl(l_npv,0) );
5156 --DEBUG
5157 print( l_prog_name, ' ');
5158 print( l_prog_name, 'ITERATION # '||i||' IRR Guess '||l_irr*100||' Time Zero is '
5159 ||TO_CHAR(p_start_date, 'DD-MON-YYYY'));
5160 print( l_prog_name,' ');
5161 */
5162
5163 -------------------------------------------
5164 -- INTERIM INTEREST INFLOWS
5165 -------------------------------------------
5166
5167 IF p_interim_tbl.COUNT > 0 THEN
5168 /*
5169 print( l_prog_name,'INTERIM INTEREST INFLOWS ...');
5170 print( l_prog_name,'');
5171 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
5172 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
5173 print( l_prog_name, '');
5174 */
5175 --DEBUG
5176 a :=0;
5177 FOR l_temp IN p_interim_tbl.FIRST .. p_interim_tbl.LAST LOOP
5178 --DEBUG
5179 a := a+1;
5180 l_cf_dpp := p_interim_tbl(l_temp).cf_dpp;
5181
5182 IF l_cf_dpp = 30 THEN
5183 l_cf_ppy := 12;
5184 ELSIF l_cf_dpp = 90 THEN
5185 l_cf_ppy := 4;
5186 ELSIF l_cf_dpp = 180 THEN
5187 l_cf_ppy := 2;
5188 ELSIF l_cf_dpp = 360 THEN
5189 l_cf_ppy := 1;
5190 END IF;
5191
5192 l_cf_amount := p_interim_tbl(l_temp).cf_amount;
5193 l_days_in_future := p_interim_tbl(l_temp).cf_days;
5194
5195 l_periods := l_days_in_future / l_cf_dpp;
5196
5197 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5198
5199 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5200 p_msg_name => 'OKL_IRR_ZERO_DIV');
5201
5202 RAISE OKL_API.G_EXCEPTION_ERROR;
5203
5204 END IF;
5205
5206 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5207
5208 /*
5209 print( l_prog_name, TO_CHAR(a, '99')||' '||'NOT AVAILAB'||' '||TO_CHAR(l_days_in_future, '9999')
5210 ||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5211 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
5212 */
5213 END LOOP;
5214
5215 END IF;
5216
5217 -------------------------------------------
5218 -- FEE COST CASH OUTFLOWS
5219 -------------------------------------------
5220
5221 IF q > 0 THEN
5222 /*
5223 print( l_prog_name, 'FEE COST CASHFLOWS ...');
5224 print( l_prog_name, '');
5225 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
5226 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
5227 print( l_prog_name, '');
5228 */
5229 --DEBUG
5230 a :=0;
5231 FOR w IN 1..outflow_tbl.COUNT LOOP
5232 --DEBUG
5233 a := a+1;
5234 l_cf_dpp := outflow_tbl(w).cf_dpp;
5235 l_cf_ppy := outflow_tbl(w).cf_ppy;
5236 l_cf_amount := outflow_tbl(w).cf_amount;
5237 l_cf_date := outflow_tbl(w).cf_date;
5238 l_days_in_future := outflow_tbl(w).cf_days;
5239
5240 l_periods := l_days_in_future / l_cf_dpp;
5241
5242 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5243
5244 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5245 p_msg_name => 'OKL_IRR_ZERO_DIV');
5246
5247 RAISE OKL_API.G_EXCEPTION_ERROR;
5248
5249 END IF;
5250
5251 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5252
5253 /*
5254 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5255 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
5256 */
5257
5258 END LOOP;
5259
5260 END IF;
5261
5262
5263 -------------------------------------------
5264 -- PASSTHROUGH CASH INFLOWS
5265 -------------------------------------------
5266
5267 IF r > 0 THEN
5268 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
5269 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'PASSTHROUGH CASH INFLOWS ...');
5270 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '');
5271 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
5272 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
5273 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '');
5274 END IF;
5275 --DEBUG
5276 a :=0;
5277 FOR v IN 1..pass_th_tbl.COUNT LOOP
5278 --DEBUG
5279 a := a+1;
5280 l_cf_dpp := pass_th_tbl(v).cf_dpp;
5281 l_cf_ppy := pass_th_tbl(v).cf_ppy;
5282 l_cf_amount := pass_th_tbl(v).cf_amount;
5283 l_cf_date := pass_th_tbl(v).cf_date;
5284 l_days_in_future := pass_th_tbl(v).cf_days;
5285
5286 l_periods := l_days_in_future / l_cf_dpp;
5287
5288 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5289
5290 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5291 p_msg_name => 'OKL_IRR_ZERO_DIV');
5292
5293 RAISE OKL_API.G_EXCEPTION_ERROR;
5294
5295 END IF;
5296
5297 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5298
5299 /*
5300 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5301 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
5302 */
5303
5304 END LOOP;
5305
5306 END IF;
5307
5308
5309 -------------------------------------------
5310 -- FEE RECURRING EXPENSE CASH OUTFLOWS
5311 -------------------------------------------
5312
5313 IF s > 0 THEN
5314 /*
5315 print( l_prog_name, 'FEE RECURRING EXPENSE CASH OUTFLOWS ...');
5316 print( l_prog_name, '');
5317 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
5318 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
5319 print( l_prog_name, '');
5320 */
5321 --DEBUG
5322 a :=0;
5323 FOR t IN 1..rec_exp_tbl.COUNT LOOP
5324 --DEBUG
5325 a := a+1;
5326 l_cf_ppy := rec_exp_tbl(t).cf_ppy;
5327 l_cf_dpp := rec_exp_tbl(t).cf_dpp;
5328 l_cf_amount := rec_exp_tbl(t).cf_amount;
5329 l_cf_date := rec_exp_tbl(t).cf_date;
5330 l_days_in_future := rec_exp_tbl(t).cf_days;
5331
5332 l_periods := l_days_in_future / l_cf_dpp;
5333
5334 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5335
5336 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5337 p_msg_name => 'OKL_IRR_ZERO_DIV');
5338
5339 RAISE OKL_API.G_EXCEPTION_ERROR;
5340
5341 END IF;
5342
5343 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5344
5345 /*
5346 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5347 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
5348 */
5349
5350 END LOOP;
5351
5352 END IF;
5353
5354 -------------------------------------------
5355 -- HEADER LEVEL CASH INFLOWS
5356 -------------------------------------------
5357
5358 IF m > 0 THEN
5359 /*
5360 print( l_prog_name, 'K LEVEL CASH INFLOWS ...');
5361 print( l_prog_name, '');
5362 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
5363 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
5364 print( l_prog_name, '');
5365 */
5366 --DEBUG
5367 a :=0;
5368 FOR x IN 1..hdr_inflow_tbl.COUNT LOOP
5369 --DEBUG
5370 a := a+1;
5371 l_cf_dpp := hdr_inflow_tbl(x).cf_dpp;
5372 l_cf_ppy := hdr_inflow_tbl(x).cf_ppy;
5373 l_cf_amount := hdr_inflow_tbl(x).cf_amount;
5374 l_cf_date := hdr_inflow_tbl(x).cf_date;
5375 l_days_in_future := hdr_inflow_tbl(x).cf_days;
5376
5377 l_periods := l_days_in_future / l_cf_dpp;
5378
5379 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5380
5381 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5382 p_msg_name => 'OKL_IRR_ZERO_DIV');
5383
5384 RAISE OKL_API.G_EXCEPTION_ERROR;
5385
5386 END IF;
5387
5388 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5389
5390 /*
5391 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '99.999')||
5392 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '99.990'));
5393 */
5394
5395 -- Security Deposit is both an inflow as well as an outflow
5396
5397 IF hdr_inflow_tbl(x).cf_purpose = 'SECURITY_DEPOSIT' THEN
5398
5399 OPEN c_deposit_date;
5400 FETCH c_deposit_date INTO l_deposit_date;
5401 CLOSE c_deposit_date;
5402
5403 IF l_deposit_date IS NOT NULL THEN
5404
5405 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
5406 p_days_in_month => l_day_convention_month,
5407 p_days_in_year => l_day_convention_year,
5408 p_end_date => l_deposit_date,
5409 p_arrears => l_cf_arrear,
5410 x_return_status => lx_return_status);
5411
5412 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
5413 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5414 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
5415 RAISE OKL_API.G_EXCEPTION_ERROR;
5416 END IF;
5417
5418 ELSE
5419
5420 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
5421 p_days_in_month => l_day_convention_month,
5422 p_days_in_year => l_day_convention_year,
5423 p_end_date => l_end_date,
5424 p_arrears => l_cf_arrear,
5425 x_return_status => lx_return_status);
5426
5427 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
5428 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5429 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
5430 RAISE OKL_API.G_EXCEPTION_ERROR;
5431 END IF;
5432
5433 END IF;
5434
5435 l_periods := l_days_in_future / l_cf_dpp;
5436 l_npv := l_npv - (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5437
5438 END IF;
5439
5440 l_deposit_date := NULL;
5441
5442 END LOOP;
5443
5444 END IF;
5445
5446 -------------------------------------------
5447 -- LINE LEVEL CASH INFLOWS
5448 -------------------------------------------
5449
5450 IF n > 0 THEN
5451 /*
5452 print( l_prog_name, 'LINE LEVEL CASH INFLOWS ...');
5453 print( l_prog_name, '');
5454 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
5455 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
5456 print( l_prog_name, '');
5457 */
5458 --DEBUG
5459 a :=0;
5460 FOR y IN 1..inflow_tbl.COUNT LOOP
5461 --DEBUG
5462 a := a+1;
5463 l_cf_dpp := inflow_tbl(y).cf_dpp;
5464 l_cf_ppy := inflow_tbl(y).cf_ppy;
5465 l_cf_amount := inflow_tbl(y).cf_amount;
5466 l_cf_date := inflow_tbl(y).cf_date;
5467 l_days_in_future := inflow_tbl(y).cf_days;
5468
5469 l_periods := l_days_in_future / l_cf_dpp;
5470
5471 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5472
5473 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5474 p_msg_name => 'OKL_IRR_ZERO_DIV');
5475
5476 RAISE OKL_API.G_EXCEPTION_ERROR;
5477
5478 END IF;
5479
5480
5481 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5482
5483 /*
5484 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5485 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
5486 */
5487
5488 /*print( TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5489 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
5490 */
5491 -- Security Deposit is both an inflow as well as an outflow
5492
5493
5494 IF inflow_tbl(y).cf_purpose = 'SECURITY_DEPOSIT' THEN
5495
5496 OPEN c_deposit_date;
5497 FETCH c_deposit_date INTO l_deposit_date;
5498 CLOSE c_deposit_date;
5499
5500 IF l_deposit_date IS NOT NULL THEN
5501
5502 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
5503 p_days_in_month => l_day_convention_month,
5504 p_days_in_year => l_day_convention_year,
5505 p_end_date => l_deposit_date,
5506 p_arrears => l_cf_arrear,
5507 x_return_status => lx_return_status);
5508
5509 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
5510 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5511 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
5512 RAISE OKL_API.G_EXCEPTION_ERROR;
5513 END IF;
5514
5515 ELSE
5516
5517 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
5518 p_days_in_month => l_day_convention_month,
5519 p_days_in_year => l_day_convention_year,
5520 p_end_date => l_end_date,
5521 p_arrears => l_cf_arrear,
5522 x_return_status => lx_return_status);
5523
5524 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
5525 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5526 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
5527 RAISE OKL_API.G_EXCEPTION_ERROR;
5528 END IF;
5529
5530 END IF;
5531
5532 l_periods := l_days_in_future / l_cf_dpp;
5533 l_npv := l_npv - (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5534
5535 END IF;
5536
5537 l_deposit_date := NULL;
5538
5539 END LOOP;
5540
5541 END IF;
5542
5543 -------------------------------------------
5544 -- RV CASH INFLOWS
5545 -------------------------------------------
5546
5547 IF p > 0 THEN
5548 /*
5549 print( l_prog_name,'RV CASH INFLOWS ...');
5550 print( l_prog_name, '');
5551 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
5552 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
5553 print( l_prog_name, '');
5554 */
5555 --DEBUG
5556 a :=0;
5557 FOR z IN 1..rv_tbl.COUNT LOOP
5558 --DEBUG
5559 a := a+1;
5560 l_cf_dpp := rv_tbl(z).cf_dpp;
5561 l_cf_ppy := rv_tbl(z).cf_ppy;
5562 l_cf_amount := rv_tbl(z).cf_amount;
5563 l_cf_date := rv_tbl(z).cf_date;
5564 l_days_in_future := rv_tbl(z).cf_days;
5565
5566 l_periods := l_days_in_future / l_cf_dpp;
5567
5568 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5569
5570 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5571 p_msg_name => 'OKL_IRR_ZERO_DIV');
5572
5573 RAISE OKL_API.G_EXCEPTION_ERROR;
5574
5575 END IF;
5576
5577 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5578
5579 /*
5580 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5581 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '99.990'));
5582 */
5583
5584 END LOOP;
5585
5586 END IF;
5587
5588 -- SUBSIDIES
5589 FOR y IN 1..subsidies_tbl.COUNT
5590 LOOP
5591
5592 l_cf_dpp := subsidies_tbl(y).cf_dpp;
5593 l_cf_ppy := subsidies_tbl(y).cf_ppy;
5594 l_cf_amount := subsidies_tbl(y).cf_amount;
5595 l_cf_date := subsidies_tbl(y).cf_date;
5596 l_days_in_future := subsidies_tbl(y).cf_days;
5597
5598 l_periods := l_days_in_future / l_cf_dpp;
5599
5600 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
5601
5602 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5603 p_msg_name => 'OKL_IRR_ZERO_DIV');
5604
5605 RAISE OKL_API.G_EXCEPTION_ERROR;
5606
5607 END IF;
5608
5609 l_npv := l_npv + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
5610
5611 /*
5612 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
5613 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
5614 */
5615
5616 END LOOP;
5617 -- SUBSIDIES
5618
5619 -- print( l_prog_name, 'NPV '||L_NPV);
5620
5621 IF ROUND(l_npv, l_precision+1) = 0 THEN
5622
5623 x_irr := l_irr; -- LLA API multiples by 100 before updating KHR implicit_interest_rate column
5624 RETURN;
5625
5626 END IF;
5627
5628
5629 IF i > 1 and SIGN(l_npv) <> SIGN(l_prev_npv) AND l_crossed_zero = 'N' THEN
5630
5631 l_crossed_zero := 'Y';
5632 IF ( sign( l_npv) = 1 ) then
5633 l_positive_npv := l_npv;
5634 l_negative_npv := l_prev_npv;
5635 l_positive_npv_irr := l_irr;
5636 l_negative_npv_irr := l_prev_irr;
5637 ELSE
5638 l_positive_npv := l_prev_npv;
5639 l_negative_npv := l_npv;
5640 l_positive_npv_irr := l_prev_irr;
5641 l_negative_npv_irr := l_irr;
5642 END IF;
5643
5644 END IF;
5645
5646 IF( sign(l_npv) = 1) THEN
5647 l_positive_npv := l_npv;
5648 l_positive_npv_irr := l_irr;
5649 ELSE
5650 l_negative_npv := l_npv;
5651 l_negative_npv_irr := l_irr;
5652 END IF;
5653
5654 IF l_crossed_zero = 'Y' THEN
5655 -- Means First time we have got two opposite signed
5656 IF i > 1 then
5657 l_abs_incr := abs(( l_positive_npv_irr - l_negative_npv_irr )
5658 / ( l_positive_npv - l_negative_npv ) * l_positive_npv) ;
5659 IF ( l_positive_npv_irr < l_negative_npv_irr ) THEN
5660 l_irr := l_positive_npv_irr + l_abs_incr;
5661 ELSE
5662 l_irr := l_positive_npv_irr - l_abs_incr;
5663
5664 END IF;
5665 l_irr_decided := 'T';
5666 else
5667 l_abs_incr := ABS(l_increment) / 2;
5668 END IF;
5669
5670 ELSE
5671
5672 l_abs_incr := ABS(l_increment);
5673
5674 END IF;
5675
5676 IF i > 1 THEN
5677
5678 IF SIGN(l_npv) <> l_prev_npv_sign THEN
5679
5680 IF l_prev_incr_sign = 1 THEN
5681
5682 l_increment := - l_abs_incr;
5683
5684 ELSE
5685
5686 l_increment := l_abs_incr;
5687
5688 END IF;
5689
5690 ELSE
5691
5692 IF l_prev_incr_sign = 1 THEN
5693
5694 l_increment := l_abs_incr;
5695
5696 ELSE
5697
5698 l_increment := - l_abs_incr;
5699
5700 END IF;
5701
5702 END IF;
5703
5704 ELSE -- i = 1
5705
5706 IF SIGN(l_npv) = -1 THEN
5707
5708 l_increment := - l_increment;
5709
5710 END IF;
5711
5712 END IF;
5713
5714
5715 -- Added by RGOOTY: Start
5716 l_prev_irr := l_irr;
5717
5718 IF l_irr_decided = 'F'
5719 THEN
5720 l_irr := l_irr + l_increment;
5721 ELSE
5722 l_irr_decided := 'F';
5723 END IF;
5724
5725
5726 /*
5727 print( i || '-Loop l_npv ' || l_npv );
5728 print( i || '-Loop l_increment ' || l_increment );
5729 print( i || '-Loop irr ' || l_irr );
5730 */
5731
5732 IF ABS(l_irr) > l_irr_limit THEN
5733
5734 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5735 p_msg_name => 'OKL_IRR_CALC_IRR_LIMIT',
5736 p_token1 => 'IRR_LIMIT',
5737 p_token1_value => l_irr_limit*100);
5738
5739 RAISE OKL_API.G_EXCEPTION_ERROR;
5740
5741 END IF;
5742
5743 l_prev_incr_sign := SIGN(l_increment);
5744 l_prev_npv_sign := SIGN(l_npv);
5745 l_prev_npv := l_npv;
5746
5747
5748 END LOOP;
5749 -- print( l_prog_name, 'end' );
5750
5751 EXCEPTION
5752
5753 WHEN OKL_API.G_EXCEPTION_ERROR THEN
5754
5755 x_return_status := G_RET_STS_ERROR;
5756
5757 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
5758
5759 x_return_status := G_RET_STS_UNEXP_ERROR;
5760
5761 WHEN OTHERS THEN
5762
5763 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
5764 p_msg_name => G_DB_ERROR,
5765 p_token1 => G_PROG_NAME_TOKEN,
5766 p_token1_value => l_prog_name,
5767 p_token2 => G_SQLCODE_TOKEN,
5768 p_token2_value => sqlcode,
5769 p_token3 => G_SQLERRM_TOKEN,
5770 p_token3_value => sqlerrm);
5771
5772 x_return_status := G_RET_STS_UNEXP_ERROR;
5773
5774 END compute_irr;
5775
5776 ---------------------------------------------------------------------------
5777 -- PROCEDURE target_pay_down
5778 --
5779 -- Description
5780 -- Populates Stream Element arrays with loan specific streams
5781 ---------------------------------------------------------------------------
5782 -- bug 2992184. Added p_purpose_code parameter.
5783 PROCEDURE target_pay_down (
5784 p_khr_id IN NUMBER,
5785 p_ppd_date IN DATE,
5786 p_ppd_amount IN NUMBER,
5787 p_iir IN NUMBER,
5788 x_payment_amount OUT NOCOPY NUMBER,
5789 x_msg_count OUT NOCOPY NUMBER,
5790 x_msg_data OUT NOCOPY VARCHAR2,
5791 x_return_status OUT NOCOPY VARCHAR2) IS
5792
5793 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'target_pay_down';
5794
5795 begin
5796
5797 NULL;
5798 end target_pay_down;
5799
5800
5801 ---------------------------------------------------------------------------
5802 -- PROCEDURE target_pay_down
5803 --
5804 -- Description
5805 -- Populates Stream Element arrays with loan specific streams
5806 ---------------------------------------------------------------------------
5807 -- bug 2992184. Added p_purpose_code parameter.
5808 PROCEDURE target_pay_down (
5809 p_khr_id IN NUMBER,
5810 p_kle_id IN NUMBER,
5811 p_ppd_date IN DATE,
5812 p_ppd_amount IN NUMBER,
5813 p_iir IN NUMBER,
5814 x_payment_amount OUT NOCOPY NUMBER,
5815 x_msg_count OUT NOCOPY NUMBER,
5816 x_msg_data OUT NOCOPY VARCHAR2,
5817 x_return_status OUT NOCOPY VARCHAR2) IS
5818
5819 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'target_pay_down';
5820
5821
5822 CURSOR c_hdr IS
5823 SELECT chr.template_yn,
5824 chr.currency_code,
5825 chr.start_date,
5826 chr.end_date,
5827 khr.deal_type,
5828 khr.term_duration,
5829 NVL(khr.generate_accrual_yn, 'Y')
5830 FROM okc_k_headers_b chr,
5831 okl_k_headers khr
5832 WHERE khr.id = p_khr_id
5833 AND chr.id = khr.id;
5834
5835 l_hdr c_hdr%ROWTYPE;
5836
5837 CURSOR c_rent_slls IS
5838 SELECT FND_DATE.canonical_to_date(sll.rule_information2) start_date,
5839 TO_NUMBER(SLL.rule_information3) periods,
5840 DECODE(sll.object1_id1, 'M', 30, 'Q', 120, 'S', 180, 'A', 360) dpp,
5841 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) mpp,
5842 NVL(sll.rule_information10, 'N') arrears_yn,
5843 FND_NUMBER.canonical_to_number(sll.rule_information6) rent_amount
5844 FROM okc_rules_b sll,
5845 okc_rules_b slh,
5846 okc_rule_groups_b rgp,
5847 okl_strm_type_b sty
5848 WHERE rgp.dnz_chr_id = p_khr_id
5849 AND rgp.cle_id = p_kle_id
5850 AND rgp.rgd_code= 'LALEVL'
5851 AND rgp.id = slh.rgp_id
5852 AND slh.rule_information_category = 'LASLH'
5853 AND TO_NUMBER(slh.object1_id1) = sty.id
5854 AND sty.version = '1.0'
5855 AND sty.stream_type_purpose = 'RENT'
5856 AND TO_CHAR(slh.id) = sll.object2_id1
5857 AND sll.rule_information_category = 'LASLL'
5858 ORDER BY fnd_date.canonical_to_date(sll.rule_information2);
5859
5860 l_rent_sll c_rent_slls%ROWTYPE;
5861
5862 -- bug 2992184. Added where condition for multi-gaap reporting streams.
5863 CURSOR c_rent_flows IS
5864 SELECT sel.id se_id,
5865 sel.amount se_amount,
5866 sel.stream_element_date se_date,
5867 sel.comments se_arrears
5868 FROM okl_strm_elements sel,
5869 okl_streams stm,
5870 okl_strm_type_b sty
5871 WHERE stm.kle_id = p_kle_id
5872 AND stm.say_code = 'CURR'
5873 AND stm.active_yn = 'Y'
5874 AND stm.purpose_code IS NULL
5875 AND stm.sty_id = sty.id
5876 AND sty.version = '1.0'
5877 AND sty.stream_type_purpose = 'RENT' --'LOAN PAYMENT'
5878 AND stm.id = sel.stm_id
5879 ORDER BY sel.stream_element_date;
5880
5881 CURSOR c_kle IS
5882 select kle.id,
5883 kle.start_date
5884 from okl_k_lines_full_v kle,
5885 okc_statuses_b sts
5886 where kle.dnz_chr_id = p_khr_id
5887 and kle.id = p_kle_id
5888 and sts.code = kle.sts_code
5889 and sts.ste_code not in ('HOLD', 'EXPIRED', 'CANCELLED');
5890
5891 l_kle c_kle%ROWTYPE;
5892
5893 TYPE loan_rec IS RECORD (se_amount NUMBER, se_date DATE, se_days NUMBER, se_arrears VARCHAR2(1));
5894 TYPE loan_tbl IS TABLE OF loan_rec INDEX BY BINARY_INTEGER;
5895
5896 x_principal_tbl okl_streams_pub.selv_tbl_type;
5897 x_interest_tbl okl_streams_pub.selv_tbl_type;
5898 x_prin_bal_tbl okl_streams_pub.selv_tbl_type;
5899
5900 x_interim_interest NUMBER;
5901 x_interim_days NUMBER;
5902 x_interim_dpp NUMBER;
5903
5904 asset_rents loan_tbl;
5905 loan_payment loan_tbl;
5906 pricipal_payment loan_tbl;
5907 interest_payment loan_tbl;
5908 pre_tax_income loan_tbl;
5909 termination_val loan_tbl;
5910
5911 l_payment_amount NUMBER := 0.1;
5912
5913 l_investment NUMBER;
5914
5915 l_iir_limit NUMBER := NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IIR_LIMIT')), 1000)/100;
5916
5917 l_start_date DATE;
5918 l_end_date DATE;
5919 l_interim_days NUMBER;
5920 l_interim_interest NUMBER;
5921 l_open_book NUMBER;
5922 l_close_book NUMBER;
5923 l_payment NUMBER;
5924 l_interest NUMBER;
5925 l_principal NUMBER;
5926 l_se_date DATE;
5927 l_termination_val NUMBER;
5928 l_days NUMBER;
5929 l_iir NUMBER := 0;
5930 l_bk_yield NUMBER := 0;
5931
5932 l_rent_period_end DATE;
5933 l_k_end_date DATE;
5934 l_total_periods NUMBER := 0;
5935 l_term_complete VARCHAR2(1) := 'N';
5936
5937 l_increment NUMBER := 0.1;
5938 l_abs_incr NUMBER;
5939 l_prev_incr_sign NUMBER;
5940 l_crossed_zero VARCHAR2(1) := 'N';
5941
5942 l_diff NUMBER;
5943 l_prev_diff NUMBER;
5944 l_prev_diff_sign NUMBER;
5945
5946 i BINARY_INTEGER := 0;
5947 j BINARY_INTEGER := 0;
5948 k BINARY_INTEGER := 0;
5949 m BINARY_INTEGER := 0;
5950
5951 lx_return_status VARCHAR2(1);
5952
5953 l_additional_parameters OKL_EXECUTE_FORMULA_PUB.ctxt_val_tbl_type;
5954
5955 l_day_convention_month VARCHAR2(30);
5956 l_day_convention_year VARCHAR2(30);
5957 l_days_in_year NUMBER;
5958
5959
5960 BEGIN
5961 IF (G_DEBUG_ENABLED = 'Y') THEN
5962 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
5963 END IF;
5964
5965 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
5966 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'begin' );
5967
5968 END IF;
5969 -- Fetch the day convention ..
5970 OKL_PRICING_UTILS_PVT.get_day_convention(
5971 p_id => p_khr_id,
5972 p_source => 'ISG',
5973 x_days_in_month => l_day_convention_month,
5974 x_days_in_year => l_day_convention_year,
5975 x_return_status => lx_return_status);
5976 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
5977 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
5978 END IF;
5979 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
5980 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
5981 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
5982 RAISE OKL_API.G_EXCEPTION_ERROR;
5983 END IF;
5984
5985 OPEN c_hdr;
5986 FETCH c_hdr INTO l_hdr;
5987 CLOSE c_hdr;
5988
5989 l_k_end_date := (ADD_MONTHS(l_hdr.start_date, l_hdr.term_duration) - 1);
5990
5991 OPEN c_kle;
5992 FETCH c_kle INTO l_kle;
5993 CLOSE c_kle;
5994
5995 OPEN c_rent_slls;
5996 FETCH c_rent_slls INTO l_rent_sll;
5997 CLOSE c_rent_slls;
5998
5999 l_start_date := l_rent_sll.start_date;
6000
6001 FOR l_rent_flow IN c_rent_flows LOOP
6002
6003 k := k + 1;
6004
6005 asset_rents(k).se_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
6006 p_days_in_month => l_day_convention_month,
6007 p_days_in_year => l_day_convention_year,
6008 p_end_date => l_rent_flow.se_date,
6009 p_arrears => l_rent_flow.se_arrears,
6010 x_return_status => lx_return_status);
6011
6012 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6013 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6014 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
6015 RAISE OKL_API.G_EXCEPTION_ERROR;
6016 END IF;
6017
6018 asset_rents(k).se_amount := l_rent_flow.se_amount;
6019 asset_rents(k).se_date := l_rent_flow.se_date;
6020 asset_rents(k).se_arrears := l_rent_flow.se_arrears;
6021
6022 l_start_date := l_rent_flow.se_date;
6023
6024 IF l_rent_flow.se_arrears = 'Y' THEN
6025 l_start_date := l_start_date + 1;
6026 END IF;
6027
6028 END LOOP;
6029
6030 l_interim_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_kle.start_date,
6031 p_days_in_month => l_day_convention_month,
6032 p_days_in_year => l_day_convention_year,
6033 p_end_date => l_rent_sll.start_date,
6034 p_arrears => 'N',
6035 x_return_status => lx_return_status);
6036
6037 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6038 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6039 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
6040 RAISE OKL_API.G_EXCEPTION_ERROR;
6041 END IF;
6042
6043 l_additional_parameters(0).name := 'TERMINATED_LINES_YN';
6044 l_additional_parameters(0).value := 'Y';
6045
6046 okl_execute_formula_pub.execute(p_api_version => G_API_VERSION,
6047 p_init_msg_list => G_FALSE,
6048 x_return_status => lx_return_status,
6049 x_msg_count => x_msg_count,
6050 x_msg_data => x_msg_data,
6051 p_formula_name => 'LINE_CAP_AMNT',
6052 p_contract_id => p_khr_id,
6053 p_line_id => p_kle_id,
6054 p_additional_parameters => l_additional_parameters,
6055 x_value => l_investment);
6056
6057 l_additional_parameters.delete;
6058
6059 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6060 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' cap amount ' || l_investment);
6061
6062 END IF;
6063 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6064 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6065 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
6066 RAISE OKL_API.G_EXCEPTION_ERROR;
6067 END IF;
6068
6069 l_investment := l_investment - p_ppd_amount;
6070
6071 LOOP
6072
6073 i := i + 1;
6074
6075 l_interim_interest := l_investment * l_interim_days * p_iir/360;
6076
6077 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6078 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || i||' Implicit Rate '||p_iir||' Interim Interest '||l_interim_interest
6079 ||' Interim Days = '||l_interim_days);
6080
6081 END IF;
6082 l_open_book := l_investment;
6083
6084 FOR k IN 1..asset_rents.COUNT LOOP
6085
6086 If ( p_ppd_date <= asset_rents(k).se_date ) Then
6087 l_payment := asset_rents(k).se_amount - l_payment_amount;
6088 Else
6089 l_payment := asset_rents(k).se_amount;
6090 End if;
6091
6092 l_interest := l_open_book*asset_rents(k).se_days*p_iir/360;
6093 l_principal := l_payment - l_interest;
6094 l_close_book := l_open_book - l_principal;
6095 l_open_book := l_close_book;
6096
6097 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6098 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' '||TO_CHAR(asset_rents(k).se_date, 'DD-MON-YYYY')||' DAYS '||asset_rents(k).se_DAYS
6099 || ' LOAN PAYMENT '||l_payment|| ' INTEREST '||ROUND(l_interest, 3)
6100 || ' PRINCIPAL '||ROUND(l_principal, 3)||' Next OB '||ROUND(l_open_book, 3));
6101
6102 END IF;
6103 END LOOP;
6104
6105 l_diff := l_open_book;
6106
6107 IF ROUND(l_diff, 4) = 0 THEN
6108
6109 l_open_book := l_investment;
6110
6111 FOR k IN asset_rents.FIRST .. asset_rents.LAST LOOP
6112
6113 If ( p_ppd_date <= asset_rents(k).se_date ) Then
6114 l_payment := asset_rents(k).se_amount - l_payment_amount;
6115 Else
6116 l_payment := asset_rents(k).se_amount;
6117 End if;
6118
6119 l_interest := l_open_book*asset_rents(k).se_days*p_iir/360;
6120 l_principal := l_payment - l_interest;
6121 l_close_book := l_open_book - l_principal;
6122
6123 l_se_date := asset_rents(k).se_date;
6124
6125 x_principal_tbl(k).amount := l_principal;
6126 x_interest_tbl(k).amount := l_interest;
6127 x_prin_bal_tbl(k).amount := l_close_book;
6128
6129 x_principal_tbl(k).se_line_number := k;
6130 x_interest_tbl(k).se_line_number := k;
6131 x_prin_bal_tbl(k).se_line_number := k;
6132
6133 x_principal_tbl(k).stream_element_date := l_se_date;
6134 x_interest_tbl(k).stream_element_date := l_se_date;
6135 x_prin_bal_tbl(k).stream_element_date := l_se_date;
6136
6137 l_open_book := l_close_book;
6138
6139 END LOOP;
6140
6141 IF l_interim_interest > 0 THEN
6142
6143 IF l_rent_sll.arrears_yn = 'Y' THEN
6144
6145 x_principal_tbl(asset_rents.FIRST-1).amount := 0;
6146 x_interest_tbl(asset_rents.FIRST-1).amount := l_interim_interest;
6147 x_prin_bal_tbl(asset_rents.FIRST-1).amount := l_investment;
6148
6149 x_principal_tbl(asset_rents.FIRST-1).se_line_number := 0;
6150 x_interest_tbl(asset_rents.FIRST-1).se_line_number := 0;
6151 x_prin_bal_tbl(asset_rents.FIRST-1).se_line_number := 0;
6152
6153 x_principal_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
6154 x_interest_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
6155 x_prin_bal_tbl(asset_rents.FIRST-1).stream_element_date := l_rent_sll.start_date;
6156
6157 ELSE
6158
6159 x_interest_tbl(asset_rents.FIRST).amount := l_interim_interest;
6160
6161 END IF;
6162
6163 END IF;
6164
6165 x_interim_interest := l_interim_interest;
6166 x_interim_days := l_interim_days;
6167 x_interim_dpp := l_rent_sll.dpp;
6168
6169 EXIT;
6170
6171 END IF;
6172
6173 IF SIGN(l_diff) <> SIGN(l_prev_diff) AND l_crossed_zero = 'N' THEN
6174 l_crossed_zero := 'Y';
6175 END IF;
6176
6177 IF l_crossed_zero = 'Y' THEN
6178 l_abs_incr := ABS(l_increment) / 2;
6179 ELSE
6180 l_abs_incr := ABS(l_increment);
6181 END IF;
6182
6183 IF i > 1 THEN
6184 IF SIGN(l_diff) <> l_prev_diff_sign THEN
6185 IF l_prev_incr_sign = 1 THEN
6186 l_increment := - l_abs_incr;
6187 ELSE
6188 l_increment := l_abs_incr;
6189 END IF;
6190 ELSE
6191 IF l_prev_incr_sign = 1 THEN
6192 l_increment := l_abs_incr;
6193 ELSE
6194 l_increment := - l_abs_incr;
6195 END IF;
6196 END IF;
6197 ELSE
6198 IF SIGN(l_diff) = 1 THEN
6199 l_increment := -l_increment;
6200 ELSE
6201 l_increment := l_increment;
6202 END IF;
6203 END IF;
6204
6205 l_payment_amount := l_payment_amount + l_increment;
6206
6207 l_prev_incr_sign := SIGN(l_increment);
6208 l_prev_diff_sign := SIGN(l_diff);
6209 l_prev_diff := l_diff;
6210
6211 END LOOP;
6212
6213 x_return_status := lx_return_status;
6214 x_payment_amount := l_payment_amount;
6215
6216 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6217 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'end' );
6218
6219 END IF;
6220 EXCEPTION
6221
6222 WHEN OKL_API.G_EXCEPTION_ERROR THEN
6223
6224 x_return_status := G_RET_STS_ERROR;
6225
6226 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
6227
6228 x_return_status := G_RET_STS_UNEXP_ERROR;
6229
6230 WHEN OTHERS THEN
6231
6232 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
6233 p_msg_name => G_DB_ERROR,
6234 p_token1 => G_PROG_NAME_TOKEN,
6235 p_token1_value => l_prog_name,
6236 p_token2 => G_SQLCODE_TOKEN,
6237 p_token2_value => sqlcode,
6238 p_token3 => G_SQLERRM_TOKEN,
6239 p_token3_value => sqlerrm);
6240
6241 x_return_status := G_RET_STS_UNEXP_ERROR;
6242
6243 END target_pay_down;
6244
6245 PROCEDURE comp_so_iir(p_api_version IN NUMBER,
6246 p_init_msg_list IN VARCHAR2 DEFAULT OKL_API.G_FALSE,
6247 x_return_status OUT NOCOPY VARCHAR2,
6248 x_msg_count OUT NOCOPY NUMBER,
6249 x_msg_data OUT NOCOPY VARCHAR2,
6250 p_khr_id IN NUMBER,
6251 p_kle_id IN NUMBER,
6252 p_target IN VARCHAR2,
6253 p_subside_yn IN VARCHAR2 DEFAULT 'N',
6254 p_interim_tbl IN interim_interest_tbl_type,
6255 x_payment OUT NOCOPY NUMBER,
6256 x_rate OUT NOCOPY NUMBER)
6257 IS
6258 l_api_name CONSTANT VARCHAR2(30) := 'COMP_SO_IIR';
6259 i BINARY_INTEGER := 0;
6260 m BINARY_INTEGER := 0;
6261 n BINARY_INTEGER := 0;
6262 p BINARY_INTEGER := 0;
6263 q BINARY_INTEGER := 0;
6264 r BINARY_INTEGER := 0;
6265 s BINARY_INTEGER := 0;
6266 l_time_zero_cost NUMBER := 0;
6267 l_cost NUMBER;
6268 l_adv_payment NUMBER := 0;
6269 l_currency_code VARCHAR2(15);
6270 l_precision NUMBER(1);
6271 l_cf_dpp NUMBER;
6272 l_cf_ppy NUMBER;
6273 l_cf_amount NUMBER;
6274 l_cf_date DATE;
6275 l_cf_arrear VARCHAR2(1);
6276 l_days_in_future NUMBER;
6277 l_periods NUMBER;
6278 l_irr NUMBER := 0;
6279 l_npv_rate NUMBER;
6280 l_npv_pay NUMBER;
6281 l_irr_limit NUMBER := NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000)/100;
6282 l_prev_npv_pay NUMBER;
6283 l_prev_npv_sign_pay NUMBER;
6284 l_crossed_zero_pay VARCHAR2(1) := 'N';
6285 l_increment_pay NUMBER := 0.1; -- 10% increment
6286 l_abs_incr_pay NUMBER;
6287 l_prev_incr_sign_pay NUMBER;
6288 l_prev_npv_rate NUMBER;
6289 l_prev_npv_sign_rate NUMBER;
6290 l_crossed_zero_rate VARCHAR2(1) := 'N';
6291 l_increment_rate NUMBER := 0.1; -- 10% increment
6292 l_abs_incr_rate NUMBER;
6293 l_prev_incr_sign_rate NUMBER;
6294 l_payment_inflow NUMBER := 0;
6295 l_payment_inter NUMBER := 0;
6296 l_asset_cost NUMBER := 0;
6297 l_residual_value NUMBER := 0;
6298 ld_res_pay_start_date DATE;
6299 ld_asset_start_date DATE;
6300 l_subside_yn VARCHAR2(1) := NVL(p_subside_yn,'N');
6301 l_khr_start_date DATE;
6302
6303 Cursor khr_type_csr IS
6304 Select SCS_CODE,
6305 START_DATE
6306 From okc_K_headers_b chr
6307 Where chr.id = p_khr_id;
6308
6309 khr_type_rec khr_type_csr%ROWTYPE;
6310 l_line_type VARCHAR2(256);
6311
6312 -- Gets all the Payment inflow over the SO_PAYMENT/FREE_FORM1 lines
6313 CURSOR c_inflows(p_khr_id NUMBER,
6314 p_kle_id NUMBER,
6315 p_line_type VARCHAR2)
6316 IS
6317 SELECT DISTINCT
6318 sel_amt.id id,
6319 sel_amt.amount cf_amount,
6320 sel_amt.stream_element_date cf_date,
6321 sel_rate.amount rate,
6322 sel_rate.comments miss_amt,
6323 sel_amt.comments cf_arrear,
6324 sty.stream_type_purpose cf_purpose,
6325 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
6326 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
6327 chr_so.start_date
6328 FROM okl_streams stm,
6329 okl_strm_type_b sty,
6330 okl_strm_elements sel_rate,
6331 okl_strm_elements sel_amt,
6332 okc_k_headers_b chr_so,
6333 okc_k_lines_b cle,
6334 okc_line_styles_b lse,
6335 okc_rules_b sll,
6336 okc_rules_b slh,
6337 okc_rule_groups_b rgp
6338 WHERE stm.khr_id = p_khr_id
6339 AND stm.kle_id = p_kle_id
6340 AND stm.kle_id = cle.id
6341 AND stm.say_code = 'WORK'
6342 AND stm.purpose_code = 'FLOW'
6343 AND stm.sty_id = sty.id
6344 AND stm.id = sel_amt.stm_id
6345 AND sel_amt.comments IS NOT NULL
6346 AND stm.id = sel_rate.stm_id
6347 AND sel_rate.sel_id = sel_amt.id
6348 AND stm.kle_id = cle.id
6349 AND cle.dnz_chr_id = chr_so.id
6350 AND trunc(cle.START_DATE) = trunc(chr_so.START_DATE)
6351 AND cle.lse_id = lse.id
6352 AND lse.lty_code = p_line_type --'SO_PAYMENT'
6353 AND cle.id = rgp.cle_id
6354 AND rgp.rgd_code = 'LALEVL'
6355 AND rgp.id = slh.rgp_id
6356 AND slh.rule_information_category = 'LASLH'
6357 AND TO_NUMBER(slh.object1_id1) = stm.sty_id
6358 AND TO_CHAR(slh.id) = sll.object2_id1
6359 AND sll.rule_information_category = 'LASLL';
6360 -- Gets the Asset residual value
6361 CURSOR c_asset_rvs(p_khr_id NUMBER,
6362 p_kle_id NUMBER,
6363 p_line_type VARCHAR2)
6364 IS
6365 SELECT DISTINCT DECODE(rul_sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
6366 DECODE(rul_sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
6367 DECODE(rul_sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
6368 cle_so.END_DATE
6369 FROM okc_k_headers_b chr_so,
6370 okc_line_styles_b lse_so,
6371 okc_k_lines_b cle_so,
6372 okc_rule_groups_b rgp_pay,
6373 okc_rules_b rul_slh,
6374 okc_rules_b rul_sll,
6375 okl_strm_type_b styt
6376 WHERE cle_so.id = p_kle_id
6377 AND cle_so.dnz_chr_id = p_khr_id
6378 AND cle_so.lse_id = lse_so.id
6379 AND cle_so.dnz_chr_id = chr_so.id
6380 AND trunc(cle_so.START_DATE) = trunc(chr_so.START_DATE )
6381 AND lse_so.lty_code = p_line_type --'SO_PAYMENT'
6382 AND cle_so.id = rgp_pay.cle_id
6383 AND rgp_pay.dnz_chr_id = cle_so.dnz_chr_id
6384 AND rgp_pay.rgd_code = 'LALEVL'
6385 AND rgp_pay.id = rul_slh.rgp_id
6386 AND rul_slh.rule_information_category = 'LASLH'
6387 AND TO_CHAR(rul_slh.id) = rul_sll.object2_id1
6388 AND rul_sll.rule_information_category = 'LASLL'
6389 AND TO_NUMBER(rul_slh.object1_id1) = styt.id
6390 AND styt.stream_type_purpose = 'RENT';
6391
6392 -- To get the Currency code and Precision
6393 CURSOR get_curr_code_pre(p_khr_id NUMBER)
6394 IS
6395 SELECT NVL(a.precision,0) precision
6396 FROM fnd_currencies a,
6397 okc_k_headers_b b
6398 WHERE b.currency_code = a.currency_code
6399 AND b.id = p_khr_id;
6400
6401 -- To get the Contract Start date
6402 CURSOR get_start_date(p_khr_id NUMBER)
6403 IS
6404 SELECT start_date
6405 FROM okc_k_headers_b b
6406 WHERE b.id = p_khr_id;
6407
6408 TYPE cash_flow_rec_type IS RECORD (cf_amount NUMBER,
6409 cf_date DATE,
6410 cf_purpose VARCHAR2(150),
6411 cf_dpp NUMBER,
6412 cf_ppy NUMBER,
6413 cf_days NUMBER,
6414 rate NUMBER,
6415 miss_amt okl_strm_elements.comments%TYPE);
6416
6417 TYPE cash_flow_tbl_type IS TABLE OF cash_flow_rec_type INDEX BY BINARY_INTEGER;
6418 hdr_inflow_tbl cash_flow_tbl_type;
6419 inflow_tbl cash_flow_tbl_type;
6420 rv_tbl cash_flow_tbl_type;
6421 outflow_tbl cash_flow_tbl_type;
6422 pass_th_tbl cash_flow_tbl_type;
6423 rec_exp_tbl cash_flow_tbl_type;
6424
6425 l_term NUMBER;
6426
6427 l_day_convention_month VARCHAR2(30);
6428 l_day_convention_year VARCHAR2(30);
6429 l_days_in_year NUMBER;
6430
6431 BEGIN
6432 IF (G_DEBUG_ENABLED = 'Y') THEN
6433 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
6434 END IF;
6435
6436 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6437 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'begin' );
6438
6439 END IF;
6440 x_return_status := OKL_API.G_RET_STS_SUCCESS;
6441 -- Call start_activity to create savepoint, check compatibility
6442 -- and initialize message list
6443 x_return_status := OKL_API.START_ACTIVITY (
6444 l_api_name
6445 ,p_init_msg_list
6446 ,'_PVT'
6447 ,x_return_status);
6448 -- Check if activity started successfully
6449 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
6450 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6451 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
6452 RAISE OKL_API.G_EXCEPTION_ERROR;
6453 END IF;
6454 -- check if the target is correctly given
6455 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6456 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'check if the target is correctly given' || ' ' || p_target );
6457
6458 END IF;
6459 -- Fetch the day convention ..
6460 OKL_PRICING_UTILS_PVT.get_day_convention(
6461 p_id => p_khr_id,
6462 p_source => 'ISG',
6463 x_days_in_month => l_day_convention_month,
6464 x_days_in_year => l_day_convention_year,
6465 x_return_status => x_return_status);
6466 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6467 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, 'comp_so_iir Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
6468 END IF;
6469 IF (x_return_status = G_RET_STS_UNEXP_ERROR) THEN
6470 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6471 ELSIF (x_return_status = G_RET_STS_ERROR) THEN
6472 RAISE OKL_API.G_EXCEPTION_ERROR;
6473 END IF;
6474
6475 IF p_target NOT IN ('RATE','PMNT') THEN
6476 OKL_API.set_message(p_app_name => G_APP_NAME,
6477 p_msg_name => G_INVALID_VALUE,
6478 p_token1 => G_COL_NAME_TOKEN,
6479 p_token1_value => 'Target');
6480 RAISE OKL_API.G_EXCEPTION_ERROR;
6481 END IF;
6482
6483 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6484 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'check if the target is correctly given - done');
6485
6486 END IF;
6487 OPEN get_start_date(P_khr_id => p_khr_id);
6488 FETCH get_start_date INTO l_khr_start_date;
6489 IF get_start_date%NOTFOUND THEN
6490 RAISE OKL_API.G_EXCEPTION_ERROR;
6491 END IF;
6492 CLOSE get_start_date;
6493 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6494 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'got start date');
6495
6496 END IF;
6497 -- Summing up Asset cost
6498 -- And since the input is a so_payment line we sum up the asset's cost
6499 -- to the so_payment line, assuming the start date of the so_payment
6500 -- and Asset start date are same.
6501 OKL_LA_STREAM_PVT.get_so_asset_oec(p_khr_id => p_khr_id,
6502 p_kle_id => p_kle_id,
6503 p_subside_yn => l_subside_yn,
6504 x_return_status => x_return_status,
6505 x_asset_oec => l_cost,
6506 x_start_date => ld_asset_start_date);
6507 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6508 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' get_so_asset_oec ' || l_cost|| x_return_status);
6509 END IF;
6510 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6511 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6512 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6513 RAISE OKL_API.G_EXCEPTION_ERROR;
6514 END IF;
6515 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6516 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_time_zero '|| x_return_status);
6517 END IF;
6518 l_time_zero_cost := l_time_zero_cost + NVL(l_cost, 0);
6519
6520 OPEN khr_type_csr;
6521 FETCH khr_type_csr INTO khr_type_rec;
6522 CLOSE khr_type_csr;
6523
6524 IF (INSTR( khr_type_rec.scs_code, 'LEASE') > 0) THEN
6525 l_line_type := 'FREE_FORM1';
6526 Else
6527 l_line_type := 'SO_PAYMENT';
6528 End If;
6529
6530 -- Collecting the inflow amounts
6531 -- from the strm elements table since where the payment associated to the
6532 -- So_payment lines are broken into stream elements data
6533 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6534 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'before inflows '|| x_return_status);
6535 END IF;
6536 FOR l_inflow IN c_inflows(p_khr_id => p_khr_id,
6537 p_kle_id => p_kle_id,
6538 p_line_type => l_line_type) LOOP
6539 n := n + 1;
6540 inflow_tbl(n).cf_amount := l_inflow.cf_amount;
6541 inflow_tbl(n).miss_amt := l_inflow.miss_amt;
6542 inflow_tbl(n).cf_date := l_inflow.cf_date;
6543 inflow_tbl(n).cf_purpose := l_inflow.cf_purpose;
6544 inflow_tbl(n).cf_dpp := l_inflow.days_per_period;
6545 inflow_tbl(n).cf_ppy := l_inflow.periods_per_year;
6546 inflow_tbl(n).rate := l_inflow.rate;
6547 inflow_tbl(n).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
6548 p_start_date => l_inflow.start_date,
6549 p_days_in_month => l_day_convention_month,
6550 p_days_in_year => l_day_convention_year,
6551 p_end_date => l_inflow.cf_date,
6552 p_arrears => l_inflow.cf_arrear,
6553 x_return_status => x_return_status);
6554 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6555 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
6556 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6557 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6558 END IF;
6559 IF (inflow_tbl(n).rate IS NULL OR
6560 inflow_tbl(n).rate = OKL_API.G_MISS_NUM) AND
6561 p_target = 'RATE' THEN
6562 OKL_API.set_message(
6563 p_app_name => G_APP_NAME,
6564 p_msg_name => G_INVALID_VALUE,
6565 p_token1 => G_COL_NAME_TOKEN,
6566 p_token1_value => 'Rate');
6567 x_return_status := OKL_API.G_RET_STS_ERROR;
6568 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6569 END IF;
6570 END LOOP;
6571
6572 -- Collecting the Residual Value amount
6573 -- Here since the Assets are associated to one so_payment line
6574 -- we sum up to get actual residual value , residual value percent
6575 -- are stored in rules
6576 FOR l_asset_rv IN c_asset_rvs(p_khr_id => p_khr_id,
6577 p_kle_id => p_kle_id,
6578 p_line_type => l_line_type) LOOP
6579 p := p + 1;
6580 OKL_LA_STREAM_PVT.get_so_residual_value(p_khr_id => p_khr_id,
6581 p_kle_id => p_kle_id,
6582 p_subside_yn => l_subside_yn,
6583 x_return_status => x_return_status,
6584 x_residual_value => rv_tbl(p).cf_amount,
6585 x_start_date => ld_res_pay_start_date);
6586 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6587 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
6588 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6589 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6590 END IF;
6591 l_residual_value := rv_tbl(p).cf_amount;
6592 rv_tbl(p).cf_date := l_asset_rv.end_date;
6593 rv_tbl(p).cf_dpp := l_asset_rv.days_per_period;
6594 rv_tbl(p).cf_ppy := l_asset_rv.periods_per_year;
6595 OKL_PRICING_PVT.get_rate(p_khr_id => p_khr_id,
6596 p_date => rv_tbl(p).cf_date,
6597 x_rate => rv_tbl(p).rate,
6598 x_return_status => x_return_status);
6599 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6600 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
6601 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6602 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6603 END IF;
6604 IF (rv_tbl(p).rate IS NULL OR
6605 rv_tbl(p).rate = OKL_API.G_MISS_NUM) AND
6606 p_target = 'RATE' THEN
6607 OKL_API.set_message(
6608 p_app_name => G_APP_NAME,
6609 p_msg_name => G_INVALID_VALUE,
6610 p_token1 => G_COL_NAME_TOKEN,
6611 p_token1_value => 'Rate');
6612 x_return_status := OKL_API.G_RET_STS_ERROR;
6613 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6614 END IF;
6615 rv_tbl(p).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
6616 p_start_date => ld_res_pay_start_date,
6617 p_days_in_month => l_day_convention_month,
6618 p_days_in_year => l_day_convention_year,
6619 p_end_date => rv_tbl(p).cf_date,
6620 p_arrears => 'Y',
6621 x_return_status => x_return_status);
6622 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6623 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR);
6624 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6625 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6626 END IF;
6627 END LOOP;
6628 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6629 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'after residual values #' || p|| x_return_status);
6630 END IF;
6631 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6632 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6633 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6634 RAISE OKL_API.G_EXCEPTION_ERROR;
6635 END IF;
6636 -- Collecting the Outflow amounts of asset
6637 -- Since we are summing up to the so_payment line
6638 -- We would have one asset cost
6639 IF ld_asset_start_date > l_khr_start_date THEN
6640 q := q + 1;
6641 OKL_LA_STREAM_PVT.get_so_asset_oec(
6642 p_khr_id => p_khr_id,
6643 p_kle_id => p_kle_id,
6644 p_subside_yn => l_subside_yn,
6645 x_return_status => x_return_status,
6646 x_asset_oec => outflow_tbl(q).cf_amount,
6647 x_start_date => ld_asset_start_date);
6648 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6649 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6650 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6651 RAISE OKL_API.G_EXCEPTION_ERROR;
6652 END IF;
6653 outflow_tbl(q).cf_amount := -(outflow_tbl(q).cf_amount);
6654 outflow_tbl(q).cf_date := ld_asset_start_date;
6655 outflow_tbl(q).cf_dpp := 1;
6656 outflow_tbl(q).cf_ppy := 360;
6657 OKL_PRICING_PVT.get_rate(p_khr_id => p_khr_id,
6658 p_date => outflow_tbl(q).cf_date,
6659 x_rate => outflow_tbl(q).rate,
6660 x_return_status => x_return_status);
6661 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6662 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6663 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6664 RAISE OKL_API.G_EXCEPTION_ERROR;
6665 END IF;
6666 IF (outflow_tbl(q).rate IS NULL OR
6667 outflow_tbl(q).rate = OKL_API.G_MISS_NUM) AND
6668 p_target = 'RATE' THEN
6669 OKL_API.set_message(
6670 p_app_name => G_APP_NAME,
6671 p_msg_name => G_INVALID_VALUE,
6672 p_token1 => G_COL_NAME_TOKEN,
6673 p_token1_value => 'Rate');
6674 x_return_status := OKL_API.G_RET_STS_ERROR;
6675 RAISE OKL_API.G_EXCEPTION_ERROR;
6676 END IF;
6677 outflow_tbl(q).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
6678 p_start_date => ld_asset_start_date,
6679 p_days_in_month => l_day_convention_month,
6680 p_days_in_year => l_day_convention_year,
6681 p_end_date => ld_asset_start_date,
6682 p_arrears => 'N',
6683 x_return_status => x_return_status);
6684 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6685 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6686 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6687 RAISE OKL_API.G_EXCEPTION_ERROR;
6688 END IF;
6689 END IF;
6690
6691 -- Validating Sum of all the inflow do not exceed the Total Time zero cost
6692 IF n > 0 THEN
6693 FOR n1 IN inflow_tbl.FIRST..inflow_tbl.LAST LOOP
6694 IF inflow_tbl(n1).cf_date <= ld_asset_start_date THEN
6695 l_adv_payment := l_adv_payment + inflow_tbl(n1).cf_amount;
6696 END IF;
6697 END LOOP;
6698 END IF;
6699 IF r > 0 THEN
6700 FOR r1 IN pass_th_tbl.FIRST..pass_th_tbl.LAST LOOP
6701 IF pass_th_tbl(r1).cf_date <= ld_asset_start_date THEN
6702 l_adv_payment := l_adv_payment + pass_th_tbl(r1).cf_amount;
6703 END IF;
6704 END LOOP;
6705 END IF;
6706 IF l_adv_payment >= l_time_zero_cost THEN
6707 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
6708 p_msg_name => 'OKL_IRR_CALC_INF_LOOP',
6709 p_token1 => 'ADV_AMOUNT',
6710 p_token1_value => l_adv_payment,
6711 p_token2 => 'CAPITAL_AMOUNT',
6712 p_token2_value => l_time_zero_cost);
6713 RAISE OKL_API.G_EXCEPTION_ERROR;
6714 END IF;
6715 -- To get the Currency code and Precision
6716 OPEN get_curr_code_pre(p_khr_id => p_khr_id);
6717 FETCH get_curr_code_pre INTO l_precision;
6718 IF get_curr_code_pre%NOTFOUND THEN
6719 OKL_API.set_message(p_app_name => G_APP_NAME,
6720 p_msg_name => G_REQUIRED_VALUE,
6721 p_token1 => G_COL_NAME_TOKEN,
6722 p_token1_value => 'Currency Code ');
6723 RAISE OKL_API.G_EXCEPTION_ERROR;
6724 END IF;
6725 CLOSE get_curr_code_pre;
6726
6727 -- Setting the IRR limit
6728 l_irr_limit := ROUND(NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000), 0)/100;
6729 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6730 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'l_irr_limit ' || l_irr_limit);
6731 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || 'b4 getting into the loop '|| x_return_status);
6732 END IF;
6733 LOOP
6734 i := i + 1;
6735 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6736 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ### ITERATION ### | ### PVALUE ### | ### IRR ### ');
6737 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || i || ' | ' || l_npv_rate || ' | ' || l_irr);
6738 END IF;
6739 l_npv_rate := -(l_time_zero_cost);
6740 l_npv_pay := -(l_time_zero_cost);
6741
6742 -------------------------------------------
6743 -- RV CASH INFLOWS
6744 -------------------------------------------
6745 IF p > 0 THEN
6746 FOR z IN rv_tbl.FIRST..rv_tbl.LAST LOOP
6747 l_cf_dpp := rv_tbl(z).cf_dpp;
6748 l_cf_ppy := rv_tbl(z).cf_ppy;
6749 l_cf_amount := rv_tbl(z).cf_amount;
6750 l_cf_date := rv_tbl(z).cf_date;
6751 l_days_in_future := rv_tbl(z).cf_days;
6752 l_periods := l_days_in_future / l_cf_dpp;
6753 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
6754 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
6755 p_msg_name => 'OKL_IRR_ZERO_DIV');
6756 x_return_status := OKL_API.G_RET_STS_ERROR;
6757 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6758 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide rvs '|| x_return_status);
6759 END IF;
6760 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6761 END IF;
6762 IF p_target = 'RATE' THEN
6763 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + rv_tbl(z).rate/(l_cf_ppy*100)), l_periods));
6764 ELSIF p_target = 'PMNT' THEN
6765 l_npv_rate := l_npv_rate + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
6766 END IF;
6767 END LOOP;
6768 END IF;
6769
6770 -------------------------------------------
6771 -- LINE LEVEL CASH INFLOWS
6772 -------------------------------------------
6773 IF p_target = 'RATE' THEN
6774 l_term := 0;
6775 FOR y IN inflow_tbl.FIRST..inflow_tbl.LAST
6776 LOOP
6777 l_cf_dpp := inflow_tbl(y).cf_dpp;
6778 l_cf_ppy := inflow_tbl(y).cf_ppy;
6779 l_days_in_future := inflow_tbl(y).cf_days;
6780 l_periods := l_days_in_future / l_cf_dpp;
6781 IF inflow_tbl(y).miss_amt = 'Y' THEN
6782 l_term := l_term + (1 / POWER((1 + inflow_tbl(y).rate/(l_cf_ppy*100)), l_periods));
6783 ELSIF inflow_tbl(y).miss_amt = 'N' THEN
6784 l_cf_amount := inflow_tbl(y).cf_amount;
6785 l_cf_date := inflow_tbl(y).cf_date;
6786 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
6787 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
6788 p_msg_name => 'OKL_IRR_ZERO_DIV');
6789 x_return_status := OKL_API.G_RET_STS_ERROR;
6790 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6791 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide indlows '|| x_return_status);
6792 END IF;
6793 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6794 END IF;
6795 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + inflow_tbl(y).rate/(l_cf_ppy*100)), l_periods));
6796 END IF;
6797 END LOOP;
6798
6799 If (l_term <> 0 ) Then
6800 l_payment_inflow := (-1 * l_npv_pay ) / l_term;
6801 else
6802 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
6803 p_msg_name => 'OKL_IRR_ZERO_DIV');
6804 x_return_status := OKL_API.G_RET_STS_ERROR;
6805 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6806 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide indlows '|| x_return_status);
6807 END IF;
6808 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6809 end if;
6810
6811 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6812 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_npv_pay ' || l_npv_pay );
6813 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' l_term ' || l_term );
6814
6815 END IF;
6816 l_npv_pay := 0;
6817 Else
6818
6819 IF n > 0 THEN
6820 FOR y IN inflow_tbl.FIRST..inflow_tbl.LAST LOOP
6821 l_cf_dpp := inflow_tbl(y).cf_dpp;
6822 l_cf_ppy := inflow_tbl(y).cf_ppy;
6823 IF inflow_tbl(y).miss_amt = 'Y' AND p_target = 'RATE' THEN
6824 l_cf_amount := l_payment_inflow;
6825 ELSIF inflow_tbl(y).miss_amt = 'N' THEN
6826 l_cf_amount := inflow_tbl(y).cf_amount;
6827 END IF;
6828 l_cf_date := inflow_tbl(y).cf_date;
6829 l_days_in_future := inflow_tbl(y).cf_days;
6830 l_periods := l_days_in_future / l_cf_dpp;
6831 IF (l_periods < 1) AND (l_irr/l_cf_ppy <= -1) THEN
6832 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
6833 p_msg_name => 'OKL_IRR_ZERO_DIV');
6834 x_return_status := OKL_API.G_RET_STS_ERROR;
6835 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6836 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' ZERO divide indlows '|| x_return_status);
6837 END IF;
6838 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6839 END IF;
6840 IF p_target = 'RATE' THEN
6841 l_npv_pay := l_npv_pay + (l_cf_amount / POWER((1 + inflow_tbl(y).rate/(l_cf_ppy*100)), l_periods));
6842 ELSIF p_target = 'PMNT' THEN
6843 l_npv_rate := l_npv_rate + (l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods));
6844 END IF;
6845 END LOOP;
6846 END IF;
6847
6848 End If;
6849
6850 IF p_target = 'RATE' THEN
6851 IF ROUND(l_npv_pay, l_precision+4) = 0 THEN
6852 x_payment := l_payment_inflow;
6853 EXIT;
6854 END IF;
6855 ELSIF p_target = 'PMNT' THEN
6856 IF ROUND(l_npv_rate, l_precision+4) = 0 THEN
6857 x_rate := l_irr;
6858 EXIT;
6859 END IF;
6860 END IF;
6861 IF p_target = 'RATE' THEN
6862 IF SIGN(l_npv_pay) <> SIGN(l_prev_npv_pay) AND l_crossed_zero_pay = 'N' THEN
6863 l_crossed_zero_pay := 'Y';
6864 END IF;
6865 IF l_crossed_zero_pay = 'Y' THEN
6866 l_abs_incr_pay := ABS(l_increment_pay) / 2;
6867 ELSE
6868 l_abs_incr_pay := ABS(l_increment_pay);
6869 END IF;
6870 IF i > 1 THEN
6871 IF SIGN(l_npv_pay) <> l_prev_npv_sign_pay THEN
6872 IF l_prev_incr_sign_pay = 1 THEN
6873 l_increment_pay := - l_abs_incr_pay;
6874 ELSE
6875 l_increment_pay := l_abs_incr_pay;
6876 END IF;
6877 ELSE
6878 IF l_prev_incr_sign_pay = 1 THEN
6879 l_increment_pay := l_abs_incr_pay;
6880 ELSE
6881 l_increment_pay := - l_abs_incr_pay;
6882 END IF;
6883 END IF;
6884 ELSE
6885 IF SIGN(l_npv_pay) = -1 THEN
6886 l_increment_pay := l_increment_pay;
6887 ELSIF SIGN(l_npv_pay) = 1 THEN
6888 l_increment_pay := -l_increment_pay;
6889 END IF;
6890 END IF;
6891 l_payment_inflow := l_payment_inflow + l_increment_pay;
6892 l_prev_incr_sign_pay := SIGN(l_increment_pay);
6893 l_prev_npv_sign_pay := SIGN(l_npv_pay);
6894 l_prev_npv_pay := l_npv_pay;
6895 ELSIF p_target = 'PMNT' THEN
6896 IF SIGN(l_npv_rate) <> SIGN(l_prev_npv_rate) AND l_crossed_zero_rate = 'N' THEN
6897 l_crossed_zero_rate := 'Y';
6898 END IF;
6899 IF l_crossed_zero_rate = 'Y' THEN
6900 l_abs_incr_rate := ABS(l_increment_rate) / 2;
6901 ELSE
6902 l_abs_incr_rate := ABS(l_increment_rate);
6903 END IF;
6904 IF i > 1 THEN
6905 IF SIGN(l_npv_rate) <> l_prev_npv_sign_rate THEN
6906 IF l_prev_incr_sign_rate = 1 THEN
6907 l_increment_rate := - l_abs_incr_rate;
6908 ELSE
6909 l_increment_rate := l_abs_incr_rate;
6910 END IF;
6911 ELSE
6912 IF l_prev_incr_sign_rate = 1 THEN
6913 l_increment_rate := l_abs_incr_rate;
6914 ELSE
6915 l_increment_rate := - l_abs_incr_rate;
6916 END IF;
6917 END IF;
6918 ELSE
6919 IF SIGN(l_npv_rate) = -1 THEN
6920 l_increment_rate := -l_increment_rate;
6921 END IF;
6922 END IF;
6923 l_irr := l_irr + l_increment_rate;
6924 IF ABS(l_irr) > l_irr_limit THEN
6925 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
6926 p_msg_name => 'OKL_IRR_CALC_IRR_LIMIT',
6927 p_token1 => 'IRR_LIMIT',
6928 p_token1_value => l_irr_limit*100);
6929 x_return_status := OKL_API.G_RET_STS_ERROR;
6930 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
6931 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_api_name || ' 100000% '|| x_return_status);
6932 END IF;
6933 EXIT WHEN (x_return_status = OKL_API.G_RET_STS_ERROR);
6934 END IF;
6935 l_prev_incr_sign_rate := SIGN(l_increment_rate);
6936 l_prev_npv_sign_rate := SIGN(l_npv_rate);
6937 l_prev_npv_rate := l_npv_rate;
6938 END IF;
6939 END LOOP;
6940 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
6941 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
6942 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
6943 RAISE OKL_API.G_EXCEPTION_ERROR;
6944 END IF;
6945 OKL_API.END_ACTIVITY (x_msg_count,
6946 x_msg_data );
6947 EXCEPTION
6948 WHEN OKL_API.G_EXCEPTION_ERROR THEN
6949 IF get_curr_code_pre%ISOPEN THEN
6950 CLOSE get_curr_code_pre;
6951 END IF;
6952 IF c_asset_rvs%ISOPEN THEN
6953 CLOSE c_asset_rvs;
6954 END IF;
6955 IF c_inflows%ISOPEN THEN
6956 CLOSE c_inflows;
6957 END IF;
6958 IF get_start_date%ISOPEN THEN
6959 CLOSE get_start_date;
6960 END IF;
6961 x_return_status := OKL_API.HANDLE_EXCEPTIONS(
6962 l_api_name,
6963 G_PKG_NAME,
6964 'OKL_API.G_RET_STS_ERROR',
6965 x_msg_count,
6966 x_msg_data,
6967 '_PVT');
6968 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
6969 IF get_curr_code_pre%ISOPEN THEN
6970 CLOSE get_curr_code_pre;
6971 END IF;
6972 IF c_asset_rvs%ISOPEN THEN
6973 CLOSE c_asset_rvs;
6974 END IF;
6975 IF c_inflows%ISOPEN THEN
6976 CLOSE c_inflows;
6977 END IF;
6978 IF get_start_date%ISOPEN THEN
6979 CLOSE get_start_date;
6980 END IF;
6981 x_return_status :=OKL_API.HANDLE_EXCEPTIONS(
6982 l_api_name,
6983 G_PKG_NAME,
6984 'OKL_API.G_RET_STS_UNEXP_ERROR',
6985 x_msg_count,
6986 x_msg_data,
6987 '_PVT');
6988 WHEN OTHERS THEN
6989 IF get_curr_code_pre%ISOPEN THEN
6990 CLOSE get_curr_code_pre;
6991 END IF;
6992 IF c_asset_rvs%ISOPEN THEN
6993 CLOSE c_asset_rvs;
6994 END IF;
6995 IF c_inflows%ISOPEN THEN
6996 CLOSE c_inflows;
6997 END IF;
6998 IF get_start_date%ISOPEN THEN
6999 CLOSE get_start_date;
7000 END IF;
7001 x_return_status :=OKL_API.HANDLE_EXCEPTIONS(
7002 l_api_name,
7003 G_PKG_NAME,
7004 'OTHERS',
7005 x_msg_count,
7006 x_msg_data,
7007 '_PVT');
7008 END comp_so_iir;
7009
7010
7011 PROCEDURE target_parameter(
7012 p_api_version IN NUMBER,
7013 p_init_msg_list IN VARCHAR2,
7014 p_khr_id IN NUMBER,
7015 p_kle_id IN NUMBER,
7016 p_rate_type IN VARCHAR2,
7017 p_target_param IN VARCHAR2,
7018 p_pay_tbl IN OKL_STREAM_GENERATOR_PVT.payment_tbl_type,
7019 x_pay_tbl OUT NOCOPY OKL_STREAM_GENERATOR_PVT.payment_tbl_type,
7020 x_overall_rate OUT NOCOPY NUMBER,
7021 x_return_status OUT NOCOPY VARCHAR2,
7022 x_msg_count OUT NOCOPY NUMBER,
7023 x_msg_data OUT NOCOPY VARCHAR2) IS
7024
7025 CURSOR c_hdr IS
7026 SELECT chr.template_yn,
7027 chr.currency_code,
7028 chr.start_date,
7029 chr.end_date,
7030 khr.deal_type,
7031 khr.term_duration,
7032 NVL(khr.generate_accrual_yn, 'Y')
7033 FROM okc_k_headers_b chr,
7034 okl_k_headers khr
7035 WHERE khr.id = p_khr_id
7036 AND chr.id = khr.id;
7037
7038 l_hdr c_hdr%ROWTYPE;
7039
7040 Cursor c_rv IS
7041 SELECT SUM(to_number(nvl(rul_rv.rule_information2,rul_rv.rule_information4))) Residual_value,
7042 DECODE(rul_sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
7043 DECODE(rul_sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
7044 DECODE(rul_sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
7045 cle_so.id cle_id,
7046 cle_so.start_date
7047 FROM okc_k_headers_b chr_rv,
7048 okc_line_styles_b lse_rv,
7049 okc_k_lines_b cle_rv,
7050 okc_rules_b rul_rv,
7051 okc_rule_groups_b rgp_rv,
7052 okc_line_styles_b lse_so,
7053 okc_k_lines_b cle_so,
7054 okc_rules_b rul_so,
7055 okc_rule_groups_b rgp_so,
7056 okc_rule_groups_b rgp_pay,
7057 okc_rules_b rul_slh,
7058 okc_rules_b rul_sll,
7059 okl_strm_type_b styt
7060 WHERE rgp_so.cle_id = p_kle_id
7061 AND rgp_so.dnz_chr_id = p_khr_id
7062 AND rgp_so.rgd_code = 'SOPYSC'
7063 AND rgp_so.dnz_chr_id = rul_so.dnz_chr_id
7064 AND rgp_so.id = rul_so.rgp_id
7065 AND rul_so.rule_information_category = 'SOPMSC'
7066 AND rgp_so.cle_id = cle_so.id
7067 AND cle_so.id = p_kle_id
7068 AND cle_so.dnz_chr_id = rul_so.dnz_chr_id
7069 AND cle_so.lse_id = lse_so.id
7070 AND lse_so.lty_code = 'SO_PAYMENT'
7071 AND rul_rv.object1_id1 = to_char(rul_so.id)
7072 AND rul_rv.dnz_chr_id = p_khr_id
7073 AND rul_rv.dnz_chr_id = rul_so.dnz_chr_id
7074 AND rul_rv.rgp_id = rgp_rv.id
7075 AND rgp_rv.rgd_code = 'SOPSAD'
7076 AND rgp_rv.dnz_chr_id = rul_so.dnz_chr_id
7077 AND rgp_rv.cle_id = cle_rv.id
7078 AND cle_rv.lse_id = lse_rv.id
7079 AND lse_rv.lty_code = 'FREE_FORM1'
7080 AND rgp_rv.dnz_chr_id = chr_rv.id
7081 AND chr_rv.START_DATE = cle_rv.START_DATE
7082 AND cle_so.id = rgp_pay.cle_id
7083 AND rgp_pay.rgd_code = 'LALEVL'
7084 AND rgp_pay.id = rul_slh.rgp_id
7085 AND rul_slh.rule_information_category = 'LASLH'
7086 AND TO_CHAR(rul_slh.id) = rul_sll.object2_id1
7087 AND rul_sll.rule_information_category = 'LASLL'
7088 AND rul_slh.object1_id1 = TO_CHAR(styt.id)
7089 AND styt.stream_type_purpose = 'RENT'
7090 GROUP BY DECODE(rul_sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360),
7091 DECODE(rul_sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1),
7092 DECODE(rul_sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12),
7093 cle_so.id,
7094 cle_so.start_date;
7095
7096 r_rv c_rv%ROWTYPE;
7097
7098 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'target_parameter';
7099
7100 l_rate NUMBER;
7101 l_payment NUMBER;
7102 l_payment_count NUMBER;
7103
7104 l_capital_cost NUMBER;
7105 l_residual_value NUMBER;
7106 l_start_date DATE;
7107
7108 Cursor l_strms_csr Is
7109 Select id
7110 from okl_streams
7111 where khr_id = p_khr_id
7112 --and kle_id = p_kle_id
7113 and purpose_code in ('PLOW', 'FLOW', 'STUBS');
7114
7115 l_strms_rec l_strms_csr%ROWTYPE;
7116
7117 Cursor c_sty ( n VARCHAR2 ) IS
7118 Select id
7119 from okl_strm_type_tl
7120 where language = 'US'
7121 and name = n;
7122
7123 r_sty c_sty%ROWTYPE;
7124 lt_pay_tbl OKL_STREAM_GENERATOR_PVT.payment_tbl_type;
7125 l_pay_tbl OKL_STREAM_GENERATOR_PVT.payment_tbl_type;
7126 l_sty_id NUMBER := -1;
7127
7128 l_interim_interest NUMBER;
7129 l_interim_days NUMBER;
7130 l_interim_dpp NUMBER;
7131
7132 l_interim_tbl interim_interest_tbl_type;
7133
7134 l_stmv_tbl okl_streams_pub.stmv_tbl_type;
7135 x_stmv_tbl okl_streams_pub.stmv_tbl_type;
7136
7137 --Added sll.rule_information2 in order by clause by djanaswa for bug 6007644
7138
7139 Cursor c_fee IS
7140 SELECT DISTINCT
7141 cle.id kleId,
7142 stm.id styId,
7143 sll.object1_id1 frequency,
7144 TO_NUMBER(sll.rule_information3) periods,
7145 FND_DATE.canonical_to_date(sll.rule_information2) start_date,
7146 sll.rule_information5 structure,
7147 sll.rule_information10 advance_arrears,
7148 FND_NUMBER.canonical_to_number(sll.rule_information6) amount,
7149 TO_NUMBER(sll.rule_information7) stub_days,
7150 TO_NUMBER(sll.rule_information8) stub_amount
7151 FROM okc_k_headers_b chr_so,
7152 okc_k_lines_b cle,
7153 okl_k_lines kle,
7154 okc_line_styles_b lse,
7155 okc_rules_b sll,
7156 okc_rules_b slh,
7157 okc_rule_groups_b rgp,
7158 okl_strm_type_tl stm
7159 WHERE chr_so.id = p_khr_id
7160 and cle.sts_code in( 'INCOMPLETE', 'COMPLETE')--'ENTERED'
7161 AND cle.dnz_chr_id = chr_so.id
7162 AND kle.id = cle.id
7163 AND trunc(cle.START_DATE) = trunc(chr_so.START_DATE)
7164 AND cle.lse_id = lse.id
7165 AND (lse.lty_code = 'FEE' OR lse.lty_code = 'LINK_FEE_ASSET')
7166 AND ( kle.fee_type <> 'CAPITALIZED' OR kle.fee_type IS NULL )
7167 AND cle.id = rgp.cle_id
7168 AND rgp.rgd_code = 'LALEVL'
7169 AND rgp.id = slh.rgp_id
7170 AND slh.rule_information_category = 'LASLH'
7171 AND TO_NUMBER(slh.object1_id1) = stm.id
7172 AND TO_CHAR(slh.id) = sll.object2_id1
7173 AND sll.rule_information_category = 'LASLL'
7174 order by stm.id, FND_DATE.canonical_to_date(sll.rule_information2);
7175
7176 r_fee c_fee%ROWTYPE;
7177 i BINARY_INTEGER;
7178 j BINARY_INTEGER;
7179
7180 Cursor c_subs Is
7181 Select 'Y'
7182 From dual
7183 where Exists(
7184 select kle.id
7185 from okl_k_lines_full_v kle,
7186 okc_line_styles_b lse,
7187 okc_statuses_b sts
7188 where KLE.LSE_ID = LSE.ID
7189 and lse.lty_code = 'SUBSIDY'
7190 and kle.dnz_chr_id = p_khr_id
7191 and sts.code = kle.sts_code
7192 and sts.ste_code not in ('HOLD', 'TERMINATED', 'EXPIRED', 'CANCELLED'));
7193
7194 r_subs c_subs%ROWTYPE;
7195 l_subsidies_yn VARCHAR2(1);
7196 l_subsidy_amount NUMBER;
7197 l_kle_id NUMBER;
7198 -- Bug 4626837 : Start
7199 l_rent_strm_name VARCHAR2(256);
7200 l_rent_strm_id NUMBER;
7201 -- Bug 4626837 : End
7202
7203 Begin
7204 IF (G_DEBUG_ENABLED = 'Y') THEN
7205 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
7206 END IF;
7207
7208 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7209 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'begin' );
7210
7211 END IF;
7212 x_return_status := G_RET_STS_SUCCESS;
7213
7214 OPEN c_hdr;
7215 FETCH c_hdr INTO l_hdr;
7216 CLOSE c_hdr;
7217
7218 For i in p_pay_tbl.FIRST..p_pay_tbl.LAST
7219 LOOP
7220 l_pay_tbl(i) := p_pay_tbl(i);
7221 --l_pay_tbl(i).rate := l_pay_tbl(i).rate / 100.0;
7222 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7223 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' date ' || l_pay_tbl(i).start_date || ' amout ' || l_pay_tbl(i).amount );
7224 END IF;
7225 If ( l_pay_tbl(i).periods IS NOT NULL) AND ( l_pay_tbl(i).amount IS NULL ) Then
7226 l_pay_tbl(i).amount := -9999999;
7227 ElsIf ( l_pay_tbl(i).periods IS NULL) AND ( l_pay_tbl(i).stub_amount IS NULL ) Then
7228 l_pay_tbl(i).stub_amount := -9999999;
7229 End If;
7230 END LOOP;
7231
7232 -- cannot have more than one payment missing.
7233 OKL_LA_STREAM_PVT.validate_payments(
7234 p_api_version => p_api_version,
7235 p_init_msg_list => p_init_msg_list,
7236 p_khr_id => p_khr_id,
7237 p_paym_tbl => l_pay_tbl,
7238 x_return_status => x_return_status,
7239 x_msg_count => x_msg_count,
7240 x_msg_data => x_msg_data);
7241
7242 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7243 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'validate payments ' || x_return_status );
7244 END IF;
7245 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7246 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7247 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7248 RAISE OKL_API.G_EXCEPTION_ERROR;
7249 END IF;
7250 -- Bug 4626837: Start
7251 --Fetch the Stream Type ID based on the purpose instead of the name
7252 OKL_ISG_UTILS_PVT.get_primary_stream_type(
7253 p_khr_id => p_khr_id,
7254 p_deal_type => l_hdr.deal_type,
7255 p_primary_sty_purpose => 'RENT',
7256 x_return_status => x_return_status,
7257 x_primary_sty_id => l_rent_strm_id,
7258 x_primary_sty_name => l_rent_strm_name);
7259 IF (x_return_status = G_RET_STS_UNEXP_ERROR) THEN
7260 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7261 ELSIF (x_return_status = G_RET_STS_ERROR) THEN
7262 RAISE OKL_API.G_EXCEPTION_ERROR;
7263 END IF;
7264 -- Bug 4626837: End
7265 OKL_STREAM_GENERATOR_PVT.generate_cash_flows(
7266 p_api_version => p_api_version,
7267 p_init_msg_list => p_init_msg_list,
7268 p_khr_id => p_khr_id,
7269 p_kle_id => p_kle_id,
7270 p_sty_id => l_rent_strm_id,
7271 p_payment_tbl => l_pay_tbl,
7272 x_payment_count => l_payment_count,
7273 x_return_status => x_return_status,
7274 x_msg_count => x_msg_count,
7275 x_msg_data => x_msg_data);
7276
7277 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7278 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'generate_cash_flows ' || x_return_status );
7279
7280 END IF;
7281 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7282 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7283 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7284 RAISE OKL_API.G_EXCEPTION_ERROR;
7285 END IF;
7286
7287
7288 OPEN c_subs;
7289 FETCH c_subs INTO l_subsidies_yn;
7290 CLOSE c_subs;
7291 l_subsidies_yn := nvl( l_subsidies_yn, 'N' );
7292
7293 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7294 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' subsidy ' || l_subsidies_yn );
7295
7296 END IF;
7297 okl_la_stream_pvt.get_so_asset_oec(p_khr_id,
7298 p_kle_id,
7299 l_subsidies_yn,
7300 x_return_status,
7301 l_capital_cost,
7302 l_start_date);
7303
7304 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7305 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' get_asset_oec ' || to_char( l_capital_cost)|| x_return_status);
7306 END IF;
7307 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7308 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7309 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7310 RAISE OKL_API.G_EXCEPTION_ERROR;
7311 END IF;
7312
7313 Okl_la_stream_pvt.get_so_residual_value(p_khr_id,
7314 p_kle_id,
7315 l_subsidies_yn,
7316 x_return_status,
7317 l_residual_value,
7318 l_start_date);
7319
7320 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7321 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' get_residual_value ' || to_char( l_residual_value )|| x_return_status);
7322 END IF;
7323 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7324 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7325 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7326 RAISE OKL_API.G_EXCEPTION_ERROR;
7327 END IF;
7328
7329 If ( p_rate_type = 'PRE_TAX_IRR' ) Then
7330
7331 i := 0;
7332
7333 FOR r_fee in c_fee
7334 LOOP
7335
7336 l_kle_id := r_fee.kleId;
7337 If ( l_sty_id = r_fee.styId ) Then
7338
7339 i := i + 1;
7340 lt_pay_tbl(i).amount := r_fee.amount;
7341 lt_pay_tbl(i).start_date := r_fee.start_date;
7342 lt_pay_tbl(i).arrears_yn := r_fee.advance_arrears;
7343 lt_pay_tbl(i).periods := r_fee.periods;
7344 lt_pay_tbl(i).frequency := r_fee.frequency;
7345 lt_pay_tbl(i).stub_days := r_fee.stub_days;
7346 lt_pay_tbl(i).stub_amount := r_fee.stub_amount;
7347
7348 If (l_pay_tbl.COUNT = 1 ) THen --bug# 4129476
7349 lt_pay_tbl(i).rate := l_pay_tbl(l_pay_tbl.FIRST).rate;
7350 Else
7351
7352 For j in l_pay_tbl.FIRST..(l_pay_tbl.LAST-1)
7353 LOOP
7354
7355 If (( TRUNC(r_fee.start_date) >= TRUNC(l_pay_tbl(j).start_date) ) AND
7356 ( TRUNC(r_fee.start_date) < TRUNC(l_pay_tbl(j+1).start_date))) Then
7357
7358 If ( l_pay_tbl(j).arrears_yn = 'Y' ) Then
7359 lt_pay_tbl(i).rate := l_pay_tbl(j+1).rate;
7360 else
7361 lt_pay_tbl(i).rate := l_pay_tbl(j).rate;
7362 End If;
7363 exit;
7364
7365 End If;
7366 END LOOP;
7367
7368 End If;
7369
7370 Else
7371
7372 If ( lt_pay_tbl.COUNT > 0 ) Then
7373
7374
7375 OKL_STREAM_GENERATOR_PVT.generate_cash_flows(
7376 p_api_version => p_api_version,
7377 p_init_msg_list => p_init_msg_list,
7378 p_khr_id => p_khr_id,
7379 p_kle_id => r_fee.kleId,
7380 p_sty_id => l_sty_id,
7381 p_payment_tbl => lt_pay_tbl,
7382 x_payment_count => l_payment_count,
7383 x_return_status => x_return_status,
7384 x_msg_count => x_msg_count,
7385 x_msg_data => x_msg_data);
7386
7387
7388 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7389 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7390 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7391 RAISE OKL_API.G_EXCEPTION_ERROR;
7392 END IF;
7393
7394 End If;
7395
7396 lt_pay_tbl.DELETE;
7397 i := 1;
7398 l_sty_id := r_fee.styId;
7399 lt_pay_tbl(i).amount := r_fee.amount;
7400 lt_pay_tbl(i).start_date := r_fee.start_date;
7401 lt_pay_tbl(i).arrears_yn := r_fee.advance_arrears;
7402 lt_pay_tbl(i).periods := r_fee.periods;
7403 lt_pay_tbl(i).frequency := r_fee.frequency;
7404 lt_pay_tbl(i).stub_days := r_fee.stub_days;
7405 lt_pay_tbl(i).stub_amount := r_fee.stub_amount;
7406
7407 If (l_pay_tbl.COUNT = 1 ) THen --bug# 4129476
7408 lt_pay_tbl(i).rate := l_pay_tbl(l_pay_tbl.FIRST).rate;
7409 Else
7410 For j in l_pay_tbl.FIRST..(l_pay_tbl.LAST-1)
7411 LOOP
7412 If (( TRUNC(r_fee.start_date) >= TRUNC(l_pay_tbl(j).start_date) ) AND
7413 ( TRUNC(r_fee.start_date) < TRUNC(l_pay_tbl(j+1).start_date))) Then
7414 lt_pay_tbl(i).rate := l_pay_tbl(j).rate;
7415 End If;
7416 END LOOP;
7417
7418 End If;
7419
7420 End If;
7421
7422 END LOOP;
7423
7424 If ( lt_pay_tbl.COUNT > 0 ) Then
7425
7426 OKL_STREAM_GENERATOR_PVT.generate_cash_flows(
7427 p_api_version => p_api_version,
7428 p_init_msg_list => p_init_msg_list,
7429 p_khr_id => p_khr_id,
7430 p_kle_id => l_kle_Id,
7431 p_sty_id => l_sty_id,
7432 p_payment_tbl => lt_pay_tbl,
7433 x_payment_count => l_payment_count,
7434 x_return_status => x_return_status,
7435 x_msg_count => x_msg_count,
7436 x_msg_data => x_msg_data);
7437
7438
7439 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7440 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7441 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7442 RAISE OKL_API.G_EXCEPTION_ERROR;
7443 END IF;
7444
7445 End If;
7446
7447
7448 OPEN c_sty ( 'RESIDUAL VALUE' );
7449 FETCH c_sty INTO r_sty;
7450 CLOSE c_sty;
7451
7452 OPEN c_rv;
7453 FETCH c_rv INTO r_rv;
7454 CLOSE c_rv;
7455
7456 lt_pay_tbl.DELETE;
7457
7458 l_interim_tbl(1).cf_days := l_interim_days;
7459 l_interim_tbl(1).cf_amount := l_interim_interest;
7460 l_interim_tbl(1).cf_dpp := l_interim_dpp;
7461
7462 comp_so_pre_tax_irr(
7463 p_api_version => p_api_version,
7464 p_init_msg_list => p_init_msg_list,
7465 x_return_status => x_return_status,
7466 x_msg_count => x_msg_count,
7467 x_msg_data => x_msg_data,
7468 p_khr_id => p_khr_id,
7469 p_kle_id => p_kle_id,
7470 p_interim_tbl => l_interim_tbl,
7471 p_target => p_target_param,
7472 p_subside_yn => l_subsidies_yn,
7473 x_payment => l_payment,
7474 x_rate => l_rate);
7475
7476 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7477 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_pre_tax_irr ' || x_return_status );
7478 END IF;
7479 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7480 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7481 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7482 RAISE OKL_API.G_EXCEPTION_ERROR;
7483 END IF;
7484
7485 ElsIf ( p_rate_type = 'IMPL_INTEREST_RATE' ) Then
7486
7487 l_interim_tbl(1).cf_days := l_interim_days;
7488 l_interim_tbl(1).cf_amount := l_interim_interest;
7489 l_interim_tbl(1).cf_dpp := l_interim_dpp;
7490
7491 comp_so_iir(
7492 p_api_version => p_api_version,
7493 p_init_msg_list => p_init_msg_list,
7494 x_return_status => x_return_status,
7495 x_msg_count => x_msg_count,
7496 x_msg_data => x_msg_data,
7497 p_khr_id => p_khr_id,
7498 p_kle_id => p_kle_id,
7499 p_interim_tbl => l_interim_tbl,
7500 p_target => p_target_param,
7501 p_subside_yn => l_subsidies_yn,
7502 x_payment => l_payment,
7503 x_rate => l_rate);
7504
7505 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7506 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_iir ' || x_return_status );
7507 END IF;
7508 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7509 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7510 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7511 RAISE OKL_API.G_EXCEPTION_ERROR;
7512 END IF;
7513
7514 ElsIf ( p_rate_type = 'PRE_TAX_YIELD' ) Then
7515 -- Same as Booking Yield whenever there is no interim cost. for SO there are no interim cost
7516
7517 l_interim_tbl(1).cf_days := l_interim_days;
7518 l_interim_tbl(1).cf_amount := l_interim_interest;
7519 l_interim_tbl(1).cf_dpp := l_interim_dpp;
7520
7521 comp_so_iir(
7522 p_api_version => p_api_version,
7523 p_init_msg_list => p_init_msg_list,
7524 x_return_status => x_return_status,
7525 x_msg_count => x_msg_count,
7526 x_msg_data => x_msg_data,
7527 p_khr_id => p_khr_id,
7528 p_kle_id => p_kle_id,
7529 p_interim_tbl => l_interim_tbl,
7530 p_target => p_target_param,
7531 p_subside_yn => l_subsidies_yn,
7532 x_payment => l_payment,
7533 x_rate => l_rate);
7534
7535 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7536 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_iir ' || x_return_status );
7537 END IF;
7538 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
7539 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7540 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
7541 RAISE OKL_API.G_EXCEPTION_ERROR;
7542 END IF;
7543
7544 Else
7545
7546 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
7547 p_msg_name => 'OKL_INVALID_RATE_TYPE',
7548 p_token1 => 'RATE_TYPE',
7549 p_token1_value => p_rate_type);
7550
7551 x_return_status := OKL_API.G_RET_STS_ERROR;
7552 RAISE OKL_API.G_EXCEPTION_ERROR;
7553
7554 End If;
7555
7556 If (p_target_param = 'RATE') AND (l_payment < 0 ) THen
7557
7558 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
7559 p_msg_name => 'OKL_LLAP_CANNOT_PRICE');
7560 x_return_status := OKL_API.G_RET_STS_ERROR;
7561 RAISE OKL_API.G_EXCEPTION_ERROR;
7562
7563 End If;
7564
7565 FOR i in l_pay_tbl.FIRST..l_pay_tbl.LAST
7566 LOOP
7567 x_pay_tbl(i) := l_pay_tbl(i);
7568
7569 If ( x_pay_tbl(i).amount = -9999999 ) Then
7570 x_pay_tbl(i).amount := l_payment;
7571 elsIf ( x_pay_tbl(i).stub_amount = -9999999 ) Then
7572 x_pay_tbl(i).stub_amount := l_payment;
7573
7574 end If;
7575
7576 If ( nvl(x_overall_rate, -9999999) = -9999999 ) Then
7577 x_overall_rate := l_rate * 100.00;
7578 end If;
7579
7580 --if ( nvl(x_pay_tbl(i).rate, -9999999) <> -9999999 ) then
7581 -- x_pay_tbl(i).rate := x_pay_tbl(i).rate * 100.00;
7582 --End If;
7583
7584 END LOOP;
7585
7586 i := 0;
7587 FOR l_strms_rec in l_strms_csr
7588 LOOP
7589
7590 i := i + 1;
7591 l_stmv_tbl(i).id := l_strms_rec.ID;
7592
7593 END LOOP;
7594
7595 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7596 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' #of streams to delete - ' || i );
7597 END IF;
7598 If ( i > 0 ) Then
7599
7600 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7601 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || i || '# of streams are getting deleted ' );
7602 END IF;
7603 Okl_Streams_pub.delete_streams(
7604 p_api_version => p_api_version,
7605 p_init_msg_list => p_init_msg_list,
7606 x_return_status => x_return_status,
7607 x_msg_count => x_msg_count,
7608 x_msg_data => x_msg_data,
7609 p_stmv_tbl => l_stmv_tbl);
7610
7611 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7612 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7613 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
7614 RAISE OKL_API.G_EXCEPTION_ERROR;
7615 END IF;
7616
7617 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7618 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' DONE '|| x_return_status);
7619
7620 END IF;
7621 End If;
7622
7623 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7624 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'end' );
7625
7626 END IF;
7627 EXCEPTION
7628
7629 WHEN OKL_API.G_EXCEPTION_ERROR THEN
7630
7631 i := 0;
7632 FOR l_strms_rec in l_strms_csr
7633 LOOP
7634
7635 i := i + 1;
7636 l_stmv_tbl(i).id := l_strms_rec.ID;
7637
7638 END LOOP;
7639
7640 If ( i > 0 ) Then
7641
7642 Okl_Streams_pub.delete_streams(
7643 p_api_version => p_api_version,
7644 p_init_msg_list => p_init_msg_list,
7645 x_return_status => x_return_status,
7646 x_msg_count => x_msg_count,
7647 x_msg_data => x_msg_data,
7648 p_stmv_tbl => l_stmv_tbl);
7649
7650 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7651 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7652 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
7653 RAISE OKL_API.G_EXCEPTION_ERROR;
7654 END IF;
7655
7656 End If;
7657 x_return_status := G_RET_STS_ERROR;
7658 RAISE OKL_API.G_EXCEPTION_ERROR;
7659
7660 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
7661
7662 i := 0;
7663 FOR l_strms_rec in l_strms_csr
7664 LOOP
7665
7666 i := i + 1;
7667 l_stmv_tbl(i).id := l_strms_rec.ID;
7668
7669 END LOOP;
7670
7671 If ( i > 0 ) Then
7672
7673 Okl_Streams_pub.delete_streams(
7674 p_api_version => p_api_version,
7675 p_init_msg_list => p_init_msg_list,
7676 x_return_status => x_return_status,
7677 x_msg_count => x_msg_count,
7678 x_msg_data => x_msg_data,
7679 p_stmv_tbl => l_stmv_tbl);
7680
7681 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7682 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7683 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
7684 RAISE OKL_API.G_EXCEPTION_ERROR;
7685 END IF;
7686
7687 End If;
7688 x_return_status := G_RET_STS_UNEXP_ERROR;
7689 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7690
7691 WHEN OTHERS THEN
7692
7693 i := 0;
7694 FOR l_strms_rec in l_strms_csr
7695 LOOP
7696
7697 i := i + 1;
7698 l_stmv_tbl(i).id := l_strms_rec.ID;
7699
7700 END LOOP;
7701
7702 If ( i > 0 ) Then
7703
7704 Okl_Streams_pub.delete_streams(
7705 p_api_version => p_api_version,
7706 p_init_msg_list => p_init_msg_list,
7707 x_return_status => x_return_status,
7708 x_msg_count => x_msg_count,
7709 x_msg_data => x_msg_data,
7710 p_stmv_tbl => l_stmv_tbl);
7711
7712 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
7713 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7714 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
7715 RAISE OKL_API.G_EXCEPTION_ERROR;
7716 END IF;
7717
7718 End If;
7719 x_return_status := G_RET_STS_UNEXP_ERROR;
7720 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7721
7722 End target_parameter;
7723
7724 ---------------------------------------------------------------------------
7725 -- PROCEDURE target_pay_down
7726 --
7727 -- Description
7728 --
7729 ---------------------------------------------------------------------------
7730 PROCEDURE target_pay_down (
7731 p_khr_id IN NUMBER,
7732 p_ppd_date IN DATE,
7733 p_ppd_amount IN NUMBER,
7734 p_pay_start_date IN DATE,
7735 p_iir IN NUMBER,
7736 p_term IN NUMBER,
7737 p_frequency IN VARCHAR2,
7738 p_arrears_yn IN VARCHAR2,
7739 x_pay_amount OUT NOCOPY NUMBER,
7740 x_msg_count OUT NOCOPY NUMBER,
7741 x_msg_data OUT NOCOPY VARCHAR2,
7742 x_return_status OUT NOCOPY VARCHAR2) IS
7743
7744
7745 -- Cursor definition implies RENT must be defined at Asset Level
7746
7747 CURSOR c_asset_rvs ( kleId NUMBER ) IS
7748 SELECT DISTINCT
7749 kle.id,
7750 NVL(kle.residual_value, 0) cf_amount,
7751 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
7752 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
7753 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
7754 cle.start_date
7755 FROM okl_k_lines kle,
7756 okc_k_lines_b cle,
7757 okc_line_styles_b lse,
7758 okc_rule_groups_b rgp,
7759 okc_rules_b slh,
7760 okc_rules_b sll,
7761 okl_strm_type_b styt
7762 WHERE cle.chr_id = p_khr_id
7763 AND cle.sts_code in ( 'BOOKED', 'TERMINATED' )
7764 AND cle.lse_id = lse.id
7765 AND cle.id = kleId
7766 AND lse.lty_code = 'FREE_FORM1'
7767 AND cle.id = kle.id
7768 AND kle.id = rgp.cle_id
7769 AND rgp.rgd_code = 'LALEVL'
7770 AND rgp.id = slh.rgp_id
7771 AND slh.rule_information_category = 'LASLH'
7772 AND TO_CHAR(slh.id) = sll.object2_id1
7773 AND sll.rule_information_category = 'LASLL'
7774 AND TO_NUMBER(slh.object1_id1) = styt.id
7775 AND styt.stream_type_purpose = 'RENT'; -- Bug 4626837
7776
7777
7778 CURSOR c_asset_cost IS
7779 SELECT cle.id id,
7780 cle.start_date start_date
7781 FROM okc_k_lines_b cle,
7782 okc_line_styles_b lse
7783 WHERE cle.chr_id = p_khr_id
7784 AND cle.sts_code in ( 'BOOKED', 'TERMINATED' )
7785 AND cle.lse_id = lse.id
7786 AND lse.lty_code = 'FREE_FORM1'
7787 AND cle.id IN (
7788 SELECT distinct stm.kle_id
7789 FROM okl_streams stm,
7790 okl_strm_elements ele,
7791 okl_strm_type_b sty
7792 WHERE stm.khr_id = p_khr_id
7793 AND stm.say_code = 'CURR'
7794 AND stm.active_yn = 'Y'
7795 AND stm.sty_id = sty.id
7796 AND sty.stream_type_purpose = 'LOAN PAYMENT'
7797 AND ele.stm_id = stm.id
7798 AND ele.stream_element_date > p_ppd_date );
7799
7800 Cursor c_stub IS
7801 Select sel.id
7802 from okl_streams stm,
7803 okl_strm_elements sel
7804 where stm.khr_id = p_khr_id
7805 and stm.say_code = 'HIST'
7806 and stm.SGN_CODE = 'MANL'
7807 and stm.active_yn = 'N'
7808 and stm.purpose_code = 'STUBS'
7809 and stm.comments = 'STUB STREAMS'
7810 and sel.stm_id = stm.id;
7811
7812 l_stub_id NUMBER;
7813
7814 --------------------------
7815 -- PERFORMANCE ENHANCEMENT SECTION
7816 --------------------------
7817 TYPE cash_flow_rec_type IS RECORD (cf_amount NUMBER,
7818 cf_date DATE,
7819 cf_purpose VARCHAR2(150),
7820 cf_dpp NUMBER,
7821 cf_ppy NUMBER,
7822 cf_days NUMBER,
7823 kleId NUMBER);
7824
7825 TYPE cash_flow_tbl_type IS TABLE OF cash_flow_rec_type INDEX BY BINARY_INTEGER;
7826
7827 hdr_inflow_tbl cash_flow_tbl_type;
7828 inflow_tbl cash_flow_tbl_type;
7829 subs_inflow_tbl cash_flow_tbl_type;
7830 rv_tbl cash_flow_tbl_type;
7831 outflow_tbl cash_flow_tbl_type;
7832 subsidies_tbl cash_flow_tbl_type;
7833
7834 m BINARY_INTEGER := 0;
7835 n BINARY_INTEGER := 0;
7836 p BINARY_INTEGER := 0;
7837 q BINARY_INTEGER := 0;
7838 r BINARY_INTEGER := 0;
7839 s BINARY_INTEGER := 0;
7840
7841 cursor l_hdr_csr IS
7842 select chr.orig_system_source_code,
7843 chr.start_date,
7844 chr.end_date,
7845 chr.template_yn,
7846 chr.authoring_org_id,
7847 chr.inv_organization_id,
7848 khr.deal_type,
7849 khr.implicit_interest_rate,
7850 pdt.id pid,
7851 nvl(pdt.reporting_pdt_id, -1) report_pdt_id,
7852 chr.currency_code currency_code,
7853 khr.term_duration term
7854 from okc_k_headers_v chr,
7855 okl_k_headers khr,
7856 okl_products_v pdt
7857 where khr.id = chr.id
7858 and chr.id = p_khr_id
7859 and khr.pdt_id = pdt.id(+);
7860
7861 l_hdr_rec l_hdr_csr%ROWTYPE;
7862 --------------------------
7863 -- END PERFORMANCE ENHANCEMENT SECTION
7864 --------------------------
7865 lx_msg_count NUMBER;
7866 lx_msg_data VARCHAR2(4000);
7867 p_start_date DATE;
7868 l_end_date DATE;
7869 l_time_zero_cost NUMBER := 0;
7870 l_cost NUMBER;
7871 l_residual_value NUMBER;
7872 l_adv_payment NUMBER := 0;
7873 l_subsidy_amount NUMBER := 0;
7874 l_currency_code VARCHAR2(15);
7875 l_precision NUMBER(1);
7876
7877 l_cf_dpp NUMBER;
7878 l_cf_ppy NUMBER;
7879 l_cf_amount NUMBER;
7880 l_cf_date DATE;
7881 l_cf_arrear VARCHAR2(1);
7882 l_days_in_future NUMBER;
7883 l_periods NUMBER;
7884 l_deposit_date DATE;
7885
7886 i BINARY_INTEGER := 0;
7887 l_nthTerm BINARY_INTEGER := 0;
7888 l_pay_amount NUMBER := 0;
7889 l_iir NUMBER := p_iir/100.0;
7890 l_npv NUMBER := 0;
7891
7892 l_prev_npv NUMBER;
7893 l_prev_npv_sign NUMBER;
7894
7895 l_crossed_zero VARCHAR2(1) := 'N';
7896
7897 l_increment NUMBER := 0.1; -- 10% increment
7898 l_abs_incr NUMBER;
7899 l_prev_incr_sign NUMBER;
7900
7901 a binary_integer := 0;
7902 b binary_integer := 0;
7903
7904 lx_return_status VARCHAR2(1);
7905
7906 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'target_pay_down';
7907 p_subsidies_yn VARCHAR2(1) := 'N';
7908 l_months NUMBER;
7909 l_dpp NUMBER;
7910 l_ppy NUMBER;
7911
7912 l_blnStretch VARCHAR2(1) := 'N';
7913 xpay NUMBER := 0;
7914
7915 l_selv_tbl okl_streams_pub.selv_tbl_type;
7916 l_tmp_selv_tbl okl_streams_pub.selv_tbl_type;
7917 l_pt_tbl okl_streams_pub.selv_tbl_type;
7918 lx_selv_tbl okl_streams_pub.selv_tbl_type;
7919
7920 l_stmv_rec okl_streams_pub.stmv_rec_type;
7921 l_pt_rec okl_streams_pub.stmv_rec_type;
7922 lx_stmv_rec okl_streams_pub.stmv_rec_type;
7923
7924 l_principal_balance NUMBER;
7925 l_advance_arrears VARCHAR2(256);
7926 L_ACCUMULATED_INT NUMBER;
7927 l_term NUMBER := 0;
7928
7929 l_number_of_assets BINARY_INTEGER := 0;
7930
7931 l_day_convention_month VARCHAR2(30);
7932 l_day_convention_year VARCHAR2(30);
7933 l_days_in_year NUMBER;
7934
7935 BEGIN
7936 IF (G_DEBUG_ENABLED = 'Y') THEN
7937 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
7938 END IF;
7939
7940 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7941 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'begin' );
7942 END IF;
7943 x_return_status := G_RET_STS_SUCCESS;
7944
7945 -- Fetch the day convention ..
7946 OKL_PRICING_UTILS_PVT.get_day_convention(
7947 p_id => p_khr_id,
7948 p_source => 'ISG',
7949 x_days_in_month => l_day_convention_month,
7950 x_days_in_year => l_day_convention_year,
7951 x_return_status => lx_return_status);
7952 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7953 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
7954 END IF;
7955 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
7956 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
7957 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
7958 RAISE OKL_API.G_EXCEPTION_ERROR;
7959 END IF;
7960
7961 OPEN l_hdr_csr;
7962 FETCH l_hdr_csr INTO l_hdr_rec;
7963 CLOSE l_hdr_csr;
7964
7965 p_start_date := l_hdr_rec.start_date;
7966 l_end_date := l_hdr_rec.end_date;
7967
7968 IF p_frequency = 'M' THEN
7969 l_months := 1;
7970 l_dpp := 30;
7971 l_ppy := 12;
7972 ELSIF p_frequency = 'Q' THEN
7973 l_months := 3;
7974 l_dpp := 90;
7975 l_ppy := 4;
7976 ELSIF p_frequency = 'S' THEN
7977 l_months := 6;
7978 l_dpp := 180;
7979 l_ppy := 2;
7980 ELSIF p_frequency = 'A' THEN
7981 l_months := 12;
7982 l_dpp := 360;
7983 l_ppy := 1;
7984 END IF;
7985
7986 If ( p_arrears_yn = 'Y' ) then
7987 l_advance_arrears := 'ARREARS';
7988 Else
7989 l_advance_arrears := 'ADVANCE';
7990 END if;
7991
7992 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
7993 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' getting asset cost ' );
7994 END IF;
7995 FOR l_asset_cost IN c_asset_cost LOOP
7996
7997 l_number_of_assets := l_number_of_assets + 1;
7998
7999 OKL_STREAM_GENERATOR_PVT.get_sched_principal_bal(
8000 p_api_version => 1.0,
8001 p_init_msg_list => 'T',
8002 p_khr_id => p_khr_id,
8003 p_kle_id => l_asset_cost.id,
8004 p_date => p_pay_start_date,
8005 x_principal_balance => l_principal_balance,
8006 x_accumulated_int => l_accumulated_int,
8007 x_return_status => x_return_status,
8008 x_msg_count => x_msg_count,
8009 x_msg_data => x_msg_data);
8010
8011 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8012 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' l_principal_balance ' || l_principal_balance
8013 || ' l_accumulated_int '||l_accumulated_int|| x_return_status);
8014 END IF;
8015 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8016 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8017 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8018 RAISE OKL_API.G_EXCEPTION_ERROR;
8019 END IF;
8020
8021 l_npv := l_npv - NVL(l_principal_balance, 0);
8022
8023 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_ppd_date,
8024 p_days_in_month => l_day_convention_month,
8025 p_days_in_year => l_day_convention_year,
8026 p_end_date => p_pay_start_date,
8027 p_arrears => 'N',
8028 x_return_status => lx_return_status);
8029
8030 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8031 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8032 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8033 RAISE OKL_API.G_EXCEPTION_ERROR;
8034 END IF;
8035
8036 l_periods := l_days_in_future / l_dpp;
8037 l_npv := l_npv + l_accumulated_int / POWER((1 + l_iir/l_ppy), l_periods);
8038
8039 lx_selv_tbl.DELETE;
8040 -- Commented the code by djanaswa for bug 6007644
8041 /*OKL_STREAM_GENERATOR_PVT.get_stream_elements(
8042 p_start_date => p_pay_start_date,
8043 p_periods => p_term,
8044 p_frequency => p_frequency,
8045 p_structure => 0,
8046 p_advance_or_arrears => l_advance_arrears,
8047 p_amount => 0,
8048 p_stub_days => NULL,
8049 p_stub_amount => NULL,
8050 p_currency_code => l_hdr_rec.currency_code,
8051 p_khr_id => p_khr_id,
8052 p_kle_id => l_asset_cost.id,
8053 p_purpose_code => NULL,
8054 x_selv_tbl => lx_selv_tbl,
8055 x_pt_tbl => l_pt_tbl,
8056 x_return_status => x_return_status,
8057 x_msg_count => x_msg_count,
8058 x_msg_data => x_msg_data);
8059
8060 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8061 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8062 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
8063 RAISE OKL_API.G_EXCEPTION_ERROR;
8064 END IF; */
8065 -- end djanaswa
8066
8067
8068 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8069 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' stream elements ' || lx_selv_tbl.COUNT );
8070
8071 END IF;
8072 FOR i in lx_selv_tbl.FIRST..lx_selv_tbl.LAST
8073 LOOP
8074
8075 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_ppd_date,
8076 p_days_in_month => l_day_convention_month,
8077 p_days_in_year => l_day_convention_year,
8078 p_end_date => lx_selv_tbl(i).stream_element_date,
8079 p_arrears => p_arrears_yn,
8080 x_return_status => lx_return_status);
8081
8082 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8083 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8084 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8085 RAISE OKL_API.G_EXCEPTION_ERROR;
8086 END IF;
8087
8088 l_periods := l_days_in_future / l_dpp;
8089 l_term := l_term + 1 / POWER((1 + l_iir/l_ppy), l_periods);
8090
8091 END LOOP;
8092
8093 END LOOP;
8094
8095 l_npv := l_npv + p_ppd_amount;
8096
8097 If ( l_term = 0 ) Then
8098 l_term := 0.0001;
8099 End If;
8100 l_pay_amount := -1 * l_npv / l_term;
8101
8102 x_pay_amount := l_pay_amount * l_number_of_assets;
8103
8104 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8105 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'end' );
8106
8107 END IF;
8108 EXCEPTION
8109
8110 WHEN OKL_API.G_EXCEPTION_ERROR THEN
8111
8112 x_return_status := G_RET_STS_ERROR;
8113
8114 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
8115
8116 x_return_status := G_RET_STS_UNEXP_ERROR;
8117
8118 WHEN OTHERS THEN
8119
8120 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
8121 p_msg_name => G_DB_ERROR,
8122 p_token1 => G_PROG_NAME_TOKEN,
8123 p_token1_value => l_prog_name,
8124 p_token2 => G_SQLCODE_TOKEN,
8125 p_token2_value => sqlcode,
8126 p_token3 => G_SQLERRM_TOKEN,
8127 p_token3_value => sqlerrm);
8128
8129 x_return_status := G_RET_STS_UNEXP_ERROR;
8130
8131 END target_pay_down;
8132
8133 ---------------------------------------------------------------------------
8134 -- PROCEDURE compute_iir
8135 --
8136 -- Description
8137 --
8138 ---------------------------------------------------------------------------
8139 PROCEDURE compute_iir (p_khr_id IN NUMBER,
8140 p_start_date IN DATE,
8141 p_term_duration IN NUMBER,
8142 p_interim_tbl IN interim_interest_tbl_type,
8143 p_subsidies_yn IN VARCHAR2,
8144 p_initial_iir IN NUMBER DEFAULT NULL,
8145 x_iir OUT NOCOPY NUMBER,
8146 x_return_status OUT NOCOPY VARCHAR2) IS
8147
8148 CURSOR c_hdr_inflows IS
8149 SELECT DISTINCT
8150 sel.id id,
8151 sel.amount cf_amount,
8152 sel.stream_element_date cf_date,
8153 sel.comments cf_arrear,
8154 sty.stream_type_purpose cf_purpose,
8155 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
8156 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year
8157 FROM okl_streams stm,
8158 okl_strm_type_b sty,
8159 okl_strm_elements sel,
8160 okc_rules_b sll,
8161 okc_rules_b slh,
8162 okc_rule_groups_b rgp
8163 WHERE stm.khr_id = p_khr_id
8164 AND stm.say_code = 'WORK'
8165 AND stm.purpose_code IS NULL
8166 AND stm.sty_id = sty.id
8167 AND stm.id = sel.stm_id
8168 AND sel.comments IS NOT NULL
8169 AND stm.khr_id = rgp.dnz_chr_id
8170 AND rgp.cle_id IS NULL
8171 AND rgp.rgd_code = 'LALEVL'
8172 AND rgp.id = slh.rgp_id
8173 AND slh.rule_information_category = 'LASLH'
8174 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
8175 AND TO_CHAR(slh.id) = sll.object2_id1
8176 AND sll.rule_information_category = 'LASLL';
8177
8178 Cursor c_link_pmnts( chrId NUMBER, kleId NUMBER ) IS
8179 Select 'Y' What
8180 from dual
8181 Where Exists(Select crl.id slh_id
8182 From OKC_RULE_GROUPS_B crg,
8183 OKC_RULES_B crl,
8184 okc_K_lines_b cle_lnk,
8185 okl_K_lines kle_roll
8186 Where crl.rgp_id = crg.id
8187 and crg.RGD_CODE = 'LALEVL'
8188 and crl.RULE_INFORMATION_CATEGORY = 'LASLL'
8189 and crg.dnz_chr_id = chrId
8190 and crg.cle_id = kleId
8191 and crg.cle_id = cle_lnk.id
8192 and cle_lnk.cle_id = kle_roll.id
8193 and kle_roll.fee_type = 'FINANCED');
8194
8195 r_link_pmnts c_link_pmnts%ROWTYPE;
8196
8197 CURSOR c_inflows IS
8198 SELECT DISTINCT
8199 sel.id id,
8200 sel.amount cf_amount,
8201 sel.stream_element_date cf_date,
8202 sel.comments cf_arrear,
8203 sty.stream_type_purpose cf_purpose,
8204 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
8205 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year
8206 FROM okl_streams stm,
8207 okl_strm_type_b sty,
8208 okl_strm_elements sel,
8209 okc_k_lines_b cle,
8210 okc_line_styles_b lse,
8211 okc_rules_b sll,
8212 okc_rules_b slh,
8213 okc_rule_groups_b rgp
8214 WHERE stm.khr_id = p_khr_id
8215 AND stm.say_code = 'WORK'
8216 AND stm.purpose_code IS NULL
8217 AND stm.sty_id = sty.id
8218 AND sty.stream_type_purpose NOT LIKE 'ESTIMATED_PROPERTY_TAX'
8219 AND stm.id = sel.stm_id
8220 AND sel.comments IS NOT NULL
8221 AND stm.kle_id = cle.id
8222 AND NOT EXISTS (SELECT 1
8223 FROM okc_rule_groups_b rgp2
8224 WHERE rgp2.dnz_chr_id = p_khr_id
8225 AND rgp2.cle_id = cle.id
8226 AND rgp2.rgd_code = 'LAPSTH')
8227 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
8228 AND cle.lse_id = lse.id
8229 AND lse.lty_code = 'FREE_FORM1'
8230 AND cle.id = rgp.cle_id
8231 AND rgp.rgd_code = 'LALEVL'
8232 AND rgp.id = slh.rgp_id
8233 AND slh.rule_information_category = 'LASLH'
8234 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
8235 AND TO_CHAR(slh.id) = sll.object2_id1
8236 AND sll.rule_information_category = 'LASLL';
8237
8238 CURSOR c_fee_inflows IS
8239 SELECT DISTINCT
8240 sel.id id,
8241 sel.amount cf_amount,
8242 sel.stream_element_date cf_date,
8243 sel.comments cf_arrear,
8244 sty.stream_type_purpose cf_purpose,
8245 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
8246 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
8247 cle.id kleId,
8248 lse.lty_code,
8249 kle.fee_type
8250 FROM okl_streams stm,
8251 okl_strm_type_b sty,
8252 okl_strm_elements sel,
8253 okc_k_lines_b cle,
8254 okl_k_lines kle,
8255 okc_line_styles_b lse,
8256 okc_rules_b sll,
8257 okc_rules_b slh,
8258 okc_rule_groups_b rgp
8259 WHERE stm.khr_id = p_khr_id
8260 AND stm.say_code = 'WORK'
8261 AND stm.purpose_code IS NULL
8262 AND stm.sty_id = sty.id
8263 AND sty.stream_type_purpose NOT LIKE 'ESTIMATED_PROPERTY_TAX'
8264 AND stm.id = sel.stm_id
8265 AND sel.comments IS NOT NULL
8266 AND stm.kle_id = cle.id
8267 AND cle.id = kle.id
8268 AND NOT EXISTS (SELECT 1
8269 FROM okc_rule_groups_b rgp2
8270 WHERE rgp2.dnz_chr_id = p_khr_id
8271 AND rgp2.cle_id = cle.id
8272 AND rgp2.rgd_code = 'LAPSTH')
8273 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
8274 AND cle.lse_id = lse.id
8275 AND lse.lty_code IN ('FEE', 'LINK_FEE_ASSET')
8276 AND cle.id = rgp.cle_id
8277 AND rgp.rgd_code = 'LALEVL'
8278 AND rgp.id = slh.rgp_id
8279 AND slh.rule_information_category = 'LASLH'
8280 AND slh.object1_id1 = TO_CHAR(stm.sty_id)
8281 AND TO_CHAR(slh.id) = sll.object2_id1
8282 AND sll.rule_information_category = 'LASLL';
8283
8284 r_fee_inflows c_fee_inflows%ROWTYPE;
8285
8286 -- Cursor definition implies RENT must be defined at Asset Level
8287
8288 CURSOR c_asset_rvs IS
8289 SELECT DISTINCT
8290 kle.id,
8291 NVL(kle.residual_value, 0) cf_amount,
8292 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
8293 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
8294 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
8295 cle.start_date,
8296 cle.date_terminated,
8297 cle.sts_code
8298 FROM okl_k_lines kle,
8299 okc_k_lines_b cle,
8300 okc_line_styles_b lse,
8301 okc_rule_groups_b rgp,
8302 okc_rules_b slh,
8303 okc_rules_b sll,
8304 okl_strm_type_b sty
8305 WHERE cle.chr_id = p_khr_id
8306 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED') -- Bug 5011438
8307 AND cle.lse_id = lse.id
8308 AND lse.lty_code = 'FREE_FORM1'
8309 AND cle.id = kle.id
8310 AND kle.id = rgp.cle_id
8311 AND rgp.rgd_code = 'LALEVL'
8312 AND rgp.id = slh.rgp_id
8313 AND slh.rule_information_category = 'LASLH'
8314 AND TO_CHAR(slh.id) = sll.object2_id1
8315 AND sll.rule_information_category = 'LASLL'
8316 AND slh.object1_id1 = TO_CHAR(sty.id)
8317 AND sty.stream_type_purpose = 'RENT';
8318
8319 CURSOR c_deposit_date IS
8320 SELECT FND_DATE.canonical_to_date(rule_information5)
8321 FROM okc_rules_b
8322 WHERE dnz_chr_id = p_khr_id
8323 AND rule_information_category = 'LASDEP';
8324
8325 /* CURSOR c_asset_cost IS
8326 SELECT cle.id id,
8327 cle.start_date start_date,
8328 kle.capital_amount,
8329 kle.capitalized_interest,
8330 kle.date_funding_expected
8331 FROM okc_k_lines_b cle,
8332 okl_K_lines kle,
8333 okc_line_styles_b lse
8334 WHERE cle.chr_id = p_khr_id
8335 AND cle.id = kle.id
8336 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
8337 AND cle.lse_id = lse.id
8338 AND lse.lty_code = 'FREE_FORM1';
8339 */
8340 -- Bug 5287279 : 08-Jun-2006 : kbbhavsa
8341 -- c_asset_cost cursor modified by including distinct
8342 CURSOR c_asset_cost IS
8343 SELECT DISTINCT cle.id id,
8344 cle.start_date start_date,
8345 kle.capital_amount,
8346 kle.capitalized_interest,
8347 kle.date_funding_expected,
8348 DECODE(sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
8349 DECODE(sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
8350 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
8351 cle.date_terminated,
8352 cle.sts_code
8353 FROM okl_k_lines kle,
8354 okc_k_lines_b cle,
8355 okc_line_styles_b lse,
8356 okc_rule_groups_b rgp,
8357 okc_rules_b slh,
8358 okc_rules_b sll,
8359 okl_strm_type_b sty
8360 WHERE cle.chr_id = p_khr_id
8361 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED') -- Bug 5011438
8362 AND cle.lse_id = lse.id
8363 AND lse.lty_code = 'FREE_FORM1'
8364 AND cle.id = kle.id
8365 AND kle.id = rgp.cle_id
8366 AND rgp.rgd_code = 'LALEVL'
8367 AND rgp.id = slh.rgp_id
8368 AND slh.rule_information_category = 'LASLH'
8369 AND TO_CHAR(slh.id) = sll.object2_id1
8370 AND sll.rule_information_category = 'LASLL'
8371 AND slh.object1_id1 = TO_CHAR(sty.id)
8372 AND sty.stream_type_purpose = 'RENT';
8373
8374 CURSOR c_fee_cost IS
8375 SELECT NVL(kle.amount, 0) amount,
8376 cle.start_date,
8377 cle.id kleid,
8378 lse.lty_code lty_code,
8379 kle.fee_type fee_type
8380 FROM okl_k_lines kle,
8381 okc_k_lines_b cle,
8382 okc_line_styles_b lse,
8383 okc_k_items cim,
8384 okl_strm_type_b sty
8385 WHERE cle.chr_id = p_khr_id
8386 AND cle.lse_id = lse.id
8387 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
8388 AND kle.fee_type not in ( 'SECDEPOSIT', 'INCOME' )
8389 AND lse.lty_code in ( 'FEE', 'LINK_FEE_ASSET')
8390 AND cle.id = kle.id
8391 AND cle.id = cim.cle_id
8392 AND cim.jtot_object1_code = 'OKL_STRMTYP'
8393 AND cim.object1_id1 = sty.id
8394 AND sty.version = '1.0'
8395 AND NVL(sty.capitalize_yn,'N') <> 'Y'
8396 AND NOT EXISTS (SELECT 1
8397 FROM okc_rule_groups_b rgp
8398 WHERE rgp.cle_id = cle.id
8399 AND rgp.rgd_code = 'LAPSTH')
8400 AND NOT EXISTS (SELECT 1
8401 FROM okc_rule_groups_b rgp,
8402 okc_rules_b rul,
8403 okc_rules_b rul2
8404 WHERE rgp.cle_id = cle.id
8405 AND rgp.rgd_code = 'LAFEXP'
8406 AND rgp.id = rul.rgp_id
8407 AND rgp.id = rul2.rgp_id
8408 AND rul.rule_information_category = 'LAFEXP'
8409 AND rul2.rule_information_category = 'LAFREQ'
8410 AND rul.rule_information1 IS NOT NULL
8411 AND rul.rule_information2 IS NOT NULL
8412 AND rul2.object1_id1 IS NOT NULL);
8413
8414 l_fee_cost c_fee_cost%ROWTYPE;
8415
8416 CURSOR c_rec_exp IS
8417 SELECT TO_NUMBER(rul.rule_information1) periods,
8418 TO_NUMBER(rul.rule_information2) cf_amount,
8419 DECODE(rul2.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) cf_dpp,
8420 DECODE(rul2.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) cf_ppy,
8421 DECODE(rul2.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) cf_mpp,
8422 cle.start_date start_date,
8423 kle.fee_type
8424 FROM okc_rules_b rul,
8425 okc_rules_b rul2,
8426 okc_rule_groups_b rgp,
8427 okc_k_lines_b cle,
8428 okl_k_lines kle,
8429 okc_line_styles_b lse
8430 WHERE cle.chr_id = p_khr_id
8431 AND cle.sts_code IN ('PASSED', 'COMPLETE', 'TERMINATED')
8432 AND cle.lse_id = lse.id
8433 AND lse.lty_code = 'FEE'
8434 AND NOT EXISTS (SELECT 1
8435 FROM okc_rule_groups_b rgp
8436 WHERE rgp.cle_id = cle.id
8437 AND rgp.rgd_code = 'LAPSTH')
8438 AND cle.id = rgp.cle_id
8439 AND cle.id = kle.id
8440 AND rgp.rgd_code = 'LAFEXP'
8441 AND rgp.id = rul.rgp_id
8442 AND rgp.id = rul2.rgp_id
8443 AND rul.rule_information_category = 'LAFEXP'
8444 AND rul2.rule_information_category = 'LAFREQ'
8445 AND rul.rule_information1 IS NOT NULL
8446 AND rul.rule_information2 IS NOT NULL
8447 AND rul2.object1_id1 IS NOT NULL;
8448
8449 r_rec_exp c_rec_exp%ROWTYPE;
8450
8451 --------------------------
8452 -- PERFORMANCE ENHANCEMENT SECTION
8453 --------------------------
8454 TYPE cash_flow_rec_type IS RECORD (cf_amount NUMBER,
8455 cf_date DATE,
8456 cf_purpose VARCHAR2(150),
8457 cf_dpp NUMBER,
8458 cf_ppy NUMBER,
8459 cf_days NUMBER,
8460 kleId NUMBER);
8461
8462 TYPE cash_flow_tbl_type IS TABLE OF cash_flow_rec_type INDEX BY BINARY_INTEGER;
8463
8464 hdr_inflow_tbl cash_flow_tbl_type;
8465 inflow_tbl cash_flow_tbl_type;
8466 subs_inflow_tbl cash_flow_tbl_type;
8467 rv_tbl cash_flow_tbl_type;
8468 outflow_tbl cash_flow_tbl_type;
8469 subsidies_tbl cash_flow_tbl_type;
8470 rec_exp_tbl cash_flow_tbl_type;
8471
8472 m BINARY_INTEGER := 0;
8473 n BINARY_INTEGER := 0;
8474 p BINARY_INTEGER := 0;
8475 q BINARY_INTEGER := 0;
8476 r BINARY_INTEGER := 0;
8477 s BINARY_INTEGER := 0;
8478
8479 --------------------------
8480 -- END PERFORMANCE ENHANCEMENT SECTION
8481 --------------------------
8482 lx_msg_count NUMBER;
8483 lx_msg_data VARCHAR2(4000);
8484 l_end_date DATE := ADD_MONTHS(p_start_date, p_term_duration) - 1;
8485 l_time_zero_cost NUMBER := 0;
8486 l_cost NUMBER;
8487 l_residual_value NUMBER;
8488 l_adv_payment NUMBER := 0;
8489 l_subsidy_amount NUMBER := 0;
8490 l_currency_code VARCHAR2(15);
8491 l_precision NUMBER(1);
8492
8493 l_cf_dpp NUMBER;
8494 l_cf_ppy NUMBER;
8495 l_cf_amount NUMBER;
8496 l_cf_date DATE;
8497 l_cf_arrear VARCHAR2(1);
8498 l_days_in_future NUMBER;
8499 l_periods NUMBER;
8500 l_deposit_date DATE;
8501
8502 i BINARY_INTEGER := 0;
8503 l_iir NUMBER := nvl(p_initial_iir, 0);
8504
8505 l_npv NUMBER;
8506 l_iir_limit NUMBER := NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000)/100;
8507
8508 l_prev_npv NUMBER;
8509 l_prev_npv_sign NUMBER;
8510
8511 l_crossed_zero VARCHAR2(1) := 'N';
8512
8513 l_increment NUMBER := 1.1;
8514 l_abs_incr NUMBER;
8515 l_prev_incr_sign NUMBER;
8516
8517 --DEBUG
8518 a binary_integer := 0;
8519 b binary_integer := 0;
8520
8521 lx_return_status VARCHAR2(1);
8522
8523 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'compute_iir';
8524
8525 l_additional_parameters OKL_EXECUTE_FORMULA_PUB.ctxt_val_tbl_type;
8526
8527 -- Added by RGOOTY
8528 l_prev_iir NUMBER := 0;
8529 l_positive_npv_iir NUMBER := 0;
8530 l_negative_npv_iir NUMBER := 0;
8531 l_positive_npv NUMBER := 0;
8532 l_negative_npv NUMBER := 0;
8533
8534 l_iir_decided VARCHAR2(1) := 'F';
8535
8536 l_day_convention_month VARCHAR2(30);
8537 l_day_convention_year VARCHAR2(30);
8538 l_days_in_year NUMBER;
8539
8540 BEGIN
8541 IF (G_DEBUG_ENABLED = 'Y') THEN
8542 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
8543 END IF;
8544
8545 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8546 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'begin' );
8547 END IF;
8548 x_return_status := G_RET_STS_SUCCESS;
8549
8550 -- Fetch the day convention ..
8551 OKL_PRICING_UTILS_PVT.get_day_convention(
8552 p_id => p_khr_id,
8553 p_source => 'ISG',
8554 x_days_in_month => l_day_convention_month,
8555 x_days_in_year => l_day_convention_year,
8556 x_return_status => lx_return_status);
8557 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8558 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
8559 END IF;
8560 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
8561 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8562 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
8563 RAISE OKL_API.G_EXCEPTION_ERROR;
8564 END IF;
8565 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8566 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' Computing IIR on the date ' || p_start_Date );
8567 END IF;
8568 FOR l_asset_cost IN c_asset_cost LOOP
8569 --Modified IF clause by RGOOTY for bug 7577105
8570 IF(NVL(l_asset_cost.date_funding_expected, l_asset_cost.start_date) = p_start_date)
8571 THEN
8572 l_cost := nvl(l_asset_cost.capital_amount, 0) + nvl(l_asset_cost.capitalized_interest,0);
8573 l_time_zero_cost := l_time_zero_cost + NVL(l_cost, 0);
8574 END IF;
8575 END LOOP;
8576
8577
8578 FOR l_fee_cost IN c_fee_cost LOOP
8579
8580 If l_fee_cost.lty_code = 'LINK_FEE_ASSET' THEN
8581 OPEN c_link_pmnts( p_khr_id, l_fee_cost.kleid);
8582 FETCH c_link_pmnts INTO r_link_pmnts;
8583 CLOSE c_link_pmnts;
8584 ENd If;
8585
8586 If ( (l_fee_cost.lty_code <> 'LINK_FEE_ASSET' AND l_fee_cost.fee_type = 'FINANCED') OR
8587 (l_fee_cost.lty_code = 'LINK_FEE_ASSET' and nvl(r_link_pmnts.What,'N')='Y') ) THen
8588 IF l_fee_cost.start_date <= p_start_date THEN
8589
8590 l_time_zero_cost := l_time_zero_cost + l_fee_cost.amount;
8591
8592 END IF;
8593 END IF;
8594
8595 END LOOP;
8596
8597
8598 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8599 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '1/ TIME ZERO COST = ' || round(nvl(l_time_zero_cost, 0), 2) );
8600 END IF;
8601 FOR l_hdr_inflow IN c_hdr_inflows LOOP
8602 m := m + 1;
8603 hdr_inflow_tbl(m).cf_amount := l_hdr_inflow.cf_amount;
8604 hdr_inflow_tbl(m).cf_date := l_hdr_inflow.cf_date;
8605 hdr_inflow_tbl(m).cf_purpose := l_hdr_inflow.cf_purpose;
8606 hdr_inflow_tbl(m).cf_dpp := l_hdr_inflow.days_per_period;
8607 hdr_inflow_tbl(m).cf_ppy := l_hdr_inflow.periods_per_year;
8608
8609 hdr_inflow_tbl(m).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
8610 p_days_in_month => l_day_convention_month,
8611 p_days_in_year => l_day_convention_year,
8612 p_end_date => l_hdr_inflow.cf_date,
8613 p_arrears => l_hdr_inflow.cf_arrear,
8614 x_return_status => lx_return_status);
8615
8616 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8617 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8618 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8619 RAISE OKL_API.G_EXCEPTION_ERROR;
8620 END IF;
8621 END LOOP;
8622 -- Third
8623 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8624 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '2/ Handling the Asset level inflows ' );
8625 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Date | Days | Amount | Purpose | DPP | PPY ' );
8626 END IF;
8627 FOR l_inflow IN c_inflows LOOP
8628 n := n + 1;
8629 inflow_tbl(n).cf_amount := l_inflow.cf_amount;
8630 inflow_tbl(n).cf_date := l_inflow.cf_date;
8631 inflow_tbl(n).cf_purpose := l_inflow.cf_purpose;
8632 inflow_tbl(n).cf_dpp := l_inflow.days_per_period;
8633 inflow_tbl(n).cf_ppy := l_inflow.periods_per_year;
8634 inflow_tbl(n).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
8635 p_days_in_month => l_day_convention_month,
8636 p_days_in_year => l_day_convention_year,
8637 p_end_date => l_inflow.cf_date,
8638 p_arrears => l_inflow.cf_arrear,
8639 x_return_status => lx_return_status);
8640
8641 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8642 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8643 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8644 RAISE OKL_API.G_EXCEPTION_ERROR;
8645 END IF;
8646 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8647 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || inflow_tbl(n).cf_date || '| ' || inflow_tbl(n).cf_days || ' | ' || inflow_tbl(n).cf_amount ||' | ' ||
8648 inflow_tbl(n).cf_dpp || ' | ' || inflow_tbl(n).cf_ppy );
8649 END IF;
8650 END LOOP;
8651
8652 FOR l_fee_inflow IN c_fee_inflows LOOP
8653
8654 If l_fee_inflow.lty_code = 'LINK_FEE_ASSET' THEN
8655 OPEN c_link_pmnts( p_khr_id, l_fee_inflow.kleid);
8656 FETCH c_link_pmnts INTO r_link_pmnts;
8657 CLOSE c_link_pmnts;
8658 ENd If;
8659
8660 If ( (l_fee_inflow.lty_code <> 'LINK_FEE_ASSET' AND l_fee_inflow.fee_type = 'FINANCED') OR
8661 (l_fee_inflow.lty_code = 'LINK_FEE_ASSET' and nvl(r_link_pmnts.What,'N')='Y') ) THen
8662
8663 n := n + 1;
8664 inflow_tbl(n).cf_amount := l_fee_inflow.cf_amount;
8665 inflow_tbl(n).cf_date := l_fee_inflow.cf_date;
8666 inflow_tbl(n).cf_purpose := l_fee_inflow.cf_purpose;
8667 inflow_tbl(n).cf_dpp := l_fee_inflow.days_per_period;
8668 inflow_tbl(n).cf_ppy := l_fee_inflow.periods_per_year;
8669
8670 inflow_tbl(n).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
8671 p_days_in_month => l_day_convention_month,
8672 p_days_in_year => l_day_convention_year,
8673 p_end_date => l_fee_inflow.cf_date,
8674 p_arrears => l_fee_inflow.cf_arrear,
8675 x_return_status => lx_return_status);
8676
8677 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8678 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8679 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8680 RAISE OKL_API.G_EXCEPTION_ERROR;
8681 END IF;
8682
8683 END IF;
8684 -- Added for approximation
8685 G_TOT_INFLOW_AMT := G_TOT_INFLOW_AMT + l_fee_inflow.cf_amount;
8686 --print( 'Inflows amount ' || l_inflow.cf_amount);
8687 END LOOP;
8688
8689
8690
8691 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8692 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '2/ Handling the Residual Values ' );
8693 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Date | Days | Amount | Purpose | DPP | PPY ' );
8694 END IF;
8695 FOR l_asset_rv IN c_asset_rvs LOOP
8696 p := p + 1;
8697 If l_asset_rv.sts_code = 'TERMINATED' Then
8698 rv_tbl(p).cf_amount := OKL_AM_UTIL_PVT.get_actual_asset_residual(p_khr_id => p_khr_id,
8699 p_kle_id => l_asset_rv.id); --bug# 4184579
8700 rv_tbl(p).cf_date := l_asset_rv.date_terminated;
8701 rv_tbl(p).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
8702 p_days_in_month => l_day_convention_month,
8703 p_days_in_year => l_day_convention_year,
8704 p_end_date => l_asset_rv.date_terminated,
8705 p_arrears => 'Y',
8706 x_return_status => lx_return_status);
8707 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8708 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8709 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8710 RAISE OKL_API.G_EXCEPTION_ERROR;
8711 END IF;
8712 ELSE
8713 rv_tbl(p).cf_amount := l_asset_rv.cf_amount;
8714 rv_tbl(p).cf_date := l_end_date;
8715
8716 rv_tbl(p).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
8717 p_days_in_month => l_day_convention_month,
8718 p_days_in_year => l_day_convention_year,
8719 p_end_date => l_end_date,
8720 p_arrears => 'Y',
8721 x_return_status => lx_return_status);
8722
8723 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8724 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8725 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8726 RAISE OKL_API.G_EXCEPTION_ERROR;
8727 END IF;
8728
8729 END IF;
8730 rv_tbl(p).cf_dpp := l_asset_rv.days_per_period;
8731 rv_tbl(p).cf_ppy := l_asset_rv.periods_per_year;
8732 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8733 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || rv_tbl(p).cf_date || '| ' || rv_tbl(p).cf_days || ' | ' || rv_tbl(p).cf_amount ||' | ' ||
8734 rv_tbl(p).cf_dpp || ' | ' || rv_tbl(p).cf_ppy );
8735 END IF;
8736 END LOOP;
8737
8738
8739 FOR l_outflow IN c_fee_cost LOOP
8740
8741 If l_fee_cost.lty_code = 'LINK_FEE_ASSET' THEN
8742 OPEN c_link_pmnts( p_khr_id, l_fee_cost.kleid);
8743 FETCH c_link_pmnts INTO r_link_pmnts;
8744 CLOSE c_link_pmnts;
8745 ENd If;
8746
8747 If ( (l_fee_cost.lty_code <> 'LINK_FEE_ASSET' AND l_fee_cost.fee_type = 'FINANCED') OR
8748 (l_fee_cost.lty_code = 'LINK_FEE_ASSET' and nvl(r_link_pmnts.What,'N')='Y') ) THen
8749
8750 IF l_outflow.start_date > p_start_date THEN
8751
8752 q := q + 1;
8753 outflow_tbl(q).cf_amount := -(l_outflow.amount);
8754 outflow_tbl(q).cf_date := l_outflow.start_date;
8755 outflow_tbl(q).cf_dpp := 1;
8756 outflow_tbl(q).cf_ppy := 360;
8757
8758 outflow_tbl(q).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
8759 p_days_in_month => l_day_convention_month,
8760 p_days_in_year => l_day_convention_year,
8761 p_end_date => l_outflow.start_date,
8762 p_arrears => 'N',
8763 x_return_status => lx_return_status);
8764
8765 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8766 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8767 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8768 RAISE OKL_API.G_EXCEPTION_ERROR;
8769 END IF;
8770
8771 END IF;
8772
8773 END IF;
8774 END LOOP;
8775
8776 If ( p_subsidies_yn = 'Y' ) Then
8777 subsidies_tbl(1).cf_amount := 0;
8778 End If;
8779
8780 FOR l_outflow IN c_asset_cost LOOP
8781 -- Handling the case when contract rebooking has happened and an asset has been
8782 -- added after the start date of the contract but whose funding starts on the revision date.
8783 --Modified IF clause by bkatraga for bug 7577105
8784 IF NVL(l_outflow.date_funding_expected, l_outflow.start_date) > p_start_date
8785 THEN
8786 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8787 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '!!! Handling the Assets who are in effect later than the start date !!!');
8788 END IF;
8789 q := q + 1;
8790 outflow_tbl(q).cf_amount := nvl(l_outflow.capital_amount, 0);
8791 outflow_tbl(q).cf_amount := -(outflow_tbl(q).cf_amount);
8792 outflow_tbl(q).cf_date := nvl(l_outflow.date_funding_expected, l_outflow.start_date);
8793 outflow_tbl(q).cf_dpp := l_outflow.days_per_period;
8794 outflow_tbl(q).cf_ppy := l_outflow.periods_per_year;
8795 outflow_tbl(q).cf_days :=
8796 OKL_PRICING_UTILS_PVT.get_day_count(
8797 p_start_date => p_start_date,
8798 p_days_in_month => l_day_convention_month,
8799 p_days_in_year => l_day_convention_year,
8800 p_end_date => outflow_tbl(q).cf_date,
8801 p_arrears => 'N',
8802 x_return_status => lx_return_status);
8803 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8804 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8805 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8806 RAISE OKL_API.G_EXCEPTION_ERROR;
8807 END IF;
8808 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8809 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || outflow_tbl(q).cf_date || '| ' || outflow_tbl(q).cf_days || ' | ' ||
8810 outflow_tbl(q).cf_amount ||' | ' || outflow_tbl(q).cf_dpp || ' | ' || outflow_tbl(q).cf_ppy );
8811 END IF;
8812 ELSIF l_outflow.date_funding_expected < p_start_date THEN
8813 --Removed = in the above if clause by RGOOTY for bug 7577105
8814 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8815 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '!!!!! Handling the Assets who are in effect earlier than the start date !!!!');
8816 END IF;
8817 q := q + 1;
8818 outflow_tbl(q).cf_amount := nvl(l_outflow.capital_amount, 0);
8819 outflow_tbl(q).cf_amount := -(outflow_tbl(q).cf_amount);
8820 outflow_tbl(q).cf_date := l_outflow.date_funding_expected;
8821 outflow_tbl(q).cf_dpp := l_outflow.days_per_period;
8822 outflow_tbl(q).cf_ppy := l_outflow.periods_per_year;
8823 outflow_tbl(q).cf_days :=
8824 OKL_PRICING_UTILS_PVT.get_day_count(
8825 p_start_date => l_outflow.date_funding_expected,
8826 p_days_in_month => l_day_convention_month,
8827 p_days_in_year => l_day_convention_year,
8828 p_end_date => p_start_date,
8829 p_arrears => 'N',
8830 x_return_status => lx_return_status);
8831 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8832 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8833 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8834 RAISE OKL_API.G_EXCEPTION_ERROR;
8835 END IF;
8836 outflow_tbl(q).cf_days := -1 * outflow_tbl(q).cf_days;
8837 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
8838 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || outflow_tbl(q).cf_date || '| ' || outflow_tbl(q).cf_days || ' | ' ||
8839 outflow_tbl(q).cf_amount ||' | ' || outflow_tbl(q).cf_dpp || ' | ' || outflow_tbl(q).cf_ppy );
8840 END IF;
8841 END IF;
8842
8843 If ( p_subsidies_yn = 'Y' ) Then
8844 -- Subsidies Begin
8845 OKL_SUBSIDY_PROCESS_PVT.get_asset_subsidy_amount(
8846 p_api_version => G_API_VERSION,
8847 p_init_msg_list => G_FALSE,
8848 x_return_status => lx_return_status,
8849 x_msg_data => lx_msg_data,
8850 x_msg_count => lx_msg_count,
8851 p_asset_cle_id => l_outflow.id,
8852 x_subsidy_amount=> l_subsidy_amount);
8853
8854 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8855 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8856 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8857 RAISE OKL_API.G_EXCEPTION_ERROR;
8858 END IF;
8859
8860 subsidies_tbl(1).cf_amount := nvl(subsidies_tbl(1).cf_amount, 0) + nvl(l_subsidy_amount,0);
8861
8862 End If;
8863
8864 END LOOP;
8865
8866 If ( p_subsidies_yn = 'Y' ) Then
8867
8868 subsidies_tbl(1).cf_date := p_start_date;
8869 subsidies_tbl(1).cf_dpp := 1;
8870 subsidies_tbl(1).cf_ppy := 360;
8871
8872 subsidies_tbl(1).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(
8873 p_days_in_month => l_day_convention_month,
8874 p_days_in_year => l_day_convention_year,
8875 p_start_date => p_start_date,
8876 p_end_date => p_start_date,
8877 p_arrears => 'N',
8878 x_return_status => lx_return_status);
8879
8880 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8881 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8882 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8883 RAISE OKL_API.G_EXCEPTION_ERROR;
8884 END IF;
8885 -- Subsidies End
8886
8887 End if;
8888
8889
8890 FOR l_rec_exp IN c_rec_exp LOOP
8891
8892 If ( nvl(l_rec_exp.fee_type, 'XYZ') = 'FINANCED') Then
8893
8894 FOR s1 in 1..l_rec_exp.periods LOOP
8895
8896 s := s + 1;
8897
8898 rec_exp_tbl(s).cf_amount := -(l_rec_exp.cf_amount);
8899 rec_exp_tbl(s).cf_date := ADD_MONTHS(l_rec_exp.start_date, (s1 -1)*l_rec_exp.cf_mpp);
8900 rec_exp_tbl(s).cf_dpp := l_rec_exp.cf_dpp;
8901 rec_exp_tbl(s).cf_ppy := l_rec_exp.cf_ppy;
8902
8903 rec_exp_tbl(s).cf_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
8904 p_days_in_month => l_day_convention_month,
8905 p_days_in_year => l_day_convention_year,
8906 p_end_date => rec_exp_tbl(s).cf_date,
8907 p_arrears => 'N',
8908 x_return_status => lx_return_status);
8909
8910 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
8911 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
8912 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
8913 RAISE OKL_API.G_EXCEPTION_ERROR;
8914 END IF;
8915
8916 END LOOP;
8917
8918 End If;
8919
8920 END LOOP;
8921
8922
8923 IF m > 0 THEN
8924 FOR m1 IN 1..hdr_inflow_tbl.COUNT LOOP
8925 IF hdr_inflow_tbl(m1).cf_date <= p_start_date THEN
8926 l_adv_payment := l_adv_payment + hdr_inflow_tbl(m1).cf_amount;
8927 END IF;
8928 END LOOP;
8929 END IF;
8930
8931 IF n > 0 THEN
8932 FOR n1 IN 1..inflow_tbl.COUNT LOOP
8933 IF inflow_tbl(n1).cf_date <= p_start_date THEN
8934 l_adv_payment := l_adv_payment + inflow_tbl(n1).cf_amount;
8935 END IF;
8936 END LOOP;
8937 END IF;
8938
8939 -- print( l_prog_name, 'TIME ZERO OUTFLOW '||l_time_zero_cost);
8940 -- print( l_prog_name, 'INFLOWS ON OR BEFORE TIME ZERO '||l_adv_payment);
8941
8942 --Commented by RGOOTY for bug 7577105
8943 /*
8944 IF l_adv_payment >= l_time_zero_cost THEN
8945
8946 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
8947 p_msg_name => 'OKL_IRR_CALC_INF_LOOP',
8948 p_token1 => 'ADV_AMOUNT',
8949 p_token1_value => l_adv_payment,
8950 p_token2 => 'CAPITAL_AMOUNT',
8951 p_token2_value => l_time_zero_cost);
8952
8953 RAISE OKL_API.G_EXCEPTION_ERROR;
8954
8955 END IF; */
8956
8957 SELECT currency_code
8958 INTO l_currency_code
8959 FROM okc_k_headers_b
8960 WHERE id = p_khr_id;
8961
8962 SELECT NVL(precision,0)
8963 INTO l_precision
8964 FROM fnd_currencies
8965 WHERE currency_code = l_currency_code;
8966
8967 l_iir_limit := ROUND(NVL(ABS(fnd_profile.value('OKL_PRE_TAX_IRR_LIMIT')), 1000), 0)/100;
8968 --print( 'Initial iir estimated ' || l_iir );
8969 LOOP
8970 i := i + 1;
8971 l_npv := -(l_time_zero_cost);
8972 l_deposit_date := NULL;
8973
8974 --DEBUG
8975 /*
8976 print( l_prog_name, ' ');
8977 print( l_prog_name, 'ITERATION # '||i||' IRR Guess '||l_iir*100||' Time Zero is '
8978 ||TO_CHAR(p_start_date, 'DD-MON-YYYY'));
8979 print( l_prog_name,' ');
8980 */
8981
8982 -------------------------------------------
8983 -- INTERIM INTEREST INFLOWS
8984 -------------------------------------------
8985
8986 IF p_interim_tbl.COUNT > 0 THEN
8987 /*
8988 print( l_prog_name,'INTERIM INTEREST INFLOWS ...');
8989 print( l_prog_name,'');
8990 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
8991 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
8992 print( l_prog_name, '');
8993 */
8994 --DEBUG
8995 a :=0;
8996 FOR l_temp IN p_interim_tbl.FIRST .. p_interim_tbl.LAST LOOP
8997 --DEBUG
8998 a := a+1;
8999 l_cf_dpp := p_interim_tbl(l_temp).cf_dpp;
9000
9001 IF l_cf_dpp = 30 THEN
9002 l_cf_ppy := 12;
9003 ELSIF l_cf_dpp = 90 THEN
9004 l_cf_ppy := 4;
9005 ELSIF l_cf_dpp = 180 THEN
9006 l_cf_ppy := 2;
9007 ELSIF l_cf_dpp = 360 THEN
9008 l_cf_ppy := 1;
9009 END IF;
9010
9011 l_cf_amount := p_interim_tbl(l_temp).cf_amount;
9012 l_days_in_future := p_interim_tbl(l_temp).cf_days;
9013
9014 l_periods := l_days_in_future / l_cf_dpp;
9015
9016 IF (l_periods < 1) AND (l_iir/l_cf_ppy <= -1) THEN
9017
9018 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9019 p_msg_name => 'OKL_IRR_ZERO_DIV');
9020
9021 RAISE OKL_API.G_EXCEPTION_ERROR;
9022
9023 END IF;
9024
9025 l_npv := l_npv + (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9026
9027 /* print( l_prog_name, TO_CHAR(a, '99')||' '||'NOT AVAILAB'||' '||TO_CHAR(l_days_in_future, '9999')
9028 ||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
9029 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods)), '999.990'));
9030 */
9031 END LOOP;
9032
9033 END IF;
9034
9035 -------------------------------------------
9036 -- HEADER LEVEL CASH INFLOWS
9037 -------------------------------------------
9038
9039 IF m > 0 THEN
9040 /*
9041 print( l_prog_name, 'K LEVEL CASH INFLOWS ...');
9042 print( l_prog_name, '');
9043 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
9044 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
9045 print( l_prog_name, '');
9046 */
9047 --DEBUG
9048 a :=0;
9049 FOR x IN 1..hdr_inflow_tbl.COUNT LOOP
9050 --DEBUG
9051 a := a+1;
9052 l_cf_dpp := hdr_inflow_tbl(x).cf_dpp;
9053 l_cf_ppy := hdr_inflow_tbl(x).cf_ppy;
9054 l_cf_amount := hdr_inflow_tbl(x).cf_amount;
9055 l_cf_date := hdr_inflow_tbl(x).cf_date;
9056 l_days_in_future := hdr_inflow_tbl(x).cf_days;
9057
9058 l_periods := l_days_in_future / l_cf_dpp;
9059
9060 IF (l_periods < 1) AND (l_iir/l_cf_ppy <= -1) THEN
9061
9062 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9063 p_msg_name => 'OKL_IRR_ZERO_DIV');
9064
9065 RAISE OKL_API.G_EXCEPTION_ERROR;
9066
9067 END IF;
9068
9069 l_npv := l_npv + (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9070
9071 /*
9072 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '99.999')||
9073 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods)), '99.990'));
9074 */
9075
9076 -- Security Deposit is both an inflow as well as an outflow
9077
9078 IF hdr_inflow_tbl(x).cf_purpose = 'SECURITY_DEPOSIT' THEN
9079
9080 OPEN c_deposit_date;
9081 FETCH c_deposit_date INTO l_deposit_date;
9082 CLOSE c_deposit_date;
9083
9084 IF l_deposit_date IS NOT NULL THEN
9085
9086 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
9087 p_days_in_month => l_day_convention_month,
9088 p_days_in_year => l_day_convention_year,
9089 p_end_date => l_deposit_date,
9090 p_arrears => l_cf_arrear,
9091 x_return_status => lx_return_status);
9092
9093 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9094 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9095 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
9096 RAISE OKL_API.G_EXCEPTION_ERROR;
9097 END IF;
9098
9099 ELSE
9100
9101 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
9102 p_days_in_month => l_day_convention_month,
9103 p_days_in_year => l_day_convention_year,
9104 p_end_date => l_end_date,
9105 p_arrears => l_cf_arrear,
9106 x_return_status => lx_return_status);
9107
9108 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9109 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9110 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
9111 RAISE OKL_API.G_EXCEPTION_ERROR;
9112 END IF;
9113
9114 END IF;
9115
9116 l_periods := l_days_in_future / l_cf_dpp;
9117 l_npv := l_npv - (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9118
9119 END IF;
9120
9121 l_deposit_date := NULL;
9122
9123 END LOOP;
9124
9125 END IF;
9126
9127 -------------------------------------------
9128 -- LINE LEVEL CASH INFLOWS
9129 -------------------------------------------
9130
9131 IF n > 0 THEN
9132 /* print( l_prog_name, 'LINE LEVEL CASH INFLOWS ...');
9133 print( l_prog_name, '');
9134 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
9135 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
9136 print( l_prog_name, '');
9137 */
9138 --DEBUG
9139 a :=0;
9140 FOR y IN 1..inflow_tbl.COUNT LOOP
9141 --DEBUG
9142 a := a+1;
9143 l_cf_dpp := inflow_tbl(y).cf_dpp;
9144 l_cf_ppy := inflow_tbl(y).cf_ppy;
9145 l_cf_amount := inflow_tbl(y).cf_amount;
9146 l_cf_date := inflow_tbl(y).cf_date;
9147 l_days_in_future := inflow_tbl(y).cf_days;
9148
9149 l_periods := l_days_in_future / l_cf_dpp;
9150
9151 IF (l_periods < 1) AND (l_iir/l_cf_ppy <= -1) THEN
9152
9153 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9154 p_msg_name => 'OKL_IRR_ZERO_DIV');
9155
9156 RAISE OKL_API.G_EXCEPTION_ERROR;
9157
9158 END IF;
9159
9160 l_npv := l_npv + (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9161
9162 /* print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
9163 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods)), '999.990'));
9164 */
9165 -- Security Deposit is both an inflow as well as an outflow
9166
9167 IF inflow_tbl(y).cf_purpose = 'SECURITY_DEPOSIT' THEN
9168
9169 OPEN c_deposit_date;
9170 FETCH c_deposit_date INTO l_deposit_date;
9171 CLOSE c_deposit_date;
9172
9173 IF l_deposit_date IS NOT NULL THEN
9174
9175 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
9176 p_days_in_month => l_day_convention_month,
9177 p_days_in_year => l_day_convention_year,
9178 p_end_date => l_deposit_date,
9179 p_arrears => l_cf_arrear,
9180 x_return_status => lx_return_status);
9181
9182 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9183 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9184 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
9185 RAISE OKL_API.G_EXCEPTION_ERROR;
9186 END IF;
9187
9188 ELSE
9189
9190 l_days_in_future := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => p_start_date,
9191 p_days_in_month => l_day_convention_month,
9192 p_days_in_year => l_day_convention_year,
9193 p_end_date => l_end_date,
9194 p_arrears => l_cf_arrear,
9195 x_return_status => lx_return_status);
9196
9197 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9198 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9199 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
9200 RAISE OKL_API.G_EXCEPTION_ERROR;
9201 END IF;
9202
9203 END IF;
9204
9205 l_periods := l_days_in_future / l_cf_dpp;
9206 l_npv := l_npv - (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9207
9208 END IF;
9209
9210 l_deposit_date := NULL;
9211
9212 END LOOP;
9213
9214 END IF;
9215
9216 -------------------------------------------
9217 -- RV CASH INFLOWS
9218 -------------------------------------------
9219
9220 IF p > 0 THEN
9221 /* print( l_prog_name,'RV CASH INFLOWS ...');
9222 print( l_prog_name, '');
9223 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
9224 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
9225 print( l_prog_name, ''); */
9226 --DEBUG
9227 a :=0;
9228 FOR z IN 1..rv_tbl.COUNT LOOP
9229 --DEBUG
9230 a := a+1;
9231 l_cf_dpp := rv_tbl(z).cf_dpp;
9232 l_cf_ppy := rv_tbl(z).cf_ppy;
9233 l_cf_amount := rv_tbl(z).cf_amount;
9234 l_cf_date := rv_tbl(z).cf_date;
9235 l_days_in_future := rv_tbl(z).cf_days;
9236
9237 l_periods := l_days_in_future / l_cf_dpp;
9238
9239 IF (l_periods < 1) AND (l_iir/l_cf_ppy <= -1) THEN
9240
9241 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9242 p_msg_name => 'OKL_IRR_ZERO_DIV');
9243
9244 RAISE OKL_API.G_EXCEPTION_ERROR;
9245
9246 END IF;
9247
9248 l_npv := l_npv + (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9249
9250 /*
9251 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
9252 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods)), '99.990'));
9253 */
9254 END LOOP;
9255
9256 END IF;
9257
9258 -- SUBSIDIES
9259 FOR y IN 1..subsidies_tbl.COUNT
9260 LOOP
9261
9262 l_cf_dpp := subsidies_tbl(y).cf_dpp;
9263 l_cf_ppy := subsidies_tbl(y).cf_ppy;
9264 l_cf_amount := subsidies_tbl(y).cf_amount;
9265 l_cf_date := subsidies_tbl(y).cf_date;
9266 l_days_in_future := subsidies_tbl(y).cf_days;
9267
9268 l_periods := l_days_in_future / l_cf_dpp;
9269
9270 IF (l_periods < 1) AND (l_iir/l_cf_ppy <= -1) THEN
9271
9272 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9273 p_msg_name => 'OKL_IRR_ZERO_DIV');
9274
9275 RAISE OKL_API.G_EXCEPTION_ERROR;
9276
9277 END IF;
9278
9279 l_npv := l_npv + (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9280
9281 /*
9282 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
9283 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods)), '999.990'));
9284 */
9285 END LOOP;
9286 -- SUBSIDIES
9287
9288 -- Handle the outflow_tbl
9289 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9290 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || '!!!!!!!! HANDLING THE OUT FLOWS !!!!!!!! ' );
9291 END IF;
9292 IF outflow_tbl IS NOT NULL AND outflow_tbl.COUNT > 0
9293 THEN
9294 FOR q IN outflow_tbl.FIRST .. outflow_tbl.LAST
9295 LOOP
9296 l_cf_dpp := outflow_tbl(q).cf_dpp;
9297 l_cf_ppy := outflow_tbl(q).cf_ppy;
9298 l_cf_amount := outflow_tbl(q).cf_amount;
9299 l_cf_date := outflow_tbl(q).cf_date;
9300 l_days_in_future := outflow_tbl(q).cf_days;
9301 l_periods := l_days_in_future / l_cf_dpp;
9302 IF (l_periods < 1) AND (l_iir/l_cf_ppy <= -1)
9303 THEN
9304 OKL_API.SET_MESSAGE (
9305 p_app_name => G_APP_NAME,
9306 p_msg_name => 'OKL_IRR_ZERO_DIV');
9307 RAISE OKL_API.G_EXCEPTION_ERROR;
9308 END IF;
9309 l_npv := l_npv + (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9310 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9311 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || TO_CHAR(a, '99')||' '|| TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||
9312 TO_CHAR(l_days_in_future, '9999')||' '|| TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '9999999.999')||
9313 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods)), '99999999.999990'));
9314 END IF;
9315 END LOOP; -- FOR q ..
9316 END IF; -- IF outflow_tbl IS ..
9317
9318 IF s > 0 THEN
9319 /*
9320 print( l_prog_name, 'FEE RECURRING EXPENSE CASH OUTFLOWS ...');
9321 print( l_prog_name, '');
9322 print( l_prog_name, ' '||' Cash Flow'||' Days in'||' Periods'||' Cash Flow'||' Discounted');
9323 print( l_prog_name, ' '||' Date'||' Future'||' (n) '||' Amount'||' Value');
9324 print( l_prog_name, '');
9325 */
9326 --DEBUG
9327 a :=0;
9328 FOR t IN 1..rec_exp_tbl.COUNT LOOP
9329 --DEBUG
9330 a := a+1;
9331 l_cf_ppy := rec_exp_tbl(t).cf_ppy;
9332 l_cf_dpp := rec_exp_tbl(t).cf_dpp;
9333 l_cf_amount := rec_exp_tbl(t).cf_amount;
9334 l_cf_date := rec_exp_tbl(t).cf_date;
9335 l_days_in_future := rec_exp_tbl(t).cf_days;
9336
9337 l_periods := l_days_in_future / l_cf_dpp;
9338
9339 IF (l_periods < 1) AND (l_iir/l_cf_ppy <= -1) THEN
9340
9341 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9342 p_msg_name => 'OKL_IRR_ZERO_DIV');
9343
9344 RAISE OKL_API.G_EXCEPTION_ERROR;
9345
9346 END IF;
9347
9348 l_npv := l_npv + (l_cf_amount / POWER((1 + l_iir/l_cf_ppy), l_periods));
9349
9350 /*
9351 print( l_prog_name, TO_CHAR(a, '99')||' '||TO_CHAR(l_cf_date, 'DD-MON-YYYY')||' '||TO_CHAR(l_days_in_future, '9999')||' '||TO_CHAR(l_periods, '99.999')||' '||TO_CHAR(l_cf_amount, '999.999')||
9352 ' '||TO_CHAR((l_cf_amount / POWER((1 + l_irr/l_cf_ppy), l_periods)), '999.990'));
9353 */
9354
9355 END LOOP;
9356
9357 END IF;
9358
9359 -- print( l_prog_name, 'NPV '||L_NPV);
9360
9361 IF ROUND(l_npv, l_precision+1) = 0 THEN
9362
9363 x_iir := l_iir; -- LLA API multiples by 100 before updating KHR implicit_interest_rate column
9364 RETURN;
9365
9366 END IF;
9367
9368 IF i > 1 AND SIGN(l_npv) <> SIGN(l_prev_npv) AND l_crossed_zero = 'N' THEN
9369
9370 l_crossed_zero := 'Y';
9371
9372 -- Added by RGOOTY
9373 IF ( sign( l_npv) = 1 ) then
9374 l_positive_npv := l_npv;
9375 l_negative_npv := l_prev_npv;
9376 l_positive_npv_iir := l_iir;
9377 l_negative_npv_iir := l_prev_iir;
9378 ELSE
9379 l_positive_npv := l_prev_npv;
9380 l_negative_npv := l_npv;
9381 l_positive_npv_iir := l_prev_iir;
9382 l_negative_npv_iir := l_iir;
9383 END IF;
9384
9385 END IF;
9386
9387 IF( sign(l_npv) = 1) THEN
9388 l_positive_npv := l_npv;
9389 l_positive_npv_iir := l_iir;
9390 ELSE
9391 l_negative_npv := l_npv;
9392 l_negative_npv_iir := l_iir;
9393 END IF;
9394
9395
9396 IF l_crossed_zero = 'Y' THEN
9397 -- Added by RGOOTY
9398 -- Means First time we have got two opposite signed
9399 IF i > 1 then
9400 l_abs_incr := abs(( l_positive_npv_iir - l_negative_npv_iir ) /
9401 ( l_positive_npv - l_negative_npv ) * l_positive_npv);
9402
9403 IF ( l_positive_npv_iir < l_negative_npv_iir ) THEN
9404 l_iir := l_positive_npv_iir + l_abs_incr;
9405 ELSE
9406 l_iir := l_positive_npv_iir - l_abs_incr;
9407
9408 END IF;
9409 l_iir_decided := 'T';
9410
9411 ELSE
9412 l_abs_incr := ABS(l_increment) / 2;
9413 END IF;
9414
9415 ELSE
9416
9417 l_abs_incr := ABS(l_increment);
9418
9419 END IF;
9420
9421 IF i > 1 THEN
9422
9423 IF SIGN(l_npv) <> l_prev_npv_sign THEN
9424
9425 IF l_prev_incr_sign = 1 THEN
9426
9427 l_increment := - l_abs_incr;
9428
9429 ELSE
9430
9431 l_increment := l_abs_incr;
9432
9433 END IF;
9434
9435 ELSE
9436
9437 IF l_prev_incr_sign = 1 THEN
9438
9439 l_increment := l_abs_incr;
9440
9441 ELSE
9442
9443 l_increment := - l_abs_incr;
9444
9445 END IF;
9446
9447 END IF;
9448
9449 ELSE -- i = 1
9450
9451 IF SIGN(l_npv) = -1 THEN
9452
9453 l_increment := - l_increment;
9454
9455 END IF;
9456
9457 END IF;
9458
9459 -- Added by RGOOTY: Start
9460 l_prev_iir := l_iir;
9461
9462 IF l_iir_decided = 'F'
9463 THEN
9464 l_iir := l_iir + l_increment;
9465 ELSE
9466 l_iir_decided := 'F';
9467 END IF;
9468
9469 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9470 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE,l_prog_name || i || '-Loop l_npv ' || l_npv );
9471 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE,l_prog_name || i || '-Loop l_increment ' || l_increment );
9472 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE,l_prog_name || i || '-Loop iir ' || l_iir );
9473
9474
9475 END IF;
9476 IF ABS(l_iir) > l_iir_limit THEN
9477
9478 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9479 p_msg_name => 'OKL_IIR_CALC_IIR_LIMIT',
9480 p_token1 => 'IIR_LIMIT',
9481 p_token1_value => l_iir_limit*100);
9482
9483 RAISE OKL_API.G_EXCEPTION_ERROR;
9484
9485 END IF;
9486
9487 l_prev_incr_sign := SIGN(l_increment);
9488 l_prev_npv_sign := SIGN(l_npv);
9489 l_prev_npv := l_npv;
9490
9491 END LOOP;
9492 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9493 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'end' );
9494
9495 END IF;
9496 EXCEPTION
9497
9498 WHEN OKL_API.G_EXCEPTION_ERROR THEN
9499
9500 x_return_status := G_RET_STS_ERROR;
9501
9502 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
9503
9504 x_return_status := G_RET_STS_UNEXP_ERROR;
9505
9506 WHEN OTHERS THEN
9507
9508 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
9509 p_msg_name => G_DB_ERROR,
9510 p_token1 => G_PROG_NAME_TOKEN,
9511 p_token1_value => l_prog_name,
9512 p_token2 => G_SQLCODE_TOKEN,
9513 p_token2_value => sqlcode,
9514 p_token3 => G_SQLERRM_TOKEN,
9515 p_token3_value => sqlerrm);
9516
9517 x_return_status := G_RET_STS_UNEXP_ERROR;
9518
9519 END compute_iir;
9520
9521 PROCEDURE compute_rates(
9522 p_api_version IN NUMBER,
9523 p_init_msg_list IN VARCHAR2,
9524 p_khr_id IN NUMBER,
9525 p_kle_id IN NUMBER,
9526 p_pay_tbl IN OKL_STREAM_GENERATOR_PVT.payment_tbl_type,
9527 x_rates OUT NOCOPY OKL_STREAM_GENERATOR_PVT.rate_rec_type,
9528 x_return_status OUT NOCOPY VARCHAR2,
9529 x_msg_count OUT NOCOPY NUMBER,
9530 x_msg_data OUT NOCOPY VARCHAR2) IS
9531
9532 l_rates OKL_STREAM_GENERATOR_PVT.rate_rec_type;
9533
9534 CURSOR c_hdr IS
9535 SELECT chr.template_yn,
9536 chr.currency_code,
9537 chr.start_date,
9538 chr.end_date,
9539 khr.deal_type,
9540 khr.term_duration,
9541 NVL(khr.generate_accrual_yn, 'Y')
9542 FROM okc_k_headers_b chr,
9543 okl_k_headers khr
9544 WHERE khr.id = p_khr_id
9545 AND chr.id = khr.id;
9546
9547 l_hdr c_hdr%ROWTYPE;
9548
9549 Cursor c_rv IS
9550 SELECT SUM(to_number(nvl(rul_rv.rule_information2,rul_rv.rule_information4))) Residual_value,
9551 DECODE(rul_sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360) days_per_period,
9552 DECODE(rul_sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1) periods_per_year,
9553 DECODE(rul_sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) months_per_period,
9554 cle_so.id cle_id,
9555 cle_so.start_date
9556 FROM okc_k_headers_b chr_rv,
9557 okc_line_styles_b lse_rv,
9558 okc_k_lines_b cle_rv,
9559 okc_rules_b rul_rv,
9560 okc_rule_groups_b rgp_rv,
9561 okc_line_styles_b lse_so,
9562 okc_k_lines_b cle_so,
9563 okc_rules_b rul_so,
9564 okc_rule_groups_b rgp_so,
9565 okc_rule_groups_b rgp_pay,
9566 okc_rules_b rul_slh,
9567 okc_rules_b rul_sll,
9568 okl_strm_type_b sty
9569 WHERE rgp_so.cle_id = p_kle_id
9570 AND rgp_so.dnz_chr_id = p_khr_id
9571 AND rgp_so.rgd_code = 'SOPYSC'
9572 AND rgp_so.dnz_chr_id = rul_so.dnz_chr_id
9573 AND rgp_so.id = rul_so.rgp_id
9574 AND rul_so.rule_information_category = 'SOPMSC'
9575 AND rgp_so.cle_id = cle_so.id
9576 AND cle_so.id = p_kle_id
9577 AND cle_so.dnz_chr_id = rul_so.dnz_chr_id
9578 AND cle_so.lse_id = lse_so.id
9579 AND lse_so.lty_code = 'SO_PAYMENT'
9580 AND rul_rv.object1_id1 = to_char(rul_so.id)
9581 AND rul_rv.dnz_chr_id = p_khr_id
9582 AND rul_rv.dnz_chr_id = rul_so.dnz_chr_id
9583 AND rul_rv.rgp_id = rgp_rv.id
9584 AND rgp_rv.rgd_code = 'SOPSAD'
9585 AND rgp_rv.dnz_chr_id = rul_so.dnz_chr_id
9586 AND rgp_rv.cle_id = cle_rv.id
9587 AND cle_rv.lse_id = lse_rv.id
9588 AND lse_rv.lty_code = 'FREE_FORM1'
9589 AND rgp_rv.dnz_chr_id = chr_rv.id
9590 AND chr_rv.START_DATE = cle_rv.START_DATE
9591 AND cle_so.id = rgp_pay.cle_id
9592 AND rgp_pay.rgd_code = 'LALEVL'
9593 AND rgp_pay.id = rul_slh.rgp_id
9594 AND rul_slh.rule_information_category = 'LASLH'
9595 AND TO_CHAR(rul_slh.id) = rul_sll.object2_id1
9596 AND rul_sll.rule_information_category = 'LASLL'
9597 AND TO_NUMBER(rul_slh.object1_id1) = sty.id
9598 AND sty.stream_type_purpose = 'RENT'
9599 GROUP BY DECODE(rul_sll.object1_id1, 'M', 30, 'Q', 90, 'S', 180, 'A', 360),
9600 DECODE(rul_sll.object1_id1, 'M', 12, 'Q', 4, 'S', 2, 'A', 1),
9601 DECODE(rul_sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12),
9602 cle_so.id,
9603 cle_so.start_date;
9604
9605 r_rv c_rv%ROWTYPE;
9606
9607 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'compute_rates';
9608
9609 l_rate NUMBER;
9610 l_payment NUMBER;
9611 l_payment_count NUMBER;
9612
9613 l_capital_cost NUMBER;
9614 l_residual_value NUMBER;
9615 l_start_date DATE;
9616
9617 Cursor l_strms_csr Is
9618 Select id
9619 from okl_streams
9620 where khr_id = p_khr_id
9621 --and kle_id = p_kle_id
9622 and purpose_code in ('PLOW', 'FLOW', 'STUBS');
9623
9624 l_strms_rec l_strms_csr%ROWTYPE;
9625
9626 Cursor c_sty ( n VARCHAR2 ) IS
9627 Select id
9628 from okl_strm_type_tl
9629 where language = 'US'
9630 and name = n;
9631
9632 r_sty c_sty%ROWTYPE;
9633 lt_pay_tbl OKL_STREAM_GENERATOR_PVT.payment_tbl_type;
9634 l_pay_tbl OKL_STREAM_GENERATOR_PVT.payment_tbl_type;
9635 l_sty_id NUMBER := -1;
9636
9637 l_interim_interest NUMBER;
9638 l_interim_days NUMBER;
9639 l_interim_dpp NUMBER;
9640
9641 l_interim_tbl interim_interest_tbl_type;
9642
9643 l_stmv_tbl okl_streams_pub.stmv_tbl_type;
9644 x_stmv_tbl okl_streams_pub.stmv_tbl_type;
9645
9646 Cursor c_rollover_fee IS
9647 SELECT DISTINCT
9648 cle.id kleId,
9649 stm.id styId,
9650 sll.object1_id1 frequency,
9651 TO_NUMBER(sll.rule_information3) periods,
9652 FND_DATE.canonical_to_date(sll.rule_information2) start_date,
9653 sll.rule_information5 structure,
9654 sll.rule_information10 advance_arrears,
9655 FND_NUMBER.canonical_to_number(sll.rule_information6) amount,
9656 TO_NUMBER(sll.rule_information7) stub_days,
9657 TO_NUMBER(sll.rule_information8) stub_amount
9658 FROM okc_k_headers_b chr_so,
9659 okc_k_lines_b cle,
9660 okl_k_lines kle,
9661 okc_line_styles_b lse,
9662 okc_rules_b sll,
9663 okc_rules_b slh,
9664 okc_rule_groups_b rgp,
9665 okl_strm_type_b stm
9666 WHERE chr_so.id = p_khr_id
9667 and cle.sts_code in( 'COMPLETE', 'INCOMPLETE')--'ENTERED'
9668 AND cle.dnz_chr_id = chr_so.id
9669 AND cle.id = kle.id
9670 AND trunc(cle.START_DATE) = trunc(chr_so.START_DATE)
9671 AND cle.lse_id = lse.id
9672 AND ((lse.lty_code = 'FEE' AND kle.fee_type = 'ROLLOVER') OR (lse.lty_code = 'LINK_FEE_ASSET'))
9673 AND nvl(kle.fee_type, 'XXX') <> 'CAPITALIZED'
9674 AND cle.id = rgp.cle_id
9675 AND rgp.rgd_code = 'LALEVL'
9676 AND rgp.id = slh.rgp_id
9677 AND slh.rule_information_category = 'LASLH'
9678 AND slh.object1_id1 = TO_CHAR(stm.id)
9679 AND TO_CHAR(slh.id) = sll.object2_id1
9680 AND sll.rule_information_category = 'LASLL'
9681 order by stm.id;
9682
9683 r_rollover_fee c_rollover_fee%ROWTYPE;
9684 -- -Added sll.rule_information2 in order by clause by djanaswa for bug 6007644
9685 Cursor c_fee IS
9686 SELECT DISTINCT
9687 cle.id kleId,
9688 stm.id styId,
9689 sll.object1_id1 frequency,
9690 TO_NUMBER(sll.rule_information3) periods,
9691 FND_DATE.canonical_to_date(sll.rule_information2) start_date,
9692 sll.rule_information5 structure,
9693 sll.rule_information10 advance_arrears,
9694 FND_NUMBER.canonical_to_number(sll.rule_information6) amount,
9695 TO_NUMBER(sll.rule_information7) stub_days,
9696 TO_NUMBER(sll.rule_information8) stub_amount
9697 FROM okc_k_headers_b chr_so,
9698 okc_k_lines_b cle,
9699 okl_k_lines kle,
9700 okc_line_styles_b lse,
9701 okc_rules_b sll,
9702 okc_rules_b slh,
9703 okc_rule_groups_b rgp,
9704 okl_strm_type_b stm
9705 WHERE chr_so.id = p_khr_id
9706 and cle.sts_code in( 'COMPLETE', 'INCOMPLETE')--'ENTERED'
9707 AND cle.dnz_chr_id = chr_so.id
9708 AND trunc(cle.START_DATE) = trunc(chr_so.START_DATE)
9709 AND cle.lse_id = lse.id
9710 AND kle.id = cle.id
9711 AND lse.lty_code in ('FEE', 'LINK_FEE_ASSET')
9712 ANd nvl(kle.fee_type, 'XXX') <> 'CAPITALIZED'
9713 AND cle.id = rgp.cle_id
9714 AND rgp.rgd_code = 'LALEVL'
9715 AND rgp.id = slh.rgp_id
9716 AND slh.rule_information_category = 'LASLH'
9717 AND slh.object1_id1 = TO_CHAR(stm.id)
9718 AND TO_CHAR(slh.id) = sll.object2_id1
9719 AND sll.rule_information_category = 'LASLL'
9720 order by stm.id, FND_DATE.canonical_to_date(sll.rule_information2);
9721
9722 r_fee c_fee%ROWTYPE;
9723 i BINARY_INTEGER;
9724 j BINARY_INTEGER;
9725
9726 Cursor c_subs Is
9727 Select 'Y'
9728 From dual
9729 where Exists(
9730 select kle.id
9731 from okl_k_lines_full_v kle,
9732 okc_line_styles_b lse,
9733 okc_statuses_b sts
9734 where KLE.LSE_ID = LSE.ID
9735 and lse.lty_code = 'SUBSIDY'
9736 and kle.dnz_chr_id = p_khr_id
9737 and sts.code = kle.sts_code
9738 and sts.ste_code not in ('HOLD', 'TERMINATED', 'EXPIRED', 'CANCELLED'));
9739
9740 r_subs c_subs%ROWTYPE;
9741 l_subsidies_yn VARCHAR2(1);
9742 l_subsidy_amount NUMBER;
9743
9744 l_kle_id NUMBER;
9745 l_has_rollover_fee VARCHAR2(1) := 'N';
9746 -- Bug 4626837 : Start
9747 l_rent_strm_name VARCHAR2(256);
9748 l_rent_strm_id NUMBER;
9749 -- Bug 4626837 : End
9750 BEGIN
9751 IF (G_DEBUG_ENABLED = 'Y') THEN
9752 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
9753 END IF;
9754 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9755 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'begin' );
9756
9757
9758 END IF;
9759 For i in p_pay_tbl.FIRST..p_pay_tbl.LAST
9760 LOOP
9761 IF ( (p_pay_tbl(i).amount IS NULL) AND (p_pay_tbl(i).stub_amount IS NULL ) ) Then
9762 OKL_API.set_message(p_app_name => G_APP_NAME,
9763 p_msg_name => 'OKL_PE_MISSING_PMNT');
9764 RAISE OKL_API.G_EXCEPTION_ERROR;
9765 End If;
9766 END LOOP;
9767
9768 For i in p_pay_tbl.FIRST..p_pay_tbl.LAST
9769 LOOP
9770 l_pay_tbl(i) := p_pay_tbl(i);
9771 l_pay_tbl(i).rate := l_pay_tbl(i).rate / 100.0;
9772 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9773 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' date ' || l_pay_tbl(i).start_date || ' amout ' || l_pay_tbl(i).amount );
9774 END IF;
9775 IF ( l_pay_tbl(i).periods IS NOT NULL) AND ( l_pay_tbl(i).amount IS NULL ) Then
9776 l_pay_tbl(i).amount := -9999999;
9777 ELSIF ( l_pay_tbl(i).periods IS NULL) AND ( l_pay_tbl(i).stub_amount IS NULL ) Then
9778 l_pay_tbl(i).stub_amount := -9999999;
9779 END IF;
9780 END LOOP;
9781
9782 -- Bug 4626837 : Start
9783 -- Get the Deal Type using the c_hdr cursor
9784 OPEN c_hdr;
9785 FETCH c_hdr INTO l_hdr;
9786 CLOSE c_hdr;
9787 OKL_ISG_UTILS_PVT.get_primary_stream_type(
9788 p_khr_id => p_khr_id,
9789 p_deal_type => l_hdr.deal_type,
9790 p_primary_sty_purpose => 'RENT',
9791 x_return_status => x_return_status,
9792 x_primary_sty_id => l_rent_strm_id,
9793 x_primary_sty_name => l_rent_strm_name);
9794 IF (x_return_status = G_RET_STS_UNEXP_ERROR) THEN
9795 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9796 ELSIF (x_return_status = G_RET_STS_ERROR) THEN
9797 RAISE OKL_API.G_EXCEPTION_ERROR;
9798 END IF;
9799 -- Bug 4626837 : End
9800 OKL_STREAM_GENERATOR_PVT.generate_cash_flows(
9801 p_api_version => p_api_version,
9802 p_init_msg_list => p_init_msg_list,
9803 p_khr_id => p_khr_id,
9804 p_kle_id => p_kle_id,
9805 p_sty_id => l_rent_strm_id, -- Bug 4626837
9806 p_payment_tbl => l_pay_tbl,
9807 x_payment_count => l_payment_count,
9808 x_return_status => x_return_status,
9809 x_msg_count => x_msg_count,
9810 x_msg_data => x_msg_data);
9811
9812 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9813 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'generate_cash_flows ' || x_return_status );
9814
9815 END IF;
9816 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9817 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9818 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
9819 RAISE OKL_API.G_EXCEPTION_ERROR;
9820 END IF;
9821
9822 OPEN c_subs;
9823 FETCH c_subs INTO l_subsidies_yn;
9824 CLOSE c_subs;
9825 l_subsidies_yn := nvl( l_subsidies_yn, 'N' );
9826
9827
9828 okl_la_stream_pvt.get_so_asset_oec(p_khr_id,
9829 p_kle_id,
9830 l_subsidies_yn,
9831 x_return_status,
9832 l_capital_cost,
9833 l_start_date);
9834
9835 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9836 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' get_asset_oec ' || to_char( l_capital_cost)|| x_return_status);
9837 END IF;
9838 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9839 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9840 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
9841 RAISE OKL_API.G_EXCEPTION_ERROR;
9842 END IF;
9843
9844 Okl_la_stream_pvt.get_so_residual_value(p_khr_id,
9845 p_kle_id,
9846 l_subsidies_yn,
9847 x_return_status,
9848 l_residual_value,
9849 l_start_date);
9850
9851 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9852 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' get_residual_value ' || to_char( l_residual_value )|| x_return_status);
9853 END IF;
9854 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9855 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9856 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
9857 RAISE OKL_API.G_EXCEPTION_ERROR;
9858 END IF;
9859
9860 --If ( p_rate_type = 'PRE_TAX_IRR' ) Then calcualte pre_tax_irr
9861
9862 i := 0;
9863 FOR r_fee in c_fee
9864 LOOP
9865
9866 l_kle_Id := r_fee.kleId;
9867 If ( l_sty_id = r_fee.styId ) Then
9868
9869 i := i + 1;
9870 lt_pay_tbl(i).amount := r_fee.amount;
9871 lt_pay_tbl(i).start_date := r_fee.start_date;
9872 lt_pay_tbl(i).arrears_yn := r_fee.advance_arrears;
9873 lt_pay_tbl(i).periods := r_fee.periods;
9874 lt_pay_tbl(i).frequency := r_fee.frequency;
9875 lt_pay_tbl(i).stub_days := r_fee.stub_days;
9876 lt_pay_tbl(i).stub_amount := r_fee.stub_amount;
9877
9878 For j in l_pay_tbl.FIRST..(l_pay_tbl.LAST-1)
9879 LOOP
9880 If (( r_fee.start_date >= l_pay_tbl(j).start_date ) AND
9881 ( r_fee.start_date < l_pay_tbl(j+1).start_date)) Then
9882
9883 If ( l_pay_tbl(j).arrears_yn = 'Y' ) Then
9884 lt_pay_tbl(i).rate := l_pay_tbl(j+1).rate;
9885 else
9886 lt_pay_tbl(i).rate := l_pay_tbl(j).rate;
9887 End If;
9888 exit;
9889
9890 End If;
9891 END LOOP;
9892
9893 Else
9894
9895 If ( lt_pay_tbl.COUNT > 0 ) Then
9896
9897 OKL_STREAM_GENERATOR_PVT.generate_cash_flows(
9898 p_api_version => p_api_version,
9899 p_init_msg_list => p_init_msg_list,
9900 p_khr_id => p_khr_id,
9901 p_kle_id => r_fee.kleId,
9902 p_sty_id => l_sty_id,
9903 p_payment_tbl => lt_pay_tbl,
9904 x_payment_count => l_payment_count,
9905 x_return_status => x_return_status,
9906 x_msg_count => x_msg_count,
9907 x_msg_data => x_msg_data);
9908
9909
9910 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9911 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9912 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
9913 RAISE OKL_API.G_EXCEPTION_ERROR;
9914 END IF;
9915
9916 End If;
9917
9918 lt_pay_tbl.DELETE;
9919 i := 1;
9920 l_sty_id := r_fee.styId;
9921 lt_pay_tbl(i).amount := r_fee.amount;
9922 lt_pay_tbl(i).start_date := r_fee.start_date;
9923 lt_pay_tbl(i).arrears_yn := r_fee.advance_arrears;
9924 lt_pay_tbl(i).periods := r_fee.periods;
9925 lt_pay_tbl(i).frequency := r_fee.frequency;
9926 lt_pay_tbl(i).stub_days := r_fee.stub_days;
9927 lt_pay_tbl(i).stub_amount := r_fee.stub_amount;
9928
9929 For j in l_pay_tbl.FIRST..(l_pay_tbl.LAST-1)
9930 LOOP
9931 If (( r_fee.start_date >= l_pay_tbl(j).start_date ) AND
9932 ( r_fee.start_date < l_pay_tbl(j+1).start_date)) Then
9933 lt_pay_tbl(i).rate := l_pay_tbl(j).rate;
9934 End If;
9935 END LOOP;
9936
9937 End If;
9938
9939 END LOOP;
9940
9941 If ( lt_pay_tbl.COUNT > 0 ) Then
9942
9943 OKL_STREAM_GENERATOR_PVT.generate_cash_flows(
9944 p_api_version => p_api_version,
9945 p_init_msg_list => p_init_msg_list,
9946 p_khr_id => p_khr_id,
9947 p_kle_id => l_kle_Id,
9948 p_sty_id => l_sty_id,
9949 p_payment_tbl => lt_pay_tbl,
9950 x_payment_count => l_payment_count,
9951 x_return_status => x_return_status,
9952 x_msg_count => x_msg_count,
9953 x_msg_data => x_msg_data);
9954
9955
9956 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9957 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9958 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
9959 RAISE OKL_API.G_EXCEPTION_ERROR;
9960 END IF;
9961
9962 End If;
9963
9964 OPEN c_sty ( 'RESIDUAL VALUE' );
9965 FETCH c_sty INTO r_sty;
9966 CLOSE c_sty;
9967
9968 OPEN c_rv;
9969 FETCH c_rv INTO r_rv;
9970 CLOSE c_rv;
9971
9972 lt_pay_tbl.DELETE;
9973
9974 l_interim_tbl(1).cf_days := l_interim_days;
9975 l_interim_tbl(1).cf_amount := l_interim_interest;
9976 l_interim_tbl(1).cf_dpp := l_interim_dpp;
9977
9978 comp_so_pre_tax_irr(
9979 p_api_version => p_api_version,
9980 p_init_msg_list => p_init_msg_list,
9981 x_return_status => x_return_status,
9982 x_msg_count => x_msg_count,
9983 x_msg_data => x_msg_data,
9984 p_khr_id => p_khr_id,
9985 p_kle_id => p_kle_id,
9986 p_interim_tbl => l_interim_tbl,
9987 p_target => 'PMNT',
9988 p_subside_yn => 'N',
9989 x_payment => l_payment,
9990 x_rate => l_rate);
9991
9992 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
9993 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_pre_tax_irr ' || to_char( l_rate)|| x_return_status);
9994 END IF;
9995 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
9996 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
9997 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
9998 RAISE OKL_API.G_EXCEPTION_ERROR;
9999 END IF;
10000
10001 l_rates.PRE_TAX_IRR := l_rate * 100.00;
10002
10003 If ( l_subsidies_yn = 'Y' ) Then
10004
10005 comp_so_pre_tax_irr(
10006 p_api_version => p_api_version,
10007 p_init_msg_list => p_init_msg_list,
10008 x_return_status => x_return_status,
10009 x_msg_count => x_msg_count,
10010 x_msg_data => x_msg_data,
10011 p_khr_id => p_khr_id,
10012 p_kle_id => p_kle_id,
10013 p_interim_tbl => l_interim_tbl,
10014 p_target => 'PMNT',
10015 p_subside_yn => 'Y',
10016 x_payment => l_payment,
10017 x_rate => l_rate);
10018
10019 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10020 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_pre_tax_irr ' || x_return_status );
10021 END IF;
10022 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
10023 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10024 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
10025 RAISE OKL_API.G_EXCEPTION_ERROR;
10026 END IF;
10027
10028 l_rates.SUB_PRE_TAX_IRR := l_rate * 100.00;
10029
10030 End If;
10031
10032 --ElsIf ( p_rate_type = 'IMPL_INTEREST_RATE' ) Then implicit_rates
10033
10034 If ( l_subsidies_yn = 'Y' ) Then
10035
10036 l_interim_tbl(1).cf_days := l_interim_days;
10037 l_interim_tbl(1).cf_amount := l_interim_interest;
10038 l_interim_tbl(1).cf_dpp := l_interim_dpp;
10039
10040 comp_so_iir(
10041 p_api_version => p_api_version,
10042 p_init_msg_list => p_init_msg_list,
10043 x_return_status => x_return_status,
10044 x_msg_count => x_msg_count,
10045 x_msg_data => x_msg_data,
10046 p_khr_id => p_khr_id,
10047 p_kle_id => p_kle_id,
10048 p_interim_tbl => l_interim_tbl,
10049 p_target => 'PMNT',
10050 p_subside_yn => 'Y',
10051 x_payment => l_payment,
10052 x_rate => l_rate);
10053
10054 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10055 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_iir ' || x_return_status );
10056 END IF;
10057 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
10058 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10059 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
10060 RAISE OKL_API.G_EXCEPTION_ERROR;
10061 END IF;
10062
10063 l_rates.SUB_IMPL_INTEREST_RATE := l_rate * 100.00;
10064
10065 End If;
10066
10067 l_interim_tbl(1).cf_days := l_interim_days;
10068 l_interim_tbl(1).cf_amount := l_interim_interest;
10069 l_interim_tbl(1).cf_dpp := l_interim_dpp;
10070
10071 comp_so_iir(
10072 p_api_version => p_api_version,
10073 p_init_msg_list => p_init_msg_list,
10074 x_return_status => x_return_status,
10075 x_msg_count => x_msg_count,
10076 x_msg_data => x_msg_data,
10077 p_khr_id => p_khr_id,
10078 p_kle_id => p_kle_id,
10079 p_interim_tbl => l_interim_tbl,
10080 p_target => 'PMNT',
10081 p_subside_yn => 'N',
10082 x_payment => l_payment,
10083 x_rate => l_rate);
10084
10085 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10086 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_iir ' || x_return_status );
10087 END IF;
10088 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
10089 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10090 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
10091 RAISE OKL_API.G_EXCEPTION_ERROR;
10092 END IF;
10093
10094
10095 l_rates.IMPLICIT_INTEREST_RATE := l_rate * 100.00;
10096
10097 --ElsIf ( p_rate_type = 'PRE_TAX_YIELD' ) Then BKG YLD
10098
10099 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10100 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' no subsidies comp_so_pre ' || x_return_status );
10101
10102 END IF;
10103 l_interim_tbl(1).cf_days := l_interim_days;
10104 l_interim_tbl(1).cf_amount := l_interim_interest;
10105 l_interim_tbl(1).cf_dpp := l_interim_dpp;
10106
10107 comp_so_iir(
10108 p_api_version => p_api_version,
10109 p_init_msg_list => p_init_msg_list,
10110 x_return_status => x_return_status,
10111 x_msg_count => x_msg_count,
10112 x_msg_data => x_msg_data,
10113 p_khr_id => p_khr_id,
10114 p_kle_id => p_kle_id,
10115 p_interim_tbl => l_interim_tbl,
10116 p_target => 'PMNT',
10117 p_subside_yn => 'N',
10118 x_payment => l_payment,
10119 x_rate => l_rate);
10120
10121 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10122 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_iir ' || x_return_status );
10123 END IF;
10124 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
10125 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10126 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
10127 RAISE OKL_API.G_EXCEPTION_ERROR;
10128 END IF;
10129
10130 l_rates.PRE_TAX_YIELD := l_rate * 100.00;
10131
10132 If ( l_subsidies_yn = 'Y' ) Then
10133
10134 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10135 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' yes subsidies comp_so_pre '|| x_return_status);
10136 END IF;
10137 l_interim_tbl(1).cf_days := l_interim_days;
10138 l_interim_tbl(1).cf_amount := l_interim_interest;
10139 l_interim_tbl(1).cf_dpp := l_interim_dpp;
10140
10141 comp_so_iir(
10142 p_api_version => p_api_version,
10143 p_init_msg_list => p_init_msg_list,
10144 x_return_status => x_return_status,
10145 x_msg_count => x_msg_count,
10146 x_msg_data => x_msg_data,
10147 p_khr_id => p_khr_id,
10148 p_kle_id => p_kle_id,
10149 p_interim_tbl => l_interim_tbl,
10150 p_target => 'PMNT',
10151 p_subside_yn => 'Y',
10152 x_payment => l_payment,
10153 x_rate => l_rate);
10154
10155 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10156 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'comp_so_iir ' || x_return_status );
10157 END IF;
10158 IF x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
10159 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10160 ELSIF x_return_status = OKL_API.G_RET_STS_ERROR THEN
10161 RAISE OKL_API.G_EXCEPTION_ERROR;
10162 END IF;
10163
10164 l_rates.SUB_PRE_TAX_YIELD := l_rate * 100.00;
10165
10166 END IF;
10167 --Else
10168 x_rates := l_rates;
10169
10170 i := 0;
10171 FOR l_strms_rec in l_strms_csr
10172 LOOP
10173
10174 i := i + 1;
10175 l_stmv_tbl(i).id := l_strms_rec.ID;
10176
10177 END LOOP;
10178
10179 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10180 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' #of streams to delete - ' || i );
10181 END IF;
10182 If ( i > 0 ) Then
10183
10184 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10185 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || i || '# of streams are getting deleted ' );
10186 END IF;
10187 Okl_Streams_pub.delete_streams(
10188 p_api_version => p_api_version,
10189 p_init_msg_list => p_init_msg_list,
10190 x_return_status => x_return_status,
10191 x_msg_count => x_msg_count,
10192 x_msg_data => x_msg_data,
10193 p_stmv_tbl => l_stmv_tbl);
10194
10195 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10196 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10197 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
10198 RAISE OKL_API.G_EXCEPTION_ERROR;
10199 END IF;
10200
10201 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10202 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || ' DONE '|| x_return_status);
10203
10204 END IF;
10205 End If;
10206
10207 For r_rollover_fee in c_rollover_fee
10208 LOOP
10209
10210 update okl_streams
10211 set say_code = 'HIST',
10212 date_history = SYSDATE,
10213 last_updated_by = FND_GLOBAL.USER_ID, -- BUG:14749215 changes start here
10214 last_update_date = sysdate,
10215 last_update_login = FND_GLOBAL.LOGIN_ID -- BUG:14749215 changes end here
10216
10217 where khr_id = p_khr_id
10218 and kle_id = p_kle_id;
10219
10220 update okl_streams
10221 set active_yn = 'N',
10222 last_updated_by = FND_GLOBAL.USER_ID, -- BUG:14749215 changes start here
10223 last_update_date = sysdate,
10224 last_update_login = FND_GLOBAL.LOGIN_ID -- BUG:14749215 changes end here
10225 where khr_id = p_khr_id
10226 and kle_id = p_kle_id;
10227
10228 OKL_STREAM_GENERATOR_PVT.generate_quote_streams(
10229 p_api_version => p_api_version,
10230 p_init_msg_list => p_init_msg_list,
10231 p_khr_id => p_khr_id,
10232 p_kle_id => p_kle_id,
10233 x_return_status => x_return_status,
10234 x_msg_count => x_msg_count,
10235 x_msg_data => x_msg_data);
10236
10237 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10238 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10239 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
10240 RAISE OKL_API.G_EXCEPTION_ERROR;
10241 END IF;
10242
10243 Exit;
10244
10245 END LOOP;
10246
10247
10248 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10249 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'end' );
10250
10251 END IF;
10252 EXCEPTION
10253
10254 WHEN OKL_API.G_EXCEPTION_ERROR THEN
10255
10256 i := 0;
10257 FOR l_strms_rec in l_strms_csr
10258 LOOP
10259
10260 i := i + 1;
10261 l_stmv_tbl(i).id := l_strms_rec.ID;
10262
10263 END LOOP;
10264
10265 If ( i > 0 ) Then
10266
10267 Okl_Streams_pub.delete_streams(
10268 p_api_version => p_api_version,
10269 p_init_msg_list => p_init_msg_list,
10270 x_return_status => x_return_status,
10271 x_msg_count => x_msg_count,
10272 x_msg_data => x_msg_data,
10273 p_stmv_tbl => l_stmv_tbl);
10274
10275 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10276 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10277 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
10278 RAISE OKL_API.G_EXCEPTION_ERROR;
10279 END IF;
10280
10281 End If;
10282
10283 x_return_status := G_RET_STS_ERROR;
10284
10285 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
10286
10287 i := 0;
10288 FOR l_strms_rec in l_strms_csr
10289 LOOP
10290
10291 i := i + 1;
10292 l_stmv_tbl(i).id := l_strms_rec.ID;
10293
10294 END LOOP;
10295
10296 If ( i > 0 ) Then
10297
10298 Okl_Streams_pub.delete_streams(
10299 p_api_version => p_api_version,
10300 p_init_msg_list => p_init_msg_list,
10301 x_return_status => x_return_status,
10302 x_msg_count => x_msg_count,
10303 x_msg_data => x_msg_data,
10304 p_stmv_tbl => l_stmv_tbl);
10305
10306 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10307 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10308 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
10309 RAISE OKL_API.G_EXCEPTION_ERROR;
10310 END IF;
10311
10312 End If;
10313
10314 x_return_status := G_RET_STS_UNEXP_ERROR;
10315
10316 WHEN OTHERS THEN
10317
10318 i := 0;
10319 FOR l_strms_rec in l_strms_csr
10320 LOOP
10321
10322 i := i + 1;
10323 l_stmv_tbl(i).id := l_strms_rec.ID;
10324
10325 END LOOP;
10326
10327 If ( i > 0 ) Then
10328
10329 Okl_Streams_pub.delete_streams(
10330 p_api_version => p_api_version,
10331 p_init_msg_list => p_init_msg_list,
10332 x_return_status => x_return_status,
10333 x_msg_count => x_msg_count,
10334 x_msg_data => x_msg_data,
10335 p_stmv_tbl => l_stmv_tbl);
10336
10337 IF (x_return_status = OKL_API.G_RET_STS_UNEXP_ERROR) THEN
10338 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10339 ELSIF (x_return_status = OKL_API.G_RET_STS_ERROR) THEN
10340 RAISE OKL_API.G_EXCEPTION_ERROR;
10341 END IF;
10342
10343 End If;
10344
10345 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
10346 p_msg_name => G_DB_ERROR,
10347 p_token1 => G_PROG_NAME_TOKEN,
10348 p_token1_value => l_prog_name,
10349 p_token2 => G_SQLCODE_TOKEN,
10350 p_token2_value => sqlcode,
10351 p_token3 => G_SQLERRM_TOKEN,
10352 p_token3_value => sqlerrm);
10353
10354 x_return_status := G_RET_STS_UNEXP_ERROR;
10355
10356 END compute_rates;
10357
10358
10359 -- Start of comments
10360 --
10361 -- Procedure Name : get_payment_after_ppd
10362 -- Description : Returns Payment amount after PPD
10363 -- Business Rules :
10364 -- Parameters : p_khr_id,
10365 -- p_kle_id
10366 -- p_ppd_amt
10367 -- p_rate
10368 -- p_ppd_date
10369 -- p_pay_level
10370 -- Version : 1.0
10371 -- End of comments
10372
10373 PROCEDURE get_payment_after_ppd(
10374 p_api_version IN NUMBER,
10375 p_init_msg_list IN VARCHAR2 DEFAULT OKL_API.G_FALSE,
10376 x_return_status OUT NOCOPY VARCHAR2,
10377 x_msg_count OUT NOCOPY NUMBER,
10378 x_msg_data OUT NOCOPY VARCHAR2,
10379 p_khr_id IN NUMBER,
10380 p_kle_id IN NUMBER,
10381 p_ppd_amt IN NUMBER,
10382 p_rate IN NUMBER,
10383 p_ppd_date IN DATE,
10384 p_pay_level IN payment_tbl_type,
10385 x_pay_level OUT NOCOPY payment_tbl_type)
10386 IS
10387 l_api_name CONSTANT VARCHAR2(30) := 'GET_PAYMENT_AFTER_PPD';
10388 l_first_payment NUMBER := 0;
10389 ln_ob_ppd NUMBER := p_ppd_amt;
10390 ln_cb_ppd NUMBER := 0;
10391 ln_intrm_int NUMBER := 0;
10392 ln_ppd_guess_int NUMBER := 0;
10393 ln_intrm_days NUMBER := 0;
10394 l_intrm_days NUMBER := 0;
10395 ln_int_ppd NUMBER := 0;
10396 ln_int_ppd_days NUMBER := 0;
10397 ln_ppd_guess NUMBER := 0;
10398 ln_ppd_pay NUMBER := 0;
10399 l_no_of_periods NUMBER := 0;
10400 l_total_number_of_days NUMBER := 0;
10401 l_advance_arrears VARCHAR2(30);
10402
10403 ld_start_date DATE;
10404 l_start_date DATE;
10405 l_term_complete VARCHAR2(1) := 'N';
10406 l_increment NUMBER;
10407 l_abs_incr NUMBER;
10408 l_prev_incr_sign NUMBER;
10409 l_crossed_zero VARCHAR2(1) := 'N';
10410 l_diff NUMBER;
10411 l_prev_diff NUMBER :=1;
10412 l_prev_diff_sign NUMBER ;
10413 l_purpose_code VARCHAR2(30) := 'FLOW';
10414 lv_adv_arr VARCHAR2(30);
10415 lv_currency_code okc_k_headers_b.currency_code%TYPE;
10416 l_selv_tbl okl_streams_pub.selv_tbl_type;
10417 l_pt_tbl okl_streams_pub.selv_tbl_type;
10418 l_pay_level payment_tbl_type := p_pay_level;
10419 lx_pay_level payment_tbl_type;
10420 l_cash_flow_tbl cash_flow_tbl_type;
10421 k NUMBER :=1;
10422 loop_counter BINARY_INTEGER := 0;
10423 l_open_balance NUMBER :=0;
10424 l_currency_code okc_k_headers_b.currency_code%TYPE;
10425
10426 CURSOR c_hdr_csr(p_khr_id okc_k_headers_b.id%TYPE)
10427 IS
10428 SELECT currency_code
10429 FROM okc_k_headers_b
10430 WHERE id = p_khr_id;
10431
10432 --Added by djanaswa for bug 6007644
10433 l_recurrence_date DATE := NULL;
10434 --end djanaswa
10435
10436 l_day_convention_month VARCHAR2(30);
10437 l_day_convention_year VARCHAR2(30);
10438 l_days_in_year NUMBER;
10439
10440 BEGIN
10441 IF (G_DEBUG_ENABLED = 'Y') THEN
10442 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
10443 END IF;
10444
10445 x_return_status := OKL_API.G_RET_STS_SUCCESS;
10446 -- Call start_activity to create savepoint, check compatibility
10447 -- and initialize message list
10448 x_return_status := okl_api.start_activity (
10449 l_api_name
10450 ,p_init_msg_list
10451 ,'_PVT'
10452 ,x_return_status);
10453 -- Check if activity started successfully
10454 IF (x_return_status = okl_api.g_ret_sts_unexp_error) THEN
10455 RAISE okl_api.g_exception_unexpected_error;
10456 ELSIF (x_return_status = okl_api.g_ret_sts_error) THEN
10457 RAISE okl_api.g_exception_error;
10458 END IF;
10459 -- Fetch the day convention ..
10460 OKL_PRICING_UTILS_PVT.get_day_convention(
10461 p_id => p_khr_id,
10462 p_source => 'ISG',
10463 x_days_in_month => l_day_convention_month,
10464 x_days_in_year => l_day_convention_year,
10465 x_return_status => x_return_status);
10466 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10467 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, 'get_payment_after_ppd Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
10468 END IF;
10469 IF (x_return_status = G_RET_STS_UNEXP_ERROR) THEN
10470 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10471 ELSIF (x_return_status = G_RET_STS_ERROR) THEN
10472 RAISE OKL_API.G_EXCEPTION_ERROR;
10473 END IF;
10474
10475 OPEN c_hdr_csr(p_khr_id => p_khr_id);
10476 FETCH c_hdr_csr INTO lv_currency_code;
10477 IF c_hdr_csr%NOTFOUND THEN
10478 okl_api.set_message(p_app_name => G_APP_NAME,
10479 p_msg_name => G_LLA_NO_MATCHING_RECORD,
10480 p_token1 => G_COL_NAME_TOKEN,
10481 p_token1_value => 'Currency Code');
10482 RAISE okl_api.g_exception_error;
10483 END IF;
10484 CLOSE c_hdr_csr;
10485
10486 -- To get the ratio of the existing payment
10487 -- this would help build future payments after
10488 -- ppd.
10489
10490 FOR i IN l_pay_level.FIRST..l_pay_level.LAST LOOP
10491 IF l_pay_level(i).amount <> 0 AND
10492 l_pay_level(i).amount <> okl_api.g_miss_num THEN
10493 l_first_payment := l_pay_level(i).amount;
10494 END IF;
10495 EXIT;
10496 END LOOP;
10497
10498 l_start_date := l_pay_level(l_pay_level.FIRST).start_date;
10499 FOR i IN l_pay_level.FIRST..l_pay_level.LAST LOOP
10500 IF l_pay_level(i).amount <> 0 AND
10501 l_pay_level(i).amount <> okl_api.g_miss_num THEN
10502 l_pay_level(i).ratio := l_pay_level(i).amount/l_first_payment;
10503 l_no_of_periods := l_no_of_periods + l_pay_level(i).periods;
10504
10505 END IF;
10506
10507 IF ( l_pay_level(i).arrears_yn = 'Y' ) THEN
10508 l_advance_arrears := 'ARREARS';
10509 ELSE
10510 l_advance_arrears := 'ADVANCE';
10511 END IF;
10512
10513 --Added by djanaswa for bug 6007644
10514 IF((l_pay_level(i).periods IS NULL) AND (l_pay_level(i).stub_days IS NOT NULL)) THEN
10515 --Set the recurrence date to null for stub payment
10516 l_recurrence_date := NULL;
10517 ELSIF(l_recurrence_date IS NULL) THEN
10518 --Set the recurrence date as periodic payment level start date
10519 l_recurrence_date := l_pay_level(i).start_date;
10520 END IF;
10521 --end djanaswa
10522 -- Added parameter p_recurrence_date by djanaswa for bug 6007644
10523 okl_stream_generator_pvt.get_stream_elements(
10524 p_start_date => l_pay_level(i).start_date,
10525 p_periods => l_pay_level(i).periods,
10526 p_frequency => l_pay_level(i).frequency,
10527 p_structure => l_pay_level(i).structure,
10528 p_advance_or_arrears => l_advance_arrears, --l_pay_level(i).adv_arr,
10529 p_amount => l_pay_level(i).amount,
10530 p_stub_days => l_pay_level(i).stub_days,
10531 p_stub_amount => l_pay_level(i).stub_amount,
10532 p_currency_code => l_currency_code,
10533 p_khr_id => p_khr_id,
10534 p_kle_id => p_kle_id,
10535 p_purpose_code => l_purpose_code,
10536 x_selv_tbl => l_selv_tbl,
10537 x_pt_tbl => l_pt_tbl,
10538 x_return_status => x_return_status,
10539 x_msg_count => x_msg_count,
10540 x_msg_data => x_msg_data,
10541 p_recurrence_date => l_recurrence_date);
10542 IF (x_return_status = okl_api.g_ret_sts_unexp_error) THEN
10543 EXIT WHEN(x_return_status = okl_api.g_ret_sts_unexp_error);
10544 ELSIF (x_return_status = okl_api.g_ret_sts_error) THEN
10545 EXIT WHEN(x_return_status = okl_api.g_ret_sts_error);
10546 END IF;
10547
10548
10549
10550 FOR j IN l_selv_tbl.FIRST..l_selv_tbl.LAST LOOP
10551
10552 ln_int_ppd_days := OKL_PRICING_UTILS_PVT.get_day_count(
10553 p_start_date => l_start_date,
10554 p_days_in_month => l_day_convention_month,
10555 p_days_in_year => l_day_convention_year,
10556 p_end_date => l_selv_tbl(j).stream_element_date,
10557 p_arrears => l_pay_level(i).arrears_yn,
10558 x_return_status => x_return_status);
10559
10560 IF (x_return_status = okl_api.g_ret_sts_unexp_error) THEN
10561 EXIT WHEN(x_return_status = okl_api.g_ret_sts_unexp_error);
10562 ELSIF (x_return_status = okl_api.g_ret_sts_error) THEN
10563 EXIT WHEN(x_return_status = okl_api.g_ret_sts_error);
10564 END IF;
10565
10566
10567 l_cash_flow_tbl(k).cf_days := ln_int_ppd_days;
10568 l_cash_flow_tbl(k).cf_date := l_selv_tbl(j).stream_element_date;
10569
10570 l_cash_flow_tbl(k).cf_amount := l_selv_tbl(j).amount;
10571
10572 l_cash_flow_tbl(k).cf_ratio := l_pay_level(i).ratio;
10573 l_start_date := l_selv_tbl(j).stream_element_date;
10574 l_total_number_of_days := l_total_number_of_days + ln_int_ppd_days; -- to count total number of days
10575
10576 k := k+1;
10577
10578
10579 END LOOP;
10580
10581
10582 END LOOP;
10583
10584 IF (l_pay_level(l_pay_level.FIRST).start_date IS NOT NULL OR
10585 l_pay_level(l_pay_level.FIRST).start_date <> okl_api.g_miss_date) AND
10586 (p_ppd_date IS NOT NULL OR
10587 p_ppd_date <> okl_api.g_miss_date) AND
10588 l_pay_level(l_pay_level.FIRST).start_date > p_ppd_date THEN
10589 l_intrm_days := OKL_PRICING_UTILS_PVT.get_day_count(
10590 p_start_date => p_ppd_date,
10591 p_days_in_month => l_day_convention_month,
10592 p_days_in_year => l_day_convention_year,
10593 p_end_date => l_pay_level(l_pay_level.FIRST).start_date,
10594 p_arrears => 'N',
10595 x_return_status => x_return_status);
10596 IF (x_return_status = okl_api.g_ret_sts_unexp_error) THEN
10597 RAISE okl_api.g_exception_unexpected_error;
10598 ELSIF (x_return_status = okl_api.g_ret_sts_error) THEN
10599 RAISE okl_api.g_exception_error;
10600 END IF;
10601 ln_intrm_int := (p_ppd_amt * l_intrm_days * p_rate)/(100 * 360);
10602 END IF;
10603
10604 ln_ppd_guess_int := (p_ppd_amt * l_total_number_of_days * p_rate)/(100 * 360);
10605
10606
10607 ln_ppd_guess := (p_ppd_amt + ln_ppd_guess_int + ln_intrm_int)/l_no_of_periods;
10608
10609 l_open_balance := p_ppd_amt + NVL(ln_intrm_int,0);
10610
10611
10612 ln_ob_ppd := l_open_balance;
10613
10614 l_increment := ln_ppd_guess /4;
10615
10616 LOOP
10617
10618 loop_counter := loop_counter + 1;
10619
10620 ln_ob_ppd := l_open_balance;
10621
10622
10623 FOR k IN l_cash_flow_tbl.FIRST..l_cash_flow_tbl.LAST LOOP
10624
10625 ln_int_ppd := (ln_ob_ppd * l_cash_flow_tbl(k).cf_days * p_rate)/(100 * 360);
10626 ln_ppd_pay := (l_cash_flow_tbl(k).cf_ratio * ln_ppd_guess) - ln_int_ppd;
10627 ln_cb_ppd := ln_ob_ppd - ln_ppd_pay;
10628 ln_ob_ppd := ln_cb_ppd;
10629 END LOOP;
10630 l_diff := ln_ob_ppd;
10631
10632 IF ROUND(l_diff, 4) = 0 THEN
10633
10634 FOR i IN l_pay_level.FIRST..l_pay_level.LAST LOOP
10635 lx_pay_level(i).start_date := l_pay_level(i).start_date;
10636 lx_pay_level(i).periods := l_pay_level(i).periods;
10637 lx_pay_level(i).frequency := l_pay_level(i).frequency;
10638 lx_pay_level(i).structure := l_pay_level(i).structure;
10639 lx_pay_level(i).arrears_yn := l_pay_level(i).arrears_yn;
10640 lx_pay_level(i).amount := ln_ppd_guess * l_pay_level(i).ratio;
10641
10642
10643 END LOOP;
10644 EXIT;
10645
10646 END IF;
10647
10648 IF (SIGN(l_diff) <> SIGN(l_prev_diff)) AND l_crossed_zero = 'N' THEN
10649 l_crossed_zero := 'Y';
10650 END IF;
10651
10652 IF l_crossed_zero = 'Y' THEN
10653 l_abs_incr := ABS(l_increment) /2 ;
10654 ELSE
10655 l_abs_incr := ABS(l_increment);
10656 END IF;
10657
10658
10659 IF loop_counter > 1 THEN
10660 IF SIGN(l_diff) <> l_prev_diff_sign THEN
10661 IF l_prev_incr_sign = 1 THEN
10662 l_increment := -l_abs_incr;
10663 ELSE
10664 l_increment := l_abs_incr;
10665 END IF;
10666 ELSE
10667 IF l_prev_incr_sign = 1 THEN
10668 l_increment := l_abs_incr;
10669 ELSE
10670 l_increment := -l_abs_incr;
10671 END IF;
10672 END IF;
10673 ELSE
10674 IF SIGN(l_diff) = 1 THEN
10675 l_increment := l_increment;
10676 ELSE
10677 l_increment := -l_increment;
10678 END IF;
10679 END IF;
10680
10681 ln_ppd_guess := ln_ppd_guess + l_increment;
10682 l_prev_incr_sign := SIGN(l_increment);
10683 l_prev_diff_sign := SIGN(l_diff);
10684 l_prev_diff := l_diff;
10685 END LOOP;
10686
10687 IF (x_return_status = okl_api.g_ret_sts_unexp_error) THEN
10688 RAISE okl_api.g_exception_unexpected_error;
10689 ELSIF (x_return_status = okl_api.g_ret_sts_error) THEN
10690 RAISE okl_api.g_exception_error;
10691 END IF;
10692 x_pay_level := lx_pay_level;
10693
10694
10695
10696
10697 okl_api.end_activity(x_msg_count => x_msg_count,
10698 x_msg_data => x_msg_data);
10699 EXCEPTION
10700 WHEN okl_api.g_exception_error THEN
10701 IF c_hdr_csr%ISOPEN THEN
10702 CLOSE c_hdr_csr;
10703 END IF;
10704 x_return_status := okl_api.handle_exceptions(
10705 l_api_name,
10706 g_pkg_name,
10707 'OKL_API.G_RET_STS_ERROR',
10708 x_msg_count,
10709 x_msg_data,
10710 '_PVT');
10711 WHEN okl_api.g_exception_unexpected_error THEN
10712 IF c_hdr_csr%ISOPEN THEN
10713 CLOSE c_hdr_csr;
10714 END IF;
10715
10716 x_return_status :=okl_api.handle_exceptions(
10717 l_api_name,
10718 g_pkg_name,
10719 'OKL_API.G_RET_STS_UNEXP_ERROR',
10720 x_msg_count,
10721 x_msg_data,
10722 '_PVT');
10723 WHEN OTHERS THEN
10724
10725 IF c_hdr_csr%ISOPEN THEN
10726 CLOSE c_hdr_csr;
10727 END IF;
10728 x_return_status :=okl_api.handle_exceptions(
10729 l_api_name,
10730 g_pkg_name,
10731 'OTHERS',
10732 x_msg_count,
10733 x_msg_data,
10734 '_PVT');
10735 END get_payment_after_ppd;
10736
10737 ---------------------------------------------------------------------------
10738 -- PROCEDURE generate_loan_schedules
10739 --
10740 -- Description
10741 -- Generate projected loan chedules for actual loans
10742 ---------------------------------------------------------------------------
10743
10744 PROCEDURE generate_loan_schedules (p_khr_id IN NUMBER,
10745 p_investment IN NUMBER,
10746 p_start_date IN DATE,
10747 x_interest_rate OUT NOCOPY NUMBER,
10748 x_schedule_table OUT NOCOPY schedule_table_type,
10749 x_return_status OUT NOCOPY VARCHAR2) IS
10750
10751 l_prog_name CONSTANT VARCHAR2(61) := G_PKG_NAME||'.'||'generate_loan_schedules';
10752
10753 -- cursor to get the end date of the contract
10754 cursor c_contract_end_date(khr_id number) IS
10755 select end_date, CURRENCY_CODE from okc_k_headers_all_b where id=khr_id;
10756
10757
10758
10759 -- cursor to get the start date and arrears flag
10760 CURSOR c_rent_slls IS
10761 SELECT FND_DATE.canonical_to_date(sll.rule_information2) start_date,
10762 TO_NUMBER(SLL.rule_information3) periods,
10763 DECODE(sll.object1_id1, 'M', 30, 'Q', 120, 'S', 180, 'A', 360) dpp,
10764 DECODE(sll.object1_id1, 'M', 1, 'Q', 3, 'S', 6, 'A', 12) mpp,
10765 NVL(sll.rule_information10, 'N') arrears_yn,
10766 FND_NUMBER.canonical_to_number(sll.rule_information6) rent_amount
10767 FROM okc_rules_b sll,
10768 okc_rules_b slh,
10769 okc_rule_groups_b rgp,
10770 okl_strm_type_b sty,
10771 okl_strm_type_tl styt
10772 WHERE rgp.dnz_chr_id = p_khr_id
10773 AND rgp.rgd_code= 'LALEVL'
10774 AND rgp.id = slh.rgp_id
10775 AND slh.rule_information_category = 'LASLH'
10776 AND TO_NUMBER(slh.object1_id1) = sty.id
10777 AND sty.version = '1.0'
10778 AND sty.id = styt.id
10779 AND STYT.LANGUAGE = USERENV('LANG')
10780 AND TO_CHAR(slh.id) = sll.object2_id1
10781 AND sll.rule_information_category = 'LASLL'
10782 ORDER BY fnd_date.canonical_to_date(sll.rule_information2);
10783
10784 l_rent_sll c_rent_slls%ROWTYPE;
10785
10786 -- cursor to get the payment streams
10787 CURSOR c_rent_flows (p_loan_start_date date ,p_end_date date) IS
10788 SELECT sum(sel.amount) se_amount,
10789 sel.stream_element_date se_date,
10790 sel.comments se_arrears,
10791 sty.stream_type_purpose,
10792 decode(sty.stream_type_purpose,'LOAN_PAYMENT',1,'UNSCHEDULED_PRINCIPAL_PAYMENT',2,'UNSCHEDULED_LOAN_PAYMENT',2,'VARIABLE_LOAN_PAYMENT',3,4) stream_ordr
10793 FROM okl_strm_elements sel,
10794 okl_streams stm,
10795 okl_strm_type_b sty,
10796 okl_strm_type_tl styt
10797 WHERE stm.khr_id =p_khr_id
10798 AND stm.say_code = 'CURR'
10799 AND DECODE(stm.purpose_code, NULL, '-99', 'REPORT') = '-99'
10800 AND stm.sty_id = sty.id
10801 AND sty.version = '1.0'
10802 AND sty.id = styt.id
10803 AND STYT.LANGUAGE = USERENV('LANG') -- Bug 4626837
10804 AND sty.stream_type_purpose in ('LOAN_PAYMENT', 'VARIABLE_LOAN_PAYMENT','UNSCHEDULED_PRINCIPAL_PAYMENT','UNSCHEDULED_LOAN_PAYMENT')
10805 AND sel.date_billed is null
10806 AND stm.id = sel.stm_id
10807 AND sel.stream_element_date >=p_loan_start_date
10808 AND sel.stream_element_date <=p_end_date
10809 GROUP BY
10810 sel.stream_element_date ,
10811 decode(sty.stream_type_purpose,'LOAN_PAYMENT',1,'UNSCHEDULED_PRINCIPAL_PAYMENT',2,'UNSCHEDULED_LOAN_PAYMENT',2,'VARIABLE_LOAN_PAYMENT',3,4),
10812 sel.comments,
10813 sty.stream_type_purpose
10814 ORDER BY stream_element_date,
10815 decode(sty.stream_type_purpose,'LOAN_PAYMENT',1,'UNSCHEDULED_PRINCIPAL_PAYMENT',2,'UNSCHEDULED_LOAN_PAYMENT',2,'VARIABLE_LOAN_PAYMENT',3,4);
10816
10817 CURSOR get_precision(p_currency_code OKC_K_HEADERS_B.CURRENCY_CODE%TYPE) IS
10818 SELECT PRECISION
10819 FROM fnd_currencies_vl
10820 WHERE currency_code = p_currency_code
10821 AND enabled_flag = 'Y'
10822 AND NVL(start_date_active, SYSDATE) <= SYSDATE
10823 AND NVL(end_date_active, SYSDATE) >= SYSDATE;
10824
10825 TYPE loan_rec IS RECORD (se_amount NUMBER,
10826 se_date DATE,
10827 se_days NUMBER,
10828 se_arrears okl_strm_elements.comments%type,
10829 se_purpose okl_strm_type_b.stream_type_purpose%type);
10830
10831 TYPE loan_tbl IS TABLE OF loan_rec INDEX BY BINARY_INTEGER;
10832
10833 round_interest_tbl Okl_Streams_Pub.selv_tbl_type;
10834 rounded_interest_tbl Okl_Streams_Pub.selv_tbl_type;
10835
10836 interest_rate_tbl OKL_VARIABLE_INTEREST_PVT.interest_rate_tbl_type;
10837
10838 asset_rents loan_tbl;
10839
10840 l_sty_id NUMBER;
10841 l_stream_name VARCHAR2(256);
10842
10843 l_start_date DATE;
10844
10845 l_open_book NUMBER;
10846 l_close_book NUMBER;
10847 l_payment NUMBER;
10848 l_interest NUMBER;
10849 l_interest_unsch_prin_pay NUMBER:=0;
10850 l_principal NUMBER;
10851
10852 l_iir NUMBER;
10853 l_rent_period_end c_contract_end_date%ROWTYPE;
10854 k BINARY_INTEGER := 0;
10855 lx_return_status VARCHAR2(1);
10856
10857 l_day_convention_month VARCHAR2(30);
10858 l_day_convention_year VARCHAR2(30);
10859 l_days_in_year NUMBER;
10860
10861 l_exit_loop_flag VARCHAR2(2);
10862
10863 l_precision NUMBER;
10864
10865 p_init_msg_list varchar2(256);
10866 x_msg_count number;
10867 x_msg_data varchar2(256);
10868
10869 BEGIN
10870 IF (G_DEBUG_ENABLED = 'Y') THEN
10871 G_IS_DEBUG_STATEMENT_ON := OKL_DEBUG_PUB.CHECK_LOG_ON(G_MODULE, FND_LOG.LEVEL_STATEMENT);
10872 END IF;
10873
10874 -- Get the interest rate for the start date
10875
10876 OKL_VARIABLE_INTEREST_PVT.interest_date_range (
10877 p_api_version => g_api_version,
10878 p_init_msg_list => p_init_msg_list,
10879 x_return_status => lx_return_status,
10880 x_msg_count => x_msg_count,
10881 x_msg_data => x_msg_data,
10882 p_contract_id => p_khr_id,
10883 p_start_date => p_start_date,
10884 p_end_date => p_start_date,
10885 p_process_flag => OKL_VARIABLE_INTEREST_PVT.G_INTEREST_CALCULATION_BASIS,
10886 x_interest_rate_tbl =>interest_rate_tbl);
10887
10888 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
10889 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10890 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
10891 RAISE OKL_API.G_EXCEPTION_ERROR;
10892 END IF;
10893 -- print( l_prog_name, 'interest_rate_tbl.COUNT:' || interest_rate_tbl.COUNT );
10894 -- print( l_prog_name, 'interest_rate_tbl(1).rate:' || interest_rate_tbl(1).rate );
10895 if interest_rate_tbl.COUNT = 0 THEN
10896 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10897 END IF;
10898
10899 IF interest_rate_tbl(1).rate = 0 THEN
10900 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10901 END IF;
10902
10903 l_iir:=interest_rate_tbl(1).rate;
10904 x_interest_rate:=l_iir;
10905
10906 -- print( l_prog_name, 'l_iir ' || l_iir );
10907
10908 l_iir:=l_iir/100;
10909
10910 -- Get the contract last date
10911 open c_contract_end_date(p_khr_id);
10912 fetch c_contract_end_date into l_rent_period_end;
10913 close c_contract_end_date;
10914
10915 open get_precision(l_rent_period_end.currency_code);
10916 fetch get_precision into l_precision;
10917 close get_precision;
10918
10919 -- Fetch the day convention ..
10920 OKL_PRICING_UTILS_PVT.get_day_convention(
10921 p_id => p_khr_id,
10922 p_source => 'ISG',
10923 x_days_in_month => l_day_convention_month,
10924 x_days_in_year => l_day_convention_year,
10925 x_return_status => lx_return_status);
10926
10927 IF (G_IS_DEBUG_STATEMENT_ON = true) THEN
10928 OKL_DEBUG_PUB.LOG_DEBUG(FND_LOG.LEVEL_STATEMENT, G_MODULE, l_prog_name || 'Month / Year = ' || l_day_convention_month || '/' || l_day_convention_year );
10929 END IF;
10930 IF (lx_return_status = G_RET_STS_UNEXP_ERROR) THEN
10931 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10932 ELSIF (lx_return_status = G_RET_STS_ERROR) THEN
10933 RAISE OKL_API.G_EXCEPTION_ERROR;
10934 END IF;
10935
10936 OPEN c_rent_slls;
10937 FETCH c_rent_slls INTO l_rent_sll;
10938 CLOSE c_rent_slls;
10939
10940
10941 -- print( l_prog_name, 'l_rent_sll.arrears_yn ' || l_rent_sll.arrears_yn );
10942
10943 l_start_date := p_start_date;
10944
10945 -- print( l_prog_name, 'l_start_date ' || l_start_date );
10946 -- print( l_prog_name, 'l_rent_sll.dpp ' || l_rent_sll.dpp );
10947 -- print( l_prog_name, 'l_rent_period_end ' || l_rent_period_end);
10948 -- print( l_prog_name, 'l_rent_period_end ' || (l_rent_period_end + l_rent_sll.dpp));
10949 -- print( l_prog_name, 'No of rent flow rows fetched:'||c_rent_flows(p_start_date,l_rent_period_end + l_rent_sll.dpp)%count);
10950
10951 FOR l_rent_flow IN c_rent_flows(p_start_date,l_rent_period_end.end_date + l_rent_sll.dpp) LOOP
10952 k := k + 1;
10953
10954 print( l_prog_name, 'l_start_date :' || l_start_date );
10955
10956 asset_rents(k).se_days := OKL_PRICING_UTILS_PVT.get_day_count(p_start_date => l_start_date,
10957 p_days_in_month => l_day_convention_month,
10958 p_days_in_year => l_day_convention_year,
10959 p_end_date => l_rent_flow.se_date,
10960 p_arrears => l_rent_flow.se_arrears,
10961 x_return_status => lx_return_status);
10962
10963 IF lx_return_status = OKL_API.G_RET_STS_UNEXP_ERROR THEN
10964 RAISE OKL_API.G_EXCEPTION_UNEXPECTED_ERROR;
10965 ELSIF lx_return_status = OKL_API.G_RET_STS_ERROR THEN
10966 RAISE OKL_API.G_EXCEPTION_ERROR;
10967 END IF;
10968
10969 if ( l_rent_flow.stream_type_purpose = 'UNSCHEDULED_PRINCIPAL_PAYMENT') then
10970 asset_rents(k).se_purpose := 'P';
10971 else
10972 asset_rents(k).se_purpose := 'B';
10973 end if;
10974
10975 -- print( l_prog_name, 'asset_rents(k).se_days ' || asset_rents(k).se_days );
10976 -- print( l_prog_name, 'l_rent_flow.se_amount ' || l_rent_flow.se_amount );
10977 asset_rents(k).se_amount := l_rent_flow.se_amount;
10978 asset_rents(k).se_date := l_rent_flow.se_date;
10979 asset_rents(k).se_arrears := l_rent_flow.se_arrears;
10980 l_start_date :=l_rent_flow.se_date;
10981
10982 -- print( l_prog_name, 'l_rent_flow.se_arrears:' || l_rent_flow.se_arrears );
10983
10984 END LOOP;
10985
10986 -- print( l_prog_name, ' asset rent count ' || to_char(asset_rents.COUNT));
10987
10988 l_open_book := p_investment;
10989 -- print( l_prog_name, ' Investment ' || to_char(l_open_book));
10990 -- print( l_prog_name, 'asset_rents.COUNT:'||asset_rents.COUNT);
10991
10992 FOR k IN 1..asset_rents.COUNT LOOP
10993 l_principal :=0;
10994 l_interest :=0;
10995 l_payment := asset_rents(k).se_amount;
10996 -- print( l_prog_name, 'asset_rents(k).se_amount:'||asset_rents(k).se_amount);
10997 -- print( l_prog_name, 'asset_rents(k).se_days:'||asset_rents(k).se_days);
10998 -- print( l_prog_name, 'l_open_book:'||l_open_book);
10999
11000 if (l_open_book < asset_rents(k).se_amount and k < asset_rents.COUNT )
11001 or (k=asset_rents.COUNT and l_open_book > 0) then
11002 l_close_book :=l_open_book-l_close_book;
11003 IF ( asset_rents(k).se_purpose = 'B' ) then
11004 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
11005 l_interest := ROUND(l_interest, l_precision);
11006 if l_interest_unsch_prin_pay > 0 then
11007 l_interest := l_interest + l_interest_unsch_prin_pay;
11008 l_interest_unsch_prin_pay:=0;
11009 end if;
11010 l_principal := l_open_book;
11011 ELSE
11012 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
11013 l_interest := ROUND(l_interest, l_precision);
11014 if l_interest_unsch_prin_pay > 0 then
11015 l_interest := l_interest + l_interest_unsch_prin_pay;
11016 l_interest_unsch_prin_pay:=0;
11017 end if;
11018 l_principal := l_payment;
11019 END IF;
11020 l_open_book := l_close_book;
11021 l_exit_loop_flag:='Y';
11022 else
11023 If ( asset_rents(k).se_purpose = 'B' ) then
11024 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
11025 l_interest := ROUND(l_interest, l_precision);
11026 if l_interest_unsch_prin_pay > 0 then
11027 l_interest := l_interest + l_interest_unsch_prin_pay;
11028 l_interest_unsch_prin_pay:=0;
11029 end if;
11030 l_principal := l_payment - l_interest;
11031 else
11032 if ( asset_rents(k).se_purpose = 'L' ) then
11033 l_interest := l_open_book*asset_rents(k).se_days*l_iir/360;
11034 l_interest := ROUND(l_interest, l_precision);
11035 else
11036 l_interest_unsch_prin_pay:=l_interest_unsch_prin_pay+l_open_book*asset_rents(k).se_days*l_iir/360;
11037 l_interest_unsch_prin_pay := ROUND(l_interest_unsch_prin_pay, l_precision);
11038 end if;
11039 l_principal := l_payment;
11040 end if;
11041 l_close_book := l_open_book - l_principal;
11042 l_open_book := l_close_book;
11043 end if;
11044
11045 x_schedule_table(k).schedule_principal := l_principal;
11046 x_schedule_table(k).schedule_interest := l_interest;
11047
11048 x_schedule_table(k).schedule_prin_bal := l_close_book;
11049 x_schedule_table(k).schedule_date := asset_rents(k).se_date;
11050
11051 print( l_prog_name, l_principal||' '||l_interest||' '||l_close_book);
11052
11053 print( l_prog_name, 'l_open_book:'||l_open_book);
11054
11055 IF l_exit_loop_flag='Y' THEN
11056 EXIT;
11057 END IF;
11058 END LOOP;
11059 x_return_status := lx_return_status;
11060 print( l_prog_name, 'end' );
11061
11062 EXCEPTION
11063
11064 WHEN OKL_API.G_EXCEPTION_ERROR THEN
11065
11066 x_return_status := G_RET_STS_ERROR;
11067
11068 WHEN OKL_API.G_EXCEPTION_UNEXPECTED_ERROR THEN
11069
11070 x_return_status := G_RET_STS_UNEXP_ERROR;
11071
11072 WHEN OTHERS THEN
11073
11074 OKL_API.SET_MESSAGE (p_app_name => G_APP_NAME,
11075 p_msg_name => G_DB_ERROR,
11076 p_token1 => G_PROG_NAME_TOKEN,
11077 p_token1_value => l_prog_name,
11078 p_token2 => G_SQLCODE_TOKEN,
11079 p_token2_value => sqlcode,
11080 p_token3 => G_SQLERRM_TOKEN,
11081 p_token3_value => sqlerrm);
11082
11083 x_return_status := G_RET_STS_UNEXP_ERROR;
11084
11085 END generate_loan_schedules;
11086
11087
11088 PROCEDURE print(p_progname IN VARCHAR2,p_message IN VARCHAR2)
11089 IS
11090 BEGIN
11091 fnd_file.put_line (fnd_file.log,p_progname||'::'||p_message);
11092 okl_debug_pub.logmessage(p_progname||'::'||p_message);
11093 END print;
11094
11095 END OKL_PRICING_PVT;