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