DBA Data[Home] [Help]

PACKAGE BODY: APPS.ARP_DISCOUNTS_API

Source


1 PACKAGE BODY ARP_DISCOUNTS_API AS
2 /* $Header: ARRUDIAB.pls 120.7 2006/06/01 09:39:40 naneja noship $ */
3 
4 /*===========================================================================+
5  | PROCEDURE                                                                 |
6  |    get_discount                                                           |
7  |                                                                           |
8  | DESCRIPTION                                                               |
9  |    Calculate the discount allowed on a payment and the remaining          |
10  |    on the invoice.							     |
11  |                                                                           |
12  | ARGUMENTS  : IN:                                                          |
13  |                 p_ps_id - payment schedule id of the invoice              |
14  |                 p_apply_date - application date of the payment	     |
15  |                 p_in_applied_amount - amount being applied 		     |
16  |                 p_grace_flag - Flag that decides grace days to be applied |
17  |				  in discount calculation or not.	     |
18  |									     |
19  |              IN OUT:                                                      |
20  |									     |
21  |              OUT:                                                         |
22  |		  p_out_discount - discount available on the payment amount  |
23  |		  p_out_remaining_amount - remaining amount on the invoice   |
24  |			after application amount and discounts are taken     |
25  |									     |
26  | MODIFICATION HISTORY 						     |
27  |  01/25/01	R Yeluri	Created 				     |
28  |  09/10/04    J Beckett       Bug 3866488 - corrected the sql to fetch     |
29  |				grace days from cust acct profile if none    |
30  |				exists for site use.			     |
31  +===========================================================================*/
32 
33 PG_DEBUG varchar2(1) := NVL(FND_PROFILE.value('AFLOG_ENABLED'), 'N');
34 /*Bug 5223829 introduced new parameter for iReceivables*/
35 PROCEDURE get_discount (
36 	p_ps_id			IN	ar_payment_schedules.payment_schedule_id%TYPE,
37   	p_apply_date           	IN     	DATE,
38        	p_in_applied_amount    	IN     	NUMBER,
39 	p_grace_days_flag       IN	VARCHAR2,
40         p_out_discount         	OUT NOCOPY    	NUMBER,
41         p_out_rem_amt_rcpt 	OUT NOCOPY    	NUMBER,
42         p_out_rem_amt_inv 	OUT NOCOPY    	NUMBER,
43         P_called_from           IN              VARCHAR2) IS
44 
45 p_ps_rec         ar_payment_schedules%ROWTYPE;
46 p_disc_rec       arp_calculate_discount.discount_record_type;
47 
48 l_grace_days            NUMBER;
49 l_customer_id            NUMBER;
50 l_site_use_id            NUMBER;
51 
52 l_use_max_cash_flag	VARCHAR2(2);
53 l_earned_both_flag	VARCHAR2(2);
54 l_default_amt_app	VARCHAR2(241);
55 l_error_code		NUMBER;
56 l_select_flag		VARCHAR2(1);
57 l_close_invoice_flag 	VARCHAR2(2);
58 l_mode			NUMBER;
59 l_earned_disc_pct 	NUMBER;
60 l_best_disc_pct 	NUMBER;
61 l_out_earned_disc 	NUMBER;
62 l_out_unearned_disc 	NUMBER;
63 l_out_discount_date 	DATE;
64 l_out_amt_to_apply 	NUMBER;
65 l_cash_receipt_id 	NUMBER;
66 l_site_level_profile    BOOLEAN; -- Bug 3866488
67 l_amt_due_rem           NUMBER; /*Bug 5223829*/
68 l_amt_in_dispute        ar_payment_schedules.amount_in_dispute%TYPE; /*Bug 5223829*/
69 
70 BEGIN
71 	IF PG_DEBUG in ('Y', 'C') THEN
72 	   arp_standard.debug( 'arp_discounts_api.get_discount() +');
73 	END IF;
74 
75 	-- Get payment schedule info and populate the payment schedule record
76 	p_ps_rec.payment_schedule_id := p_ps_id;
77 	arp_calculate_discount.get_payment_schedule_info(p_disc_rec, p_ps_rec);
78 
79 	IF PG_DEBUG in ('Y', 'C') THEN
80 	   arp_standard.debug('get_discount: ' ||  'initialized payment schedule record');
81 	END IF;
82 
83      -- Get Customer Id and Site Use Id to obtain any grace days
84      -- available for the Customer.
85      BEGIN
86 	SELECT	customer_id, customer_site_use_id
87 	INTO	l_customer_id, l_site_use_id
88 	FROM	ar_payment_schedules
89 	WHERE	payment_schedule_id = p_ps_id;
90 
91      EXCEPTION
92 		WHEN NO_DATA_FOUND THEN
93 		IF PG_DEBUG in ('Y', 'C') THEN
94 		   arp_standard.debug('get_discount: ' || 'No data found for Customer id');
95 		END IF;
96       END;
97 
98       -- If grace days is allowed from iReceivables, calculate the
99       -- grace days available for the Customer, otherwise grace days is 0
100       /* Bug 3866488 - even though a site use id exists, a customer profile
101       may not be assigned to it, so the cust account profile must be used */
102 	if (p_grace_days_flag = 'Y') then
103            l_site_level_profile := TRUE;
104 	   if l_site_use_id is NOT NULL then
105              BEGIN
106                SELECT  NVL(discount_grace_days, 0)
107                INTO    l_grace_days
108                FROM    hz_customer_profiles
109                WHERE   cust_account_id = l_customer_id
110                AND     site_use_id     = l_site_use_id;
111              EXCEPTION
112                WHEN NO_DATA_FOUND THEN
113                  l_site_level_profile := FALSE;
114 
115                WHEN OTHERS THEN
116                  IF PG_DEBUG in ('Y', 'C') THEN
117                    arp_util.debug('get_discount: ' || 'EXCEPTION: Error selecting discount_grace_days from site level customer profile ');
118                    arp_util.debug('Validate_amount: ' || 'site_use_id  =  ' ||TO_CHAR(l_site_use_id));
119                  END IF;
120                  RAISE;
121              END;
122            END IF;
123 
124 	   IF ( l_site_use_id IS NULL OR NOT l_site_level_profile ) THEN
125                SELECT  NVL(discount_grace_days, 0)
126                INTO    l_grace_days
127                FROM    hz_customer_profiles
128                WHERE   cust_account_id = l_customer_id
129 	       AND     site_use_id IS NULL;
130            end if;
131 
132 	 else
133 		l_grace_days := 0;
134 	 end if;
135 
136 	IF PG_DEBUG in ('Y', 'C') THEN
137 	   arp_standard.debug('get_discount: ' ||  'grace days:'||l_grace_days );
138 	END IF;
139 
140 
141 	-- Initilaize various variables necessary to be passed into
142 	-- calculate discounts routine.
143         l_use_max_cash_flag  := 'Y' ;
144 /*Bug 4288015 Discount should be earned discount */
145         l_earned_both_flag   := 'E' ; /*does B imply both earned and Unearned */
146         l_default_amt_app    := 'PMT' ;
147         l_error_code := '0' ;
148         l_select_flag := 'N' ; -- set to 'N' if select_flag is FALSE
149         l_close_invoice_flag := 'N' ; --is Y if mode=default and l_default_amt_app<>PMT
150 				      --Need to check on this, this needs to be a N
151         l_mode := 1 ; -- default mode
152 
153         l_earned_disc_pct := 0 ;
154         l_best_disc_pct := 0 ;
155         l_out_earned_disc := 0 ;
156         l_out_unearned_disc := 0 ;
157         l_out_discount_date := p_apply_date ;
158         l_out_amt_to_apply := 0 ;
159         l_cash_receipt_id := 0 ;
160 /*Bug 5223829 put the logic to consider for amount in dispute when called from iReceivables*/
161         IF p_called_from ='OIR' THEN
162           l_amt_due_rem  := p_ps_rec.amount_due_remaining - nvl(p_ps_rec.amount_in_dispute,0);
163           l_amt_in_dispute := p_ps_rec.amount_in_dispute;
164         ELSE
165           l_amt_due_rem  := p_ps_rec.amount_due_remaining;
166           l_amt_in_dispute := NULL;
167         END IF;
168 
169 	-- Call the discounts package.
170 	arp_calculate_discount.calculate_discounts(
171             p_in_applied_amount, --input
172             l_grace_days,
173             p_apply_date, --input
174             p_disc_rec.disc_partial_pmt_flag,
175             p_disc_rec.calc_disc_on_lines,
176             l_earned_both_flag,
177             l_use_max_cash_flag,
178             l_default_amt_app,
179             l_earned_disc_pct,
180             l_best_disc_pct,
181             l_out_earned_disc,
182             l_out_unearned_disc,
183             l_out_discount_date,
184             l_out_amt_to_apply,
185             l_close_invoice_flag,
186             p_ps_id, --input
187             p_ps_rec.term_id,
188             p_ps_rec.terms_sequence_number,
189             p_ps_rec.trx_date,
190             p_ps_rec.amount_due_original,
191             l_amt_due_rem,/*Bug 5223829 callled in place of  p_ps_rec.amount_due_remaining*/
192             NVL(p_ps_rec.discount_taken_earned,0),
193             NVL(p_ps_rec.discount_taken_unearned,0),
194             NVL(p_ps_rec.amount_line_items_original,0),
195             p_ps_rec.invoice_currency_code,
196             l_select_flag,
197             l_mode,
198             l_error_code,
199             l_cash_receipt_id,
200             p_called_from,  /*Bug 5223829*/
201             l_amt_in_dispute /*Bug 5223829*/
202    );
203 
204 	IF PG_DEBUG in ('Y', 'C') THEN
205 	   arp_standard.debug('get_discount: ' ||  'earned discount :'|| l_out_earned_disc );
206 	   arp_standard.debug('get_discount: ' ||  'unearned discount :'|| l_out_unearned_disc );
207 	END IF;
208 
209  -- This is the total discount available on the payment schedule
210  -- This program is intended only to give out NOCOPY earned disocunts.
211  -- There will be no unearned discounts, hence even if there are
212  -- unearned discounts, the total disocunt is zero.
213 
214    /* Bug 4460264 - allows for negative discount */
215    p_out_discount := l_out_earned_disc;
216 
217 	IF PG_DEBUG in ('Y', 'C') THEN
218 	   arp_standard.debug('get_discount: ' ||  'Input Amount applied :'|| p_in_applied_amount);
219 	   arp_standard.debug('get_discount: ' ||  'ADR on the Invoice :'||p_ps_rec.amount_due_remaining);
220 	END IF;
221 
222 
223  -- This calculates if the receipt application plus the discount can
224  -- close out NOCOPY the invoice. If is does, is there any receipt amount being
225  -- left as unapplied. If the application plus discount does not close out NOCOPY
226  -- the invoice, what is the amount due remaining on the invoice.
227 
228   if ((p_out_discount+p_in_applied_amount)
229 		>= p_ps_rec.amount_due_remaining) then
230 
231   	p_out_rem_amt_rcpt := (p_out_discount+p_in_applied_amount)
232 					- p_ps_rec.amount_due_remaining;
233 	p_out_rem_amt_inv  := 0;
234   else
235 	p_out_rem_amt_rcpt := 0;
236 	p_out_rem_amt_inv  := p_ps_rec.amount_due_remaining
237 				- (p_out_discount+p_in_applied_amount);
238   end if;
239 
240 	IF PG_DEBUG in ('Y', 'C') THEN
241 	   arp_standard.debug('get_discount: ' ||  'Total discount :'|| p_out_discount );
242 	   arp_standard.debug('get_discount: ' ||  'ADR on the Invoice after discount :'||p_out_rem_amt_inv);
243 	   arp_standard.debug('get_discount: ' ||  'ADR on the Receipt after discount :'||p_out_rem_amt_rcpt);
244 	   arp_standard.debug( 'arp_discounts_api.get_discount() -');
245 	END IF;
246 
247 
248 END get_discount;
249 
250 
251 /*===========================================================================+
252  | PROCEDURE                                                                 |
253  |    get_max_discount                                                       |
254  |                                                                           |
255  | DESCRIPTION                                                               |
256  |    Calculate the maximum allowable discount for a given payment schedule  |
257  |    and the amount needed to close out NOCOPY the invoice. 			     |
258  |    on the invoice.                                                        |
259  |                                                                           |
260  | ARGUMENTS  : IN:                                                          |
261  |                 p_ps_id - payment schedule id of the invoice              |
262  |                 p_apply_date - application date of the payment            |
263  |                 p_grace_days_flag - Allow grace days Yes/No 		     |
264  |                                                                           |
265  |              IN OUT:                                                      |
266  |                                                                           |
267  |              OUT:                                                         |
268  |                p_out_discount - Max discount available on the payment     |
269  |				   schedule				     |
270  |                p_out_amount_applied - amount needed minus the discount    |
271  |				       available needed to close the invoice |
272  |                                                                           |
273  | MODIFICATION HISTORY                                                      |
274  |  01/25/01    R Yeluri        Created                                      |
275  |                                                                           |
276  +===========================================================================*/
277 
278 PROCEDURE get_max_discount (
279         p_ps_id                 IN      ar_payment_schedules.payment_schedule_id%TYPE,
280         p_apply_date            IN      DATE,
281         p_grace_days_flag     	IN      VARCHAR2,
282         p_out_discount          OUT NOCOPY     NUMBER,
283         p_out_applied_amt	OUT NOCOPY     NUMBER) IS
284 
285 p_ps_rec         ar_payment_schedules%ROWTYPE;
286 p_disc_rec       arp_calculate_discount.discount_record_type;
287 
288 p_mode      	NUMBER;
289 l_customer_id	NUMBER;
290 l_site_use_id	NUMBER;
291 l_grace_days	NUMBER;
292 l_discount_date	DATE;
293 
294 BEGIN
295 
296 	IF PG_DEBUG in ('Y', 'C') THEN
297 	   arp_standard.debug( 'arp_discounts_api.get_max_discount() +');
298 	   arp_standard.debug('get_max_discount: ' ||  'Payment schedule Id :'|| p_ps_id);
299 	   arp_standard.debug('get_max_discount: ' ||  'Apply Date :'|| p_apply_date );
300 	   arp_standard.debug('get_max_discount: ' ||  'Allow Grace Days :'|| p_grace_days_flag );
301 	END IF;
302 
303 	p_mode := 1; --default mode
304 
305      -- Get Customer Id and Site Use Id to obtain any grace days
306      -- available for the Customer.
307       BEGIN
308 	SELECT  customer_id, customer_site_use_id
309         INTO    l_customer_id, l_site_use_id
310         FROM    ar_payment_schedules
311         WHERE   payment_schedule_id = p_ps_id;
312 
313 	EXCEPTION
314 	   WHEN NO_DATA_FOUND THEN
315 		IF PG_DEBUG in ('Y', 'C') THEN
316 		   arp_standard.debug('get_max_discount: ' || 'No Customer Data Found');
317 		END IF;
318        END;
319 
320 
321 	-- Grace days
322 	-- If grace days is allowed from iReceivables, calculate the
323       	-- grace days available for the Customer, otherwise grace days is 0
324 
325 	if (p_grace_days_flag = 'Y') then
326 	    if l_site_use_id is NOT NULL then
327                SELECT  NVL(discount_grace_days, 0)
328                INTO    l_grace_days
329                FROM    hz_customer_profiles
330                WHERE   cust_account_id = l_customer_id
331                AND     site_use_id     = l_site_use_id;
332             else
333                SELECT  NVL(discount_grace_days, 0)
334                INTO    l_grace_days
335                FROM    hz_customer_profiles
336                WHERE   cust_account_id = l_customer_id;
337             end if;
338 
339          else
340                 l_grace_days := 0;
341          end if;
342 
343 	IF PG_DEBUG in ('Y', 'C') THEN
344 	   arp_standard.debug('get_max_discount: ' ||  'Grace Days :'|| l_grace_days );
345 	END IF;
346 
347 	-- We need this following set of statements, because the
348 	-- determine_max_discount always calculates max discount
349 	-- while taking into consideration grace days
350 	-- The requirement of iReceivables is that if the grace_days_flag
351 	-- is FALSE, then the max discount should eliminate any
352 	-- grace days available during discount calculation
353        BEGIN
354 	SELECT 	discount_date
355 	INTO 	l_discount_date
356         FROM   	ar_trx_discounts_v
357         WHERE 	payment_schedule_id  = p_ps_id;
358 
359 	EXCEPTION
360 	   WHEN NO_DATA_FOUND THEN
361 		IF PG_DEBUG in ('Y', 'C') THEN
362 		   arp_standard.debug('get_max_discount: ' ||  'error getting discount date');
363 		END IF;
364        END;
365 
366 	IF PG_DEBUG in ('Y', 'C') THEN
367 	   arp_standard.debug('get_max_discount: ' ||  'Discount Date :'|| l_discount_date );
368 	END IF;
369 
370 	-- Populate the payment schedule record.
371 	p_ps_rec.payment_schedule_id := p_ps_id;
372         arp_calculate_discount.get_payment_schedule_info(p_disc_rec, p_ps_rec);
373 	IF PG_DEBUG in ('Y', 'C') THEN
374 	   arp_standard.debug('get_max_discount: ' ||  'Initialized the payment schedule record');
375 	END IF;
376 
377 	if ((p_apply_date - l_grace_days) > l_discount_date) then
378 	   --implies the application date is past the discount date
379 	   --including the grace days, hence no disocunt is available
380 
381 		p_out_discount := 0;
382 	else
383 
384 		--Get Discount Percentages
385 		arp_calculate_discount.get_discount_percentages (p_disc_rec, p_ps_rec);
386 		IF PG_DEBUG in ('Y', 'C') THEN
387 		   arp_standard.debug('get_max_discount: ' ||  'Calculated Discount percentages');
388 		END IF;
389 
390     		-- Correct percentages for lines-only(ardline) discount if necessary.
391     		IF p_disc_rec.calc_disc_on_lines <> 'I' AND
392     			p_disc_rec.calc_disc_on_lines <> 'N' THEN
393     		   arp_calculate_discount.correct_lines_only_discounts ( p_disc_rec, p_ps_rec );
394     		END IF;
395     		--
396 
397     		-- If no discount percentages, set discounts to zero.
398     		IF ( p_disc_rec.best_disc_pct = 0 ) THEN
399         		p_out_discount := 0 ;
400         		p_disc_rec.earned_disc_pct := 0;
401     		END IF;
402 
403 		--Calculate max discount available
404 		IF PG_DEBUG in ('Y', 'C') THEN
405 		   arp_standard.debug('get_max_discount: ' ||  'Calling MAX discount routine() +');
406 		END IF;
407 		arp_calculate_discount.determine_max_allowed_disc
408 					( p_mode, p_disc_rec, p_ps_rec );
409 
410 
411 		p_out_discount := nvl(p_disc_rec.max_disc,0);
412 
413 
414 	end if;
415 
416 	IF PG_DEBUG in ('Y', 'C') THEN
417 	   arp_standard.debug('get_max_discount: ' ||  'Maximum Available Discount :'|| p_out_discount);
418 	END IF;
419 
420 	if (p_out_discount > 0) then
421 		p_out_applied_amt := p_ps_rec.amount_due_remaining - p_out_discount;
422 	else
423 		p_out_applied_amt := p_ps_rec.amount_due_remaining;
424 	end if;
425 
426 	IF PG_DEBUG in ('Y', 'C') THEN
427 	   arp_standard.debug('get_max_discount: ' ||  'Amount Needed to Close the Invoice :'|| p_out_applied_amt);
428 	   arp_standard.debug( 'arp_discounts_api.get_max_discount() -');
429 	END IF;
430 
431 END get_max_discount;
432 
433 END ARP_DISCOUNTS_API;