DBA Data[Home] [Help]

PACKAGE BODY: APPS.OKL_PRICING_PVT

Source


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