DBA Data[Home] [Help]

PACKAGE BODY: APPS.AP_WEB_AMOUNT_UTIL

Source


1 PACKAGE BODY ap_web_amount_util AS
2 /* $Header: apwamtub.pls 120.13 2011/08/22 11:23:54 rveliche ship $ */
3 
4   /* -------------------------------------------------------------------
5   -- Function to get user_id for an employee.
6   -- Parameters:
7   --     IN  p_employee_id
8   -- Return Value:
9   --     user_id (from fnd_user) or NULL if no user exists for
10   --     that employee_id
11   --     Note: this will return the first user_id that has an AP SSWA
12   --     responsibility, since that is the most likely useful user_id.
13   --     In other words, this function is NOT a generic employee_id->user_id
14   --     converter!
15   -- ---------------------------------------------------------------- */
16 
17   function get_user_id(p_employee_id IN NUMBER) RETURN NUMBER IS
18     l_user_id NUMBER;
19   begin
20     begin
21      select fu.user_id
22       into l_user_id
23       from fnd_user fu
24       where fu.employee_id = p_employee_id
25       and sysdate >= fu.start_date
26       and sysdate <= nvl(fu.end_date, sysdate)
27       and rownum = 1;
28 
29     exception
30       when others then
31        l_user_id := NULL;
32     end;
33 
34     return l_user_id;
35 
36   end get_user_id;
37 
38 
39   /* -------------------------------------------------------------------
40   -- Function to round an amount based on a currency code
41   -- Parameters:
42   --     IN  p_amount           amount to be rounded
43   --     IN  p_curr_code        currency code of amount
44   -- Return Value:
45   --     rounded amount
46   -- ---------------------------------------------------------------- */
47 
48   function round_amount(
49                  p_amount IN NUMBER,
50                  p_curr_code IN VARCHAR2) RETURN NUMBER IS
51     l_value number;
52   begin
53 
54 --    arp_standard.debug('rounding amount ' || p_amount || ' for curr ' || p_curr_code);
55 
56     select round(p_amount, fc.precision)
57     into l_value
58     from fnd_currencies_vl fc
59     where currency_code = p_curr_code;
60 
61     return l_value;
62   end;
63 
64 
65   /* -------------------------------------------------------------------
66   -- Function to derive the OIE responsibility for a given user.
67   -- Note: We have to make certain assumptions:
68   --   1. a self-service responsibility for product AP is an OIE
69   --      responsibility.  This isn't necessarily true, but it's
70   --      quite unlikely that an internal approver has iInvoicing
71   --      access (another type of AP Web Responsibility).  In the
72   --      future this would have to be revisited as more and more
73   --      products migrate to web UI.
74   --   2. a user could have multiple OIE responsibilities (e.g.,
75   --      "OIE with Projects" and "OIE without Projects".  We take
76   --      the first one.  Since we're using the responsibility to
77   --      derive the ORG and thus the functional currency code, it
78   --      should in most cases make no difference.
79   -- ---------------------------------------------------------------- */
80 
81   function get_oie_responsibility(p_user_id IN NUMBER,
82                                   p_responsibility_id OUT NOCOPY NUMBER) RETURN VARCHAR2 IS
83 
84    l_menu_id NUMBER;
85    l_responsibility_id NUMBER;
86   begin
87 
88     begin
89       select menu_id, responsibility_id
90       into l_menu_id, l_responsibility_id
91       from (
92          select fr.menu_id, fr.responsibility_id
93          from fnd_responsibility fr,
94          fnd_user_resp_groups furg
95          where fr.application_id = 200
96          and fr.version = 'W'
97          and furg.user_id = p_user_id
98          and furg.responsibility_id = fr.responsibility_id
99          order by furg.start_date desc
100       )
101       where rownum=1;
102 
103       p_responsibility_id := l_responsibility_id;
104       return 'Y';
105 
106     exception
107       when others then
108        p_responsibility_id := NULL;
109        return 'N';
110     end;
111 
112   end;
113 
114 
115   /* -------------------------------------------------------------------
116   -- Function to get the ORG ID for a given user and responsibility.
117   -- This is based on a profile
118   -- ---------------------------------------------------------------- */
119 
120 
121   function get_oie_org_id(p_userid IN NUMBER,
122                           p_oie_resp_id IN NUMBER,
123                           p_org_id      OUT NOCOPY NUMBER) RETURN VARCHAR2 IS
124 
125    l_defined BOOLEAN;
126    l_value   VARCHAR2(240);
127   begin
128 
129     begin
130 
131       fnd_profile.get_specific(NAME_Z => 'ORG_ID',
132                              USER_ID_Z => p_userid,
133                              RESPONSIBILITY_ID_Z => p_oie_resp_id,
134 			     APPLICATION_ID_Z => 200,  -- SQL*AP product id
135                              VAL_Z => l_value,
136                              DEFINED_Z => l_defined);
137 
138       exception
139         when others then
140           l_defined := FALSE;
141     end;
142 
143     if (l_defined) then
144       p_org_id := to_number(l_value);
145       return 'Y';
146     else
147       p_org_id := NULL;
148       return 'N';
149     end if;
150 
151   end;
152 
153 
154   /* -------------------------------------------------------------------
155   -- Function to get the func currency, the set of books id, and the
156   -- default exchange rate type for a given org from ap_system_parameters
157   -- ---------------------------------------------------------------- */
158 
159   function get_ap_setup_data(p_org_id IN NUMBER,
160                              p_func_curr_code OUT NOCOPY VARCHAR2,
161                              p_sob_id OUT NOCOPY NUMBER,
162                              p_default_exchange_rate_type OUT NOCOPY VARCHAR2) RETURN VARCHAR2 IS
163     l_curr_code VARCHAR2(30);
164     l_sob_id NUMBER;
165     l_default_exchange_rate_type VARCHAR2(30);
166   begin
167 
168     begin
169       select base_currency_code, asp.set_of_books_id, asp.default_exchange_rate_type
170       into   l_curr_code, l_sob_id, l_default_exchange_rate_type
171       from  ap_system_parameters_all asp
172       where asp.org_id = p_org_id;
173 
174       p_func_curr_code := l_curr_code;
175       p_sob_id := l_sob_id;
176       p_default_exchange_rate_type := l_default_exchange_rate_type;
177       return 'Y';
178 
179     exception
180       when others then
181         p_func_curr_code := NULL;
182         p_sob_id := NULL;
183         p_default_exchange_rate_type := NULL;
184         return 'N';
185     end;
186 
187   end;
188 
189 
190   /* -------------------------------------------------------------------
191   -- Bug 4020295
192   -- Function to get the exchange rate for a given from Currency code,
193   -- exchange rate type, pair of currencies and date.
194   -- This is essentially just a cover on top of a GL API.  It looks
195   -- back into the past for up to 60 days if the exchange rate isn't
196   -- defined for the requested date.
197   -- ---------------------------------------------------------------- */
198 
199   function get_exchange_rate(p_from_curr_code IN VARCHAR2,
200                              p_to_curr_code   IN VARCHAR2,
201                              p_date           IN DATE,
202                              p_exchange_rate_type IN VARCHAR2,
203                              p_exchange_rate  OUT NOCOPY NUMBER) RETURN VARCHAR2 IS
204     l_rate NUMBER;
205   begin
206 
207     l_rate := gl_currency_api.get_closest_rate_sql(
208                     x_from_currency   => p_from_curr_code,
209                     x_to_currency     => p_to_curr_code,
210                     x_conversion_date => p_date,
211                     x_conversion_type => p_exchange_rate_type,
212                     x_max_roll_days   => 60);
213 
214     if (l_rate < 0) then
215       p_exchange_rate := NULL;
216       return 'N';
217     else
218       p_exchange_rate := l_rate;
219       return 'Y';
220     end if;
221 
222   end;
223 
224 
225   /* -------------------------------------------------------------------
226   -- Function to get the exchange rate for a given set of books,
227   -- exchange rate type, pair of currencies and date.
228   -- This is essentially just a cover on top of a GL API.  It looks
229   -- back into the past for up to 60 days if the exchange rate isn't
230   -- defined for the requested date.
231   -- ---------------------------------------------------------------- */
232 
233   function get_exchange_rate(p_sob_id         IN NUMBER,
234                              p_func_curr_code IN VARCHAR2,
235                              p_currency_code  IN VARCHAR2,
236                              p_date           IN DATE,
237                              p_exchange_rate_type IN VARCHAR2,
238                              p_exchange_rate  OUT NOCOPY NUMBER) RETURN VARCHAR2 IS
239     l_rate NUMBER;
240   begin
241 
242     l_rate := gl_currency_api.get_closest_rate_sql(
243                     x_set_of_books_id => p_sob_id,
244                     x_from_currency =>    p_currency_code,
245                     x_conversion_date => p_date,
246                     x_conversion_type => p_exchange_rate_type,
247                     x_max_roll_days   => 60);
248 
249     if (l_rate < 0) then
250       p_exchange_rate := NULL;
251       return 'N';
252     else
253       p_exchange_rate := l_rate;
254       return 'Y';
255     end if;
256 
257   end;
258 
259  /* -------------------------------------------------------------------
260   -- Public procedure to get a meaningful exchange rate for a given
261   -- user, date, and currency code.
262   -- ---------------------------------------------------------------- */
263 
264   procedure get_meaningful_rate(
265                p_userid        IN NUMBER,
266                p_date          IN DATE,
267                p_currency_code IN VARCHAR2,
268                p_success_flag       OUT NOCOPY VARCHAR2,
269                p_conv_date          OUT NOCOPY DATE,
270                p_conv_rate          OUT NOCOPY NUMBER,
271                p_conv_currency_code IN OUT NOCOPY VARCHAR2) IS
272 
273     l_success_flag VARCHAR2(1);
274 
275 
276     l_oie_resp_id NUMBER;
277     l_org_id      NUMBER;
278     l_func_curr_code VARCHAR2(30);
279     l_sob_id      NUMBER;
280     l_exchange_rate_type VARCHAR2(30);
281     l_exchange_rate NUMBER;
282     l_pref_curr_code VARCHAR2(30);
283     l_employee_id	NUMBER;
284 
285   begin
286 
287     -- Bug 4020295
288     -- Get the preferred currency code from profile for this user if set
289     --
290 
291 --    l_pref_curr_code := get_preferred_currency_code( p_user_id => p_userid );
292     l_pref_curr_code := p_conv_currency_code;
293 
294     if ( l_pref_curr_code is not null ) then
295 
296       --
297       -- Get the other information from the employee's HR information
298       --
299 
300       begin
301 
302 	    select asp.default_exchange_rate_type
303 	    into  l_exchange_rate_type
304 	    from per_employees_x pex,
305 		 ap_system_parameters_all asp,
306 		 fnd_user fu
307 	    where
308 		pex.set_of_books_id = asp.set_of_books_id  and
309 		fu.employee_id = pex.employee_id and
310 		fu.user_id = p_userid and
311 		rownum = 1;
312       exception
313       when others then
314 	p_success_flag := 'N';
315 	return;
316       end;
317 
318       --
319       -- Get the conversion rate for this preferred currency code
320       --
321 
322     l_success_flag := get_exchange_rate(
323 				p_from_curr_code     => p_currency_code,
324 				p_to_curr_code       => l_pref_curr_code,
325                                 p_date               => p_date,
326                                 p_exchange_rate_type => l_exchange_rate_type,
327                                 p_exchange_rate      => l_exchange_rate);
328 
329     if (l_success_flag = 'N') then
330 
331       p_success_flag := 'N';
332       return;
333     else
334       p_conv_rate := l_exchange_rate;
335       p_conv_currency_code := l_pref_curr_code;
336       p_success_flag := 'Y';
337     end if;
338 
339   else
340 
341 /*
342 --    arp_standard.enable_file_debug('/sqlcom/out/aroa55n','osteinme_oie');
343 
344 --    arp_standard.debug('get_meaningful_value()+');
345 
346     l_success_flag := get_oie_responsibility(p_userid, l_oie_resp_id);
347 
348 --    arp_standard.debug('resp_id = ' || to_char(l_oie_resp_id));
349 --    arp_standard.debug('success = ' || l_success_flag);
350 
351     if (l_success_flag = 'N') then
352       p_success_flag := 'N';
353       return;
354     end if;
355 
356     l_success_flag := get_oie_org_id(p_userid, l_oie_resp_id, l_org_id);
357 
358 --    arp_standard.debug('org_id = ' || to_char(l_org_id));
359 --    arp_standard.debug('success = ' || l_success_flag);
360 */
361     BEGIN
362 	IF NOT (AP_WEB_DB_HR_INT_PKG.GetEmpIdForUser(p_userid, l_employee_id)) THEN
363 		p_success_flag := 'N';
364 		return;
365 	END IF;
366 	 SELECT set_of_books_id
367 	   INTO l_sob_id
368 	   FROM
369 	  (SELECT set_of_books_id
370 	     FROM per_employees_x emp
371 	    WHERE employee_id = l_employee_id
372 	  AND NOT AP_WEB_DB_HR_INT_PKG.isPersonCwk(emp.employee_id)='Y'
373 
374 	UNION ALL
375 
376 	   SELECT set_of_books_id
377 	     FROM per_cont_workers_current_x emp
378 	    WHERE person_id = l_employee_id
379 	  );
380         IF (l_sob_id IS NOT NULL) THEN
381 		SELECT currency_code INTO l_func_curr_code FROM gl_sets_of_books WHERE set_of_books_id=l_sob_id;
382 	END IF;
383         IF (l_sob_id IS NOT NULL AND l_func_curr_code IS NOT NULL) THEN
384 		SELECT default_exchange_rate_type
385 		   INTO l_exchange_rate_type
386 		   FROM ap_system_parameters_all
387 		 WHERE set_of_books_id = l_sob_id
388 		 AND rownum= 1;
389         END IF;
390       EXCEPTION
391 	WHEN OTHERS THEN
392 		l_success_flag := 'N';
393     END;
394 
395    /* if (l_success_flag = 'N') then
396       p_success_flag := 'N';
397       return;
398     end if;*/
399 
400     IF (l_sob_id IS NULL OR l_func_curr_code IS NULL OR l_exchange_rate_type IS NULL) THEN
401 	IF NOT (AP_WEB_DB_HR_INT_PKG.GetEmpOrgId(l_employee_id, l_org_id)) THEN
402 	  p_success_flag := 'N';
403 	  return;
404         END IF;
405 
406       l_success_flag := get_ap_setup_data(l_org_id, l_func_curr_code, l_sob_id, l_exchange_rate_type);
407     END IF;
408 
409 --    arp_standard.debug('sob_id = ' || to_char(l_sob_id));
410 --    arp_standard.debug('func curr = ' || l_func_curr_code);
411 --    arp_standard.debug('def exch type = ' || l_exchange_rate_type);
412 
413 --    arp_standard.debug('success = ' || l_success_flag);
414 
415 
416     if (l_success_flag = 'N') then
417       p_success_flag := 'N';
418       return;
419     end if;
420 
421 
422     -- no point in doing conversion if reimbursement amount is already
423     -- in desired currency.
424 
425     if (l_func_curr_code = p_currency_code) then
426       p_success_flag := 'N';
427       return;
428     end if;
429 
430 
431     l_success_flag := get_exchange_rate(l_sob_id,
432 				        l_func_curr_code,
433                                         p_currency_code,
434                                         p_date,
435                                         l_exchange_rate_type,
436                                         l_exchange_rate);
437 
438 
439 --    arp_standard.debug('rate = ' || to_char(l_exchange_rate));
440 --    arp_standard.debug('success = ' || l_success_flag);
441 
442     if (l_success_flag = 'N') then
443       p_success_flag := 'N';
444       return;
445     else
446       p_conv_rate := l_exchange_rate;
447       p_conv_currency_code := l_func_curr_code;
448       p_success_flag := 'Y';
449     end if;
450 
451   end if; -- end of if ( l_pref_curr_code is not null )
452 
453   end get_meaningful_rate;
454 
455 
456  /* -------------------------------------------------------------------
457   -- Public procedure to get a meaningful converted amount for a given
458   -- user, date, and currency code.
459   -- ---------------------------------------------------------------- */
460 
461  procedure get_meaningful_amount(
462                p_userid        IN NUMBER,
463                p_amount        IN NUMBER,
464                p_date          IN DATE,
465                p_currency_code IN VARCHAR2,
466                p_success_flag       OUT NOCOPY VARCHAR2,    -- Y/N
467                p_conv_amount        OUT NOCOPY NUMBER,
468                p_conv_currency_code IN OUT NOCOPY VARCHAR2) IS
469 
470    l_conv_rate NUMBER;
471    l_conv_date DATE;
472    l_success_flag VARCHAR2(1);
473 
474  begin
475 
476    get_meaningful_rate(
477 	p_userid,
478 	p_date,
479         p_currency_code,
480         l_success_flag,
481         l_conv_date,
482         l_conv_rate,
483         p_conv_currency_code);
484 
485    if (l_success_flag = 'Y') then
486      p_conv_amount := round_amount(p_amount * l_conv_rate, p_conv_currency_code);
487      p_success_flag := 'Y';
488    else
489      p_success_flag := 'N';
490      p_conv_amount := NULL;
491    end if;
492 
493  end;
494 
495 
496   /* -------------------------------------------------------------------
497   -- Public function to get a string returning a translated string of
498   -- format "Estimated Reimbursement Amount in <curr>: <amount>
499   -- where <amount> is a converted amount in currency <curr>.
500   -- ---------------------------------------------------------------- */
501 
502  function get_meaningful_amount_msg(
503               p_userid        IN NUMBER,
504               p_amount        IN NUMBER,
505               p_date          IN DATE,
506               p_currency_code IN VARCHAR2,
507               p_out_currency_code IN VARCHAR2) RETURN VARCHAR2 IS
508 
509    l_msg VARCHAR2(240);
510    l_success_flag VARCHAR2(1);
511    l_conv_amount NUMBER;
512    l_conv_amount_formatted VARCHAR2(30);
513    l_conv_curr_code VARCHAR2(30);
514 
515   begin
516     l_conv_curr_code := p_out_currency_code;
517 
518     begin
519       get_meaningful_amount(
520               p_userid,
521               p_amount,
522               p_date,
523               p_currency_code,
524               l_success_flag,
525               l_conv_amount,
526               l_conv_curr_code);
527 
528       if l_success_flag = 'N' then
529         return null;
530       else
531         l_conv_amount_formatted := to_char(l_conv_amount,
532                                  fnd_currency.get_format_mask(l_conv_curr_code, 20));
533 
534         fnd_message.set_name('SQLAP','OIE_MEANINGFUL_AMOUNT_PROMPT');
535         fnd_message.set_token('CURRENCY', l_conv_curr_code);
536         fnd_message.set_token('AMOUNT', l_conv_amount_formatted);
537         l_msg := fnd_message.get;
538         return l_msg;
539       end if;
540 
541       exception
542         when others then
543           return NULL;
544       end;
545 
546  end get_meaningful_amount_msg;
547 
548   /* -------------------------------------------------------------------
549   -- Public function to get a string returning a translated string of
550   -- format "Estimated Reimbursement Amount in <curr>: <amount>
551   -- where <amount> is a converted amount in currency <curr>.
552   -- Function altered to fetch the functional currency
553   -- ---------------------------------------------------------------- */
554 
555  function get_meaningful_amount_msg_emp(
556               p_employee_id   IN NUMBER,
557               p_amount        IN NUMBER,
558               p_date          IN DATE,
559               p_currency_code IN VARCHAR2,
560               p_out_currency_code IN VARCHAR2) RETURN VARCHAR2 IS
561    l_user_id NUMBER;
562    l_org_id  VARCHAR2(200);
563    l_defined BOOLEAN;
564    l_func_curr_code VARCHAR2(30);
565    l_sob_id      NUMBER;
566    l_exchange_rate_type VARCHAR2(30);
567    l_success_flag varchar2(1);
568 
569  begin
570 
571    -- Bug 5436992 - Do not show any message if the currencies are the same
572    if ( (p_out_currency_code IS NOT NULL) AND ( p_out_currency_code = p_currency_code) )
573    THEN
574      return null;
575    END IF;
576 
577    l_user_id := get_user_id(p_employee_id);
578    l_func_curr_code := p_out_currency_code;
579    /* The following code is for future use where current resp is also checked
580    if(l_user_id is not null and p_out_currency_code is null) then
581 	fnd_profile.get_specific(NAME_Z => 'ORG_ID',
582                              USER_ID_Z => null,
583                              RESPONSIBILITY_ID_Z => fnd_global.resp_id(),
584 			     APPLICATION_ID_Z => null,  -- SQL*AP product id
585                              VAL_Z => l_org_id,
586                              DEFINED_Z => l_defined);
587         if (l_org_id is not null) then
588 		l_success_flag := get_ap_setup_data(to_number(l_org_id), l_func_curr_code, l_sob_id, l_exchange_rate_type);
589         end if;
590    end if;*/
591 
592    if l_user_id is not null then
593      return get_meaningful_amount_msg(
594              l_user_id,
595              p_amount,
596              p_date,
597              p_currency_code,
598 	     p_out_currency_code);
599    else
600      return null;
601    end if;
602 
603  end get_meaningful_amount_msg_emp;
604 
605 
606  procedure get_meaningful_amount_emp(
607                p_employee_id        IN NUMBER,
608                p_amount             IN NUMBER,
609                p_date               IN DATE,
610                p_currency_code      IN VARCHAR2,
611                p_success_flag       OUT NOCOPY VARCHAR2,
612                p_conv_amount        OUT NOCOPY NUMBER,
613                p_conv_currency_code OUT NOCOPY VARCHAR2) IS
614    l_user_id NUMBER;
615  begin
616 
617    l_user_id := get_user_id(p_employee_id);
618 
619    if l_user_id is not null then
620       get_meaningful_amount(
621              l_user_id,
622              p_amount,
623              p_date,
624              p_currency_code,
625              p_success_flag,
626              p_conv_amount,
627              p_conv_currency_code);
628    else
629      p_success_flag := 'N';
630    end if;
631 
632  end get_meaningful_amount_emp;
633 
634 end ap_web_amount_util;