DBA Data[Home] [Help]

PACKAGE BODY: APPS.ARP_STAGED_DUNNING

Source


1 PACKAGE BODY ARP_STAGED_DUNNING as
2 /* $Header: ARCUSDLB.pls 115.10 2002/11/15 02:28:51 anukumar ship $ */
3 
4 /*-------------------------------------------------------------------------+
5  |                                                                         |
6  | PRIVATE VARIABLES                                                       |
7  |                                                                         |
8  +-------------------------------------------------------------------------*/
9 -- to store SELECT Statement
10   sql_statement		VARCHAR2(2000);
11 
12 
13 /*----------------------------------------------------------------------------*
14  | PUBLIC FUNCTION                                                            |
15  |    staged_dunning( site       IN site_type			              |
16  |		     ,parameter  IN parameter_type			      |
17  |    		     ,letter_tab IN OUT NOCOPY letter_id_tab  			      |
18  |		     ,letter_count IN OUT NOCOPY NUMBER                              |
19  |                   ,single_letter_flag IN VARCHAR2) RETURN BOOLEAN AS       |
20  |                                                                            |
21  |                                                                            |
22  | DESCRIPTION                                                                |
23  |    Given an input list of parameters for a customer/site, get dunning let- |
24  |    ters for on which the open payment  schedules of this customer/site will|
25  |    be printed. Return FALSE if NO letter could be found                    |
26  |                                                                            |
27  |                                                                            |
28  | MODIFIES                                                                   |
29  |    letter_tab  store dunning letter information                            |
30  |    letter_count count dunning_letters found				      |
31  |                                                                            |
32  | RETURNS                                                                    |
33  |    TRUE   - at least 1 dunning letter found                                |
34  |    FALSE  - no dunning letter found                                        |
35  |                                                                            |
36  |                                                                            |
37  | HISTORY                                                                    |
38  |   7/31/95  Christine Vogel  Created                                        |
39  |   8/7/96   Paul Rooney      Modified to accept single_letter_flag          |
40  |   8/25/96  Simon Jou        Modified for staged dunning/credit memo        |
41  *----------------------------------------------------------------------------*/
42 
43 FUNCTION staged_dunning( site         IN site_type
44 			,parameter    IN parameter_type
45 			,letter_tab   IN OUT NOCOPY letter_id_tab
46 			,letter_count IN OUT NOCOPY NUMBER
47                         ,single_letter_flag IN VARCHAR2) RETURN BOOLEAN AS
48 
49 -- define array to store distinct dunning levels
50   TYPE leveltab IS TABLE OF ar_payment_schedules.staged_dunning_level%TYPE
51 	INDEX BY BINARY_INTEGER;
52   level_tab	leveltab;
53 
54 -- define cursor for the dynamic SELECT of the open payment schedules
55   ps_cursor	integer;
56   sum_cursor	integer;
57 
58 -- define variables to select values in
59   ps_id		          NUMBER(15);
60   inv_code	          VARCHAR2(15);
61 
62   curr_code               VARCHAR2(15);
63   adr		          NUMBER;
64   sum_adr                 NUMBER;
65   days_late	          NUMBER;
66   st_dunning_level        NUMBER(3);
67   dunning_level_override_date       DATE;
68 
69 -- define other variables
70   current_dun_date      DATE;
71   ok_flag  		BOOLEAN;
72   prev_currency		VARCHAR2(15);
73   dun_flag		BOOLEAN;
74   dun_ok		BOOLEAN;
75   change_flag		BOOLEAN;
76   i			NUMBER(4);
77   j			NUMBER(4);
78   min_dun_amount	NUMBER;
79   min_dun_inv_amount	NUMBER;
80   help_level		NUMBER(2);
81   ignore                INTEGER;
82   id		        NUMBER;
83   error_message         varchar2(2000);
84   level_tab_dummy   leveltab;
85   letter_tab_dummy  letter_id_tab;
86   t                     NUMBER(4);
87   sql_statement_s       VARCHAR2(2000);
88 
89 BEGIN
90 
91   -- initialize the array
92   level_tab := level_tab_dummy;
93   letter_tab := letter_tab_dummy;
94 
95   -- build the SELECT statement to retrieve the open payment schedules for cus-
96   -- tomer/site which are not Guarantees and are not unapproved adjustments
97   sql_statement :=
98 	'SELECT	  ps.payment_schedule_id'				||
99 		',ps.invoice_currency_code'				||
100 		',ps.amount_due_remaining'				||
101 		',fnd_date.canonical_to_date(:b_dun_date) - ps.due_date ' 	||
102 		',ps.staged_dunning_level'	         		||
103 		',ps.dunning_level_override_date'          		||
104 	  ' FROM  ar_payment_schedules ps';
105 
106   sql_statement_s :=
107 	'SELECT	  ps.invoice_currency_code, '                           ||
108                 ' sum(ps.amount_due_remaining) '                        ||
109         ' FROM   ar_payment_schedules ps';
110 
111   if parameter.transaction_type_from is not null
112      OR
113      parameter.transaction_type_to is not null then
114     sql_statement := sql_statement 					||
115 	', ra_cust_trx_types t ';
116     sql_statement_s := sql_statement_s 					||
117 	', ra_cust_trx_types t ';
118 
119   end if;
120 
121 /* Refered to bug # 436336
122    Transaction types such as CM or PMT are also needed in deciding a
123    dunning letter.
124    The idea is that: besides just taking the individual INV type trx into
125    account, the sum of INV, CM and PMT of the same currency should be greater
126    or equal than minimum dunning amount for single dunning letter option.
127    Otherwise, the program may pick up some single trx which appears that it
128    should be dunned, and use that as an indication to choose a dunning letter.
129    But in actual fact, the program should have calculated the sum of the trxs
130    (INV, PMT and CM) and found out NOCOPY the sum would have been lesser than min
131    dunning amount and that letter should never have be chosen.
132  */
133 
134    sql_statement := sql_statement					||
135 	 ' WHERE  ps.customer_id	= :b_customer_id '		||
136 	   ' AND  ps.status		= ''OP'''			||
137 	   ' AND  nvl(ps.exclude_from_dunning_flag,''N'') = ''N'''      ||
138            ' AND  ps.class NOT in (''GUAR'')';
139    sql_statement_s := sql_statement_s	           			||
140          ' WHERE  ps.customer_id	= :b_customer_id '		||
141 	   ' AND  ps.status		= ''OP'''			||
142 	   ' AND  nvl(ps.exclude_from_dunning_flag,''N'') = ''N'''      ||
143            ' AND  ps.class NOT in (''GUAR'')';
144   -- bug # 436336: changed form the below:
145   --         ' AND  ps.class NOT in (''GUAR'', ''CM'', ''PMT'')';
146  /* 2107939
147  On Account and Unapplied Payments should only be considered if the
148  Dunning Letter Set has the 'Include Unapplied Receipts' field set to
149  Yes. Added the If condition below.
150  Start of bug fix for 2107939. */
151 
152    IF site.include_payments = 'N' THEN
153 	sql_statement := sql_statement                                  ||
154               ' AND ps.class NOT IN (''PMT'')';
155    	sql_statement_s := sql_statement_s				||
156            ' AND  ps.class NOT IN (''PMT'')';
157    END IF;
158  /* End of bug fix for 2107939.*/
159   if site.grace_days = 'Y' then
160        sql_statement := sql_statement					||
161 	  ' AND  nvl(ps.trx_date,fnd_date.canonical_to_date(:b_dun_date))+'||
162                ' to_number(:b_payment_grace_days) '		        ||
163 		  ' <= fnd_date.canonical_to_date(:b_dun_date)';
164        sql_statement_s := sql_statement_s				||
165 	  ' AND  nvl(ps.trx_date,fnd_date.canonical_to_date(:b_dun_date))+'||
166                ' to_number(:b_payment_grace_days) '		        ||
167 		  ' <= fnd_date.canonical_to_date(:b_dun_date)';
168 
169   else
170        sql_statement := sql_statement					||
171 	   ' AND  nvl(ps.trx_date,fnd_date.canonical_to_date(:b_dun_date))'||
172 		  ' <= fnd_date.canonical_to_date(:b_dun_date)';
173        sql_statement_s := sql_statement_s				||
174 	   ' AND  nvl(ps.trx_date,fnd_date.canonical_to_date(:b_dun_date))'||
175 		  ' <= fnd_date.canonical_to_date(:b_dun_date)';
176 
177   end if;
178 
179   if parameter.transaction_type_from is not null
180      OR
181      parameter.transaction_type_to is not null
182   then
183 	sql_statement := sql_statement					||
184 	' AND ps.cust_trx_type_id = t.cust_trx_type_id ';
185 	sql_statement_s := sql_statement_s				||
186 	' AND ps.cust_trx_type_id = t.cust_trx_type_id ';
187 
188   end if;
189 
190   if parameter.transaction_type_from is not null
191      AND
192      parameter.transaction_type_to is not null
193      AND
194       parameter.transaction_type_from = parameter.transaction_type_to
195   then
196       sql_statement := sql_statement					||
197  	' AND t.name = :b_transaction_type_from ';
198       sql_statement_s := sql_statement_s				||
199  	' AND t.name = :b_transaction_type_from ';
200   else
201      if parameter.transaction_type_from is not null
202      then
203        sql_statement := sql_statement					||
204  	' AND t.name||'''' >= :b_transaction_type_from ';
205        sql_statement_s := sql_statement_s				||
206  	' AND t.name||'''' >= :b_transaction_type_from ';
207      end if;
208      if parameter.transaction_type_to is not null
209      then
210        sql_statement := sql_statement					||
211  	' AND t.name||'''' <= :b_transaction_type_to ';
212        sql_statement_s := sql_statement_s				||
213  	' AND t.name||'''' <= :b_transaction_type_to ';
214      end if;
215   end if;
216 
217   if site.dunning_level = 'S' then
218     sql_statement := sql_statement					||
219 	    ' AND ps.customer_site_use_id	= :b_site_use_id';
220     sql_statement_s := sql_statement_s					||
221 	    ' AND ps.customer_site_use_id	= :b_site_use_id';
222   end if;
223 
224   if site.dun_disputed_items = 'N' then
225     sql_statement  := sql_statement					||
226 	' AND  nvl(ps.amount_in_dispute, 0) = 0 '			||
227 	' AND NOT EXISTS('						||
228 		'SELECT ''Unapproved Adjustments '''			||
229 		  ' FROM  ar_adjustments adj'				||
230 		 ' WHERE  adj.payment_schedule_id = ps.payment_schedule_id'||
231 		   ' AND  adj.status NOT IN (''A'',''R'',''U''))';
232     sql_statement_s  := sql_statement_s					||
233 	' AND  nvl(ps.amount_in_dispute, 0) = 0 '			||
234 	' AND NOT EXISTS('						||
235 		'SELECT ''Unapproved Adjustments '''			||
236 		  ' FROM  ar_adjustments adj'				||
237 		 ' WHERE  adj.payment_schedule_id = ps.payment_schedule_id'||
238 		   ' AND  adj.status NOT IN (''A'',''R'',''U''))';
239   end if;
240 
241   sql_statement_s  := sql_statement_s					||
242   ' AND ps.invoice_currency_code = :curr';
243 
244   sql_statement := sql_statement					||
245 	' ORDER BY ps.invoice_currency_code';
246   sql_statement_s := sql_statement_s					||
247 	' GROUP BY ps.invoice_currency_code'                            ||
248 	' ORDER BY ps.invoice_currency_code';
249   -- bug #436336 : changed from the below:
250   --    ' ORDER BY ps.staged_dunning_level';
251 
252   ps_cursor   := dbms_sql.open_cursor;
253 
254   dbms_sql.parse(ps_cursor, sql_statement, dbms_sql.v7 );
255 
256   -- bind variables into placeholder
257   dbms_sql.bind_variable(ps_cursor,':b_dun_date',parameter.dun_date);
258   if site.dunning_level = 'S' then
259       dbms_sql.bind_variable(ps_cursor,':b_site_use_id',site.site_use_id);
260   end if;
261   dbms_sql.bind_variable(ps_cursor,':b_customer_id',site.customer_id);
262   if site.grace_days = 'Y' then
263       dbms_sql.bind_variable(ps_cursor,':b_payment_grace_days',
264                     site.payment_grace_days);
265   end if;
266 
267   if parameter.transaction_type_from is not null
268      AND
269      parameter.transaction_type_to is not null
270      AND
271      parameter.transaction_type_from = parameter.transaction_type_to
272   then
273         dbms_sql.bind_variable(ps_cursor,':b_transaction_type_from',
274 			parameter.transaction_type_from );
275   else
276        if parameter.transaction_type_from is not null
277        then
278          dbms_sql.bind_variable(ps_cursor,':b_transaction_type_from',
279 			parameter.transaction_type_from );
280         end if;
281        if parameter.transaction_type_to is not null
282        then
283          dbms_sql.bind_variable(ps_cursor,':b_transaction_type_to',
284 			parameter.transaction_type_to );
285         end if;
286   end if;
287 
288   -- specify columns to be selected in
289   dbms_sql.define_column(ps_cursor,1,ps_id);
290   dbms_sql.define_column(ps_cursor,2,curr_code,15);
291   dbms_sql.define_column(ps_cursor,3,adr);
292   dbms_sql.define_column(ps_cursor,4,days_late);
293   dbms_sql.define_column(ps_cursor,5,st_dunning_level);
294   dbms_sql.define_column(ps_cursor,6,dunning_level_override_date);
295 
296   sum_adr := 0;
297   dun_ok        := FALSE;
298   ignore        := dbms_sql.execute(ps_cursor);
299   prev_currency := '0';
300   current_dun_date := fnd_date.canonical_to_date(parameter.dun_date);
301 
302   <<Open_Payment_Loop>>
303 LOOP
304 	if dbms_sql.fetch_rows(ps_cursor) <= 0 then
305 	   exit Open_Payment_Loop;
306 	end if;
307 
308  	-- get fetched values from the variables
309 	dbms_sql.column_value(ps_cursor,1,ps_id);
310 	dbms_sql.column_value(ps_cursor,2,curr_code);
311 	dbms_sql.column_value(ps_cursor,3,adr);
312 	dbms_sql.column_value(ps_cursor,4,days_late);
313 	dbms_sql.column_value(ps_cursor,5,st_dunning_level);
314 	dbms_sql.column_value(ps_cursor,6,dunning_level_override_date);
315 
316 	if curr_code <> prev_currency then
317 	  ok_flag := ARP_STAGED_DUNNING.get_cpa(site,curr_code,min_dun_amount,
318 			min_dun_inv_amount);
319 	  if ok_flag = FALSE then
320 		exit Open_Payment_Loop;
321 	  end if;
322 	  prev_currency := curr_code;
323 	end if;
324 
325        dun_flag := FALSE;
326        if ((site.grace_days = 'N' and days_late >= 0 )
327 	or
328 	(site.grace_days = 'Y' and days_late >= site.payment_grace_days ))
329 	AND
330 	( adr >= min_dun_inv_amount ) then
331   --	bug # 436336: changed from below:
332   --    ( adr >= min_dun_inv_amount ) then
333 
334 	dun_flag := ARP_STAGED_DUNNING.get_new_dunning_level(ps_id
335 				,st_dunning_level
336 				,current_dun_date
337 				,dunning_level_override_date
338                                 ,days_late
339                                 ,site.letter_set_id);
340 
341  -- For bug# 436336
342  -- for this ps_id find out NOCOPY if the sum of INV, PMT or CM of the same currency
343  -- is <0. if so, then don't insert this transaction into the level tab;
344  -- Only will be done if a new dunning level has been assigned.
345 
346   if (dun_flag = TRUE) then
347 
348     -- Open cursor
349        sum_cursor  := dbms_sql.open_cursor;
350     -- Parse cursor
351        dbms_sql.parse(sum_cursor, sql_statement_s, dbms_sql.v7 );
352     -- Bind variables
353 
354        dbms_sql.bind_variable(sum_cursor,':b_dun_date',parameter.dun_date);
355        if site.dunning_level = 'S' then
356             dbms_sql.bind_variable(sum_cursor,':b_site_use_id',site.site_use_id);
357        end if;
358        dbms_sql.bind_variable(sum_cursor,':b_customer_id',site.customer_id);
359        if site.grace_days = 'Y' then
360            dbms_sql.bind_variable(sum_cursor,':b_payment_grace_days',
361                     site.payment_grace_days);
362        end if;
363 
364       if parameter.transaction_type_from is not null
365          AND
366           parameter.transaction_type_to is not null
367          AND
368           parameter.transaction_type_from = parameter.transaction_type_to
369       then
370          dbms_sql.bind_variable(sum_cursor,':b_transaction_type_from',
371 			parameter.transaction_type_from );
372       else
373          if parameter.transaction_type_from is not null
374          then
375            dbms_sql.bind_variable(sum_cursor,':b_transaction_type_from',
376 			parameter.transaction_type_from );
377           end if;
378          if parameter.transaction_type_to is not null
379          then
380            dbms_sql.bind_variable(sum_cursor,':b_transaction_type_to',
381 			parameter.transaction_type_to );
382         end if;
383       end if;
384       dbms_sql.bind_variable(sum_cursor,':curr',
385 		     	curr_code );
386 
387     -- Define the output column
388        dbms_sql.define_column(sum_cursor, 1, inv_code, 15);
389        dbms_sql.define_column(sum_cursor, 2, sum_adr);
390 
391     -- Execute
392        ignore        := dbms_sql.execute(sum_cursor);
393 
394     -- Fetch a row
395        if dbms_sql.fetch_rows(sum_cursor) <= 0 then
396 	  exit Open_Payment_Loop;
397        end if;
398 
399     -- Get column's value
400        dbms_sql.column_value(sum_cursor, 1, inv_code);
401        dbms_sql.column_value(sum_cursor, 2, sum_adr);
402 
403     -- Close cursor
404        dbms_sql.close_cursor(sum_cursor);
405   end if;
406 
407   if (sum_adr < min_dun_amount) then
408       dun_flag := FALSE;
409   end if;
410 
411 -- end of # bug 436336
412 
413 	-- CONTINUE processing only if open payment schedule should be dunned
414 	-- get min_dun_amount and min_dun_inv_amount only if new dunning level
415 	-- is in the range selected by user( parameter )
416 
417 	if dun_flag = TRUE
418 	AND
419 	 st_dunning_level >= parameter.dunning_level_from
420 	   AND
421 	   st_dunning_level <= parameter.dunning_level_to then
422 
423                 -- save distinct dunning level into array
424 		change_flag := FALSE;
425 		i := 1;
426 		<<Level_Loop>>
427 		LOOP
428 		  BEGIN
429 		   if level_tab(i) = st_dunning_level then
430 			change_flag := TRUE;
431 			exit Level_Loop;
432 		   end if;
433 		   i := i + 1;
434 		  EXCEPTION
435 		    when NO_DATA_FOUND then
436 			exit Level_Loop;
437 		  END;
438 		END LOOP Level_Loop;
439 		if change_flag = FALSE then  -- level not yet in array
440 			level_tab(i) := st_dunning_level;
441 		end if;
442 	end if;     -- end of level in range
443         end if;     -- end of open payment dunning
444         if dun_flag = TRUE then
445   		dun_ok := TRUE;
446         end if;
447 --exit Open_Payment_Loop;
448   END LOOP Open_Payment_Loop;
449 
450 -- return FALSE if no open payment schedule found or function get_cpa returned
451 -- FALSE
452   if ok_flag = FALSE OR dbms_sql.last_row_count <= 0 OR dun_ok = FALSE then
453      if dbms_sql.last_row_count <= 0 OR dun_ok = FALSE then
454        letter_count := 0;
455        dbms_sql.close_cursor(ps_cursor);
456        return(TRUE);
457     else
458        dbms_sql.close_cursor(ps_cursor);
459        return( FALSE );
460     end if;
461   end if;
462   dbms_sql.close_cursor(ps_cursor);
463 
464 
465   -- sort the array of dunning levels
466   change_flag := TRUE;
467   <<While_loop>>
468   WHILE( change_flag ) LOOP
469     i := 1;
470     change_flag := FALSE;
471     <<Change_Loop>>
472     LOOP
473 	BEGIN
474 	  if level_tab(i) > level_tab(i+1) then
475 		help_level     := level_tab(i);
476 		level_tab(i)   := level_tab(i+1);
477 		level_tab(i+1) := help_level;
478 		change_flag    := TRUE;
479 	  end if;
480           i := i + 1;
481 	EXCEPTION
482 	  when NO_DATA_FOUND then
483 		exit Change_Loop;
484 	END;
485     END LOOP Change_Loop;
486   END LOOP While_Loop;
487 
488 
489   -- for each dunning level from array, find corresponding dunning letter
490   -- MAX_STAGED DUNNING distinct dunning letters will be supported. If more
491   -- return FALSE;
492 
493     if nvl(single_letter_flag,'N') <> 'Y' then
494       i := 1;
495     end if;
496   <<Letter_Loop>>
497   LOOP
498     -- because NO_DATA_FOUND can be raised from SELECT and from table
499     -- define this block for table and next one for SELECT
500     BEGIN
501       help_level := level_tab(i);
502     EXCEPTION
503       when NO_DATA_FOUND then
504 	exit Letter_Loop;
505     END ;
506     BEGIN
507 	SELECT	dlsl.dunning_letter_id
508 	  INTO  id
509 	  FROM  ar_dunning_letter_set_lines dlsl
510 	 WHERE  dlsl.dunning_letter_set_id = site.letter_set_id
511 	   AND  help_level BETWEEN dlsl.range_of_dunning_level_from
512 				 AND dlsl.range_of_dunning_level_to;
513 
514 	change_flag := FALSE;
515 	j := 1;
516 	<<Distinct_Letter_Loop>>
517 	LOOP
518 	  BEGIN
519 
520 	   if letter_tab(j) = id then
521 		change_flag := TRUE;
522 		exit Distinct_Letter_Loop;
523 	   end if;
524 	   j := j + 1;
525 	  EXCEPTION
526 	    when NO_DATA_FOUND then
527 		exit Distinct_Letter_Loop;
528 	  END;
529 	END LOOP Distinct_Level_Loop;
530 	if change_flag = FALSE then  -- letter not yet in array
531 
532 		letter_tab(j) := id;
533 	end if;
534 
535 	i := i +1;
536     EXCEPTION
537 	when OTHERS then
538 		return( FALSE );
539     END;
540   END LOOP Letter_Loop;
541 
542   letter_count := j ;
543 
544   if letter_count  >  MAX_STAGED_DUNNING   then
545 	return(FALSE);
546   end if;
547 
548   return( TRUE );
549 END staged_dunning;
550 
551 /*----------------------------------------------------------------------------*
552  | PUBLIC FUNCTION                                                            |
553  |    get_cpa( site		  IN site_type                                |
554  |	      ,curr_code	  IN VARCHAR2				      |
555  |	      ,min_dun_amount	  IN OUT NOCOPY NUMBER				      |
556  |	      ,min_dun_inv_amount IN OUT NOCOPY NUMBER ) RETURN BOOLEAN	      |
557  |                                                                            |
558  | DESCRIPTION                                                                |
559  |    for a given customer/site and currency get the minimum dunning amount   |
560  |    and minimum dunning invoice amount				      |
561  |    If the site has a CUSTOMER dunning level, then only the customer level  |
562  |    profile will be queried. If SITE then the site level profile will be    |
563  |    examined first. If this does not exist, then the values will be taken   |
564  |    from customer level. If this does not exist the amounts will be 0       |
565  |									      |
566  | MODIFIES								      |
567  |    min_dun_amount     store the amount found				      |
568  |    min_dun_inv_amount store amount found				      |
569  |									      |
570  | RETURNS                                                                    |
571  |    TRUE  if no error occured                                               |
572  |    FALSE else							      |
573  |                                                                            |
574  |                                                                            |
575  | KNOWN BUGS                                                                 |
576  |                                                                            |
577  |                                                                            |
578  | HISTORY                                                                    |
579  |  7/31/95  Christine Vogel  Created                                         |
580  |                                                                            |
581  *----------------------------------------------------------------------------*/
582 
583 FUNCTION get_cpa(site			IN site_type
584 	 	, curr_code		IN VARCHAR2
585 		, min_dun_amount	OUT NOCOPY NUMBER
586 		, min_dun_inv_amount	OUT NOCOPY NUMBER ) RETURN BOOLEAN AS
587 BEGIN
588   if site.dunning_level = 'S' then
589 	SELECT	 nvl(site_cpa.min_dunning_amount,
590 		    nvl(cust_cpa.min_dunning_amount, 0 ))
591 		,nvl(site_cpa.min_dunning_invoice_amount,
592 		    nvl(cust_cpa.min_dunning_invoice_amount, 0 ))
593 	  INTO 	 min_dun_amount
594 		,min_dun_inv_amount
595 	  FROM	 hz_customer_profiles		cust_cp
596 		,hz_cust_profile_amts		cust_cpa
597 		,hz_customer_profiles		site_cp
598 		,hz_cust_profile_amts		site_cpa
599 	 where   CUST_CP.CUST_ACCOUNT_ID	= site.customer_id
600 	   AND	 cust_cp.site_use_id IS NULL
601 	   AND 	 cust_cpa.cust_account_profile_id(+)= cust_cp.cust_account_profile_id
602 	   AND 	 cust_cpa.currency_code(+)	= curr_code
603 	   AND	 site_cp.cust_account_id(+)	= cust_cp.cust_account_id
604 	   AND 	 site_cp.site_use_id(+)		= site.site_use_id
605 	   AND	 site_cpa.cust_account_profile_id(+)= site_cp.cust_account_profile_id
606 	   AND   site_cpa.currency_code(+)	= curr_code;
607   else
608       /* bug 2362943 : depending on profile value change where profile amounts are read from */
609 
610       if FND_PROFILE.value( 'AR_USE_STATEMENTS_AND_DUNNING_SITE_PROFILE' ) = 'N' then
611 
612 	SELECT	 nvl(cust_cpa.min_dunning_amount, 0)
613 		,nvl(cust_cpa.min_dunning_invoice_amount, 0)
614 	  INTO 	 min_dun_amount
615 		,min_dun_inv_amount
616 	  FROM	 hz_customer_profiles		cust_cp
617 		,hz_cust_profile_amts		cust_cpa
618 	 WHERE   cust_cp.cust_account_id	= site.customer_id
619 	   AND	 cust_cp.site_use_id IS NULL
620 	   AND 	 cust_cpa.cust_account_profile_id(+)
621                                = cust_cp.cust_account_profile_id
622 	   AND 	 cust_cpa.currency_code(+)	= curr_code;
623       else
624         SELECT  NVL(min_dunning_amount, 0) ,
625                 NVL(min_dunning_invoice_amount, 0)
626           INTO  min_dun_amount,
627                 min_dun_inv_amount
628           FROM  hz_cust_profile_amts
629          WHERE  CUST_ACCOUNT_PROFILE_ID =
630                         (SELECT cust_account_profile_id
631                            FROM hz_customer_profiles
632                           WHERE site_use_id = arpt_sql_func_util.get_bill_id(site.site_use_id))
633            AND     currency_code = curr_code
634            AND     CUST_ACCOUNT_ID = site.customer_id;
635       end if;
636   end if;
637   return( TRUE );
638 
639 EXCEPTION
640   when OTHERS then
641 	return( FALSE );
642 END get_cpa;
643 
644 
645 /*----------------------------------------------------------------------------*
646  | PUBLIC  FUNCTION                                                           |
647  |    get_new_dunning_level( ps_id		     IN NUMBER                |
648  |	                    ,staged_dunning_level    IN OUT NOCOPY NUMBER            |
649  |             		    ,current_dun_date	     IN DATE                  |
650  |	                    ,dunning_level_override_date  IN DATE             |
651  |                          ,days_late IN NUMBER                              |
652  |                          ,o_letter_set_id IN NUMBER ) RETURN BOOLEAN       |
653  |                                                                            |
654  | DESCRIPTION                                                                |
655  |    for a payment schedule get the new dunning level. The user has the      |
656  |    possibility to update the dunning level. Thatfore , dunning level can   |
657  |    not be increased by 1 with every printing of a dunning letter	      |
658  |									      |
659  |									      |
660  | RETURNS                                                                    |
661  |    TRUE if open payment should be dunned, else return FALSE                |
662  |									      |
663  | MODIFIES								      |
664  |    staged_dunning_level						      |
665  |                                                                            |
666  |                                                                            |
667  | KNOWN BUGS                                                                 |
668  |                                                                            |
669  |                                                                            |
670  | HISTORY                                                                    |
671  |  7/31/95  Christine Vogel  Created                                         |
672  |  8/25/96  Simon Jou        Modified for staged dunning/credit memo         |
673  *----------------------------------------------------------------------------*/
674 
675 
676 FUNCTION get_new_dunning_level(ps_id	   IN NUMBER
677 		  ,staged_dunning_level    IN OUT NOCOPY NUMBER
678 		  ,current_dun_date	   IN DATE
679 		  ,dunning_level_override_date IN DATE
680                   ,days_late IN NUMBER
681                   ,o_letter_set_id IN NUMBER ) RETURN BOOLEAN AS
682 
683   last_print_date	DATE;
684   min_dunning_days      NUMBER;
685   previously_dunned     BOOLEAN := TRUE;
686 
687 --  cursor to get latest print for a given open payment schedule
688 --  Note: the new one is not in the ar_correspondence_pay_sched yet,
689 --  so this is the latest one for the existing records.
690 
691   CURSOR last_print IS
692 	SELECT  c.correspondence_date
693 	  FROM  ar_correspondence_pay_sched	cp
694 	       ,ar_correspondences		c
695 	       ,ar_dunning_letter_set_lines     dlsl
696 	 WHERE  cp.payment_schedule_id		= ps_id
697 	   AND  c.preliminary_flag		= 'N'
698 	   AND  cp.staged_dunning_level is NOT NULL
699 	   AND  dlsl.dunning_letter_set_id	= c.reference1
700 	   AND  dlsl.dunning_letter_id		= c.reference2
701 	   AND  cp.correspondence_id		= c.correspondence_id
702       ORDER BY  c.correspondence_date DESC;
703 
704 BEGIN
705 
706   OPEN last_print;
707   FETCH last_print INTO last_print_date;
708 
709   -- if payment not yet dunned, cursor exception %NOTFOUND
710   if last_print%NOTFOUND then
711         previously_dunned := FALSE;
712   end if;
713   CLOSE last_print;
714 
715   SELECT min_days_between_dunning
716   INTO   min_dunning_days
717   FROM   ar_dunning_letter_set_lines
718   WHERE  dunning_letter_set_id = o_letter_set_id
719     AND  range_of_dunning_level_from <= (NVL(staged_dunning_level, 0)+1)
720     AND  range_of_dunning_level_to   >= (NVL(staged_dunning_level, 0)+1);
721 
722 -- If the open payment was previously dunned then
723 --    see if its dunning level has been overriden, if not, see the
724 --    last print date plus the min dunning days < current_dunning_days.
725 --    If WAS overriden, then both the override date AND the last print date
726 --    have to satisfy the above criteria at the same time.
727 -- If not previously dunned then
728 --   see if minimum dunning days <= days_late
729 --
730 -- If any of the above condition is true, increment the dunning level and
731 -- return true; else return false and dunning stays the same.
732 
733 IF previously_dunned THEN
734   IF dunning_level_override_date IS NULL THEN
735       IF last_print_date + min_dunning_days <= current_dun_date THEN
736  	 staged_dunning_level := nvl(staged_dunning_level,0) +1;
737    	 return(TRUE);
738       ELSE
739 	 return(FALSE);
740       END IF;
741   ELSE
742       IF (dunning_level_override_date + min_dunning_days <= current_dun_date)
743          AND (last_print_date + min_dunning_days <= current_dun_date) THEN
744  	 staged_dunning_level := nvl(staged_dunning_level,0) +1;
745    	 return(TRUE);
746       ELSE
747 	 return(FALSE);
748       END IF;
749   END IF;
750 ELSE
751  IF min_dunning_days <= days_late THEN
752     staged_dunning_level := nvl(staged_dunning_level,0) +1;
753     return(TRUE);
754  ELSE
755     return(FALSE);
756  END IF;
757 END IF;
758 
759 EXCEPTION
760   when NO_DATA_FOUND then
761     return(FALSE);
762 
763 END get_new_dunning_level;
764 
765 
766 END ARP_STAGED_DUNNING;