DBA Data[Home] [Help]

PACKAGE BODY: APPS.OKL_PRICING_PVT

Source


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