DBA Data[Home] [Help]

PACKAGE BODY: APPS.PA_INTEGRATION

Source


1 PACKAGE BODY pa_integration AS
2 --$Header: PAXPINTB.pls 120.7 2010/05/13 10:15:55 lamalviy ship $
3 
4 l_invoice_id    NUMBER;
5 l_invoice_status Varchar2(30);
6 l_status_type    Varchar2(30);
7 
8 G_PrevPeriodName pa_cost_distribution_lines_all.gl_period_name%TYPE;
9 G_PrevPdStDate   DATE;
10 G_PrevPdEdDate   DATE;
11 G_PrevSOBId      NUMBER;
12 
13 -- FUNCTION get_period_name /*2835063*/
14     FUNCTION get_period_name RETURN  pa_cost_distribution_lines_all.pa_period_name%TYPE is
15     BEGIN
16          /* Please note that this function should be used only after ensuring that
17 	    get_raw_cdl_pa_date() is called, so that the returned variable's value has a
18 	    non-NULL value */
19       return  g_prvdr_pa_period_name;
20     end get_period_name;
21 
22 FUNCTION pending_vi_adjustments_exists( P_invoice_id IN NUMBER )
23                                         RETURN varchar2 IS
24 --
25 -- CDL's that are not yet transfered to AP
26 --
27 CURSOR pending_transfer IS
28 SELECT 'AP_PROJ_TASK_EXIST_PA'
29 FROM
30     PA_COST_DISTRIBUTION_LINES  CDL,
31     PA_EXPENDITURE_ITEMS   EI
32   WHERE
33    EI.EXPENDITURE_ITEM_ID = CDL.EXPENDITURE_ITEM_ID
34   AND CDL.TRANSFER_STATUS_CODE IN ('P','R','X')
35   AND EI.SYSTEM_LINKAGE_FUNCTION in ( 'VI','ER')
36   AND CDL.LINE_TYPE  = 'R'
37   AND CDL.system_reference2 = to_char(P_invoice_id);
38 --
39 -- Expenditure items that are
40 -- split/transfered but not cost distributed.
41 --
42 CURSOR pending_ei IS
43 SELECT 'AP_SPLIT_EXIST_PA'
44 FROM
45     PA_COST_DISTRIBUTION_LINES  CDL
46   WHERE
47       CDL.system_reference2 = to_char(P_invoice_id)
48   AND CDL.transfer_status_code||'' IN ('V','A')
49   AND CDL.line_type = 'R'
50   AND EXISTS
51     ( SELECT ' There are Splits/Transfers on EI'
52         FROM PA_EXPENDITURE_ITEMS   EI
53        WHERE EI.SYSTEM_LINKAGE_FUNCTION in ( 'VI', 'ER' )
54          AND EI.TRANSFERRED_FROM_EXP_ITEM_ID = CDL.EXPENDITURE_ITEM_ID
55          AND EI.ADJUSTED_EXPENDITURE_ITEM_ID IS NULL
56          AND EI.COST_DISTRIBUTED_FLAG||'' = 'N'
57      );
58 --
59 -- Expenditure items that are marked for recalc
60 --
61 
62 CURSOR pending_recalc IS
63 SELECT 'AP_RECALC_COST_PA'
64 FROM
65     PA_COST_DISTRIBUTION_LINES CDL
66 WHERE
67     CDL.system_reference2 = to_char(P_invoice_id)
68   AND CDL.transfer_status_code||'' IN ( 'V', 'A' )
69   AND CDL.line_type = 'R'
70   AND EXISTS
71     ( SELECT 'Marked for recalc'
72         FROM PA_EXPENDITURE_ITEMS EI
73        WHERE EI.SYSTEM_LINKAGE_FUNCTION in ( 'VI','ER')
74          AND EI.EXPENDITURE_ITEM_ID = CDL.EXPENDITURE_ITEM_ID
75          AND EI.COST_DISTRIBUTED_FLAG = 'N'
76      );
77 --
78 -- Checking for reversals
79 --
80 
81 CURSOR pending_reversed IS
82 SELECT 'AP_ADJ_EXIST_PA'
83 FROM
84     PA_COST_DISTRIBUTION_LINES  CDL
85   WHERE
86       CDL.system_reference2 = to_char(P_invoice_id)
87   AND CDL.transfer_status_code ||'' IN ('V','A')
88   AND CDL.line_type = 'R'
89   AND EXISTS
90     ( SELECT ' Reversed EI '
91         FROM PA_EXPENDITURE_ITEMS   EI
92        WHERE EI.SYSTEM_LINKAGE_FUNCTION in ( 'VI','ER')
93          AND EI.ADJUSTED_EXPENDITURE_ITEM_ID = CDL.EXPENDITURE_ITEM_ID
94          AND EI.COST_DISTRIBUTED_FLAG||'' = 'N'
95      );
96 
97 v_error_code  varchar2(30) := 'Y';
98 
99 BEGIN
100   OPEN pending_transfer;
101   FETCH pending_transfer INTO v_error_code;
102   IF ( v_error_code <> 'Y' ) THEN
103     CLOSE pending_transfer;
104     RETURN v_error_code;
105   END IF;
106   CLOSE pending_transfer;                        -- Added for Bug#5381711
107 
108   OPEN pending_ei;
109   FETCH pending_ei INTO v_error_code;
110   IF ( v_error_code <> 'Y' ) THEN
111     CLOSE pending_ei;
112     RETURN v_error_code;
113   END IF;
114   CLOSE pending_ei;                              -- Added for Bug#5381711
115 
116   OPEN pending_recalc;
117   FETCH pending_recalc INTO v_error_code;
118   IF ( v_error_code <> 'Y' ) THEN
119     CLOSE pending_recalc;
120     RETURN v_error_code;
121   END IF;
122   CLOSE pending_recalc;                          -- Added for Bug#5381711
123 
124   OPEN pending_reversed;
125   FETCH pending_reversed INTO v_error_code;
126   IF ( v_error_code <> 'Y' ) THEN
127     CLOSE pending_reversed;                      -- Modified for Bug#5381711
128     RETURN v_error_code;
129   END IF;
130   CLOSE pending_reversed;                        -- Added for Bug#5381711
131 
132 -- If you can get here, then there are no pending adjustments in PA
133 --
134   v_error_code := 'N';
135   RETURN v_error_code;
136 
137 EXCEPTION WHEN others THEN
138   RAISE;
139 END pending_vi_adjustments_exists;
140 
141 FUNCTION check_ap_invoices(p_invoice_id IN NUMBER,
142                            p_status_type IN VARCHAR2) RETURN VARCHAR2 IS
143 v_error_code      VARCHAR2(30) :='';
144 v_cancelled_date  DATE;
145 v_cancelled_by    NUMBER;
146 BEGIN
147    -- v_error_code := AP_PA_API_PKG.get_invoice_status(p_invoice_id,p_status_type); /* bug#5010877 */
148 
149    -- Added this section to replace the above function call.
150     IF p_status_type = 'ADJUSTMENTS' THEN
151 
152 	SELECT CANCELLED_DATE,
153 	       CANCELLED_BY
154 	INTO   v_cancelled_date,
155 	       v_cancelled_by
156 	FROM   ap_invoices_all
157 	WHERE  invoice_id = p_invoice_id;
158 
159       	If    (v_cancelled_date IS NOT NULL AND v_cancelled_by IS NOT NULL) THEN
160               v_error_code := 'PA_INV_CANCELLED';
161         else
162               v_error_code := 'N';
163         End if;
164 
165     END IF;
166 
167    RETURN(v_error_code);
168 
169 EXCEPTION WHEN OTHERS THEN
170   RAISE;
171 END check_ap_invoices;
172 
173 PROCEDURE init_ap_invoices IS
174 BEGIN
175    l_invoice_id := -1;
176    l_invoice_status := '';
177    l_status_type :='';
178 END init_ap_invoices;
179 
180 FUNCTION ap_invoice_status( p_invoice_id IN NUMBER,
181                             p_status_type In VARCHAR2) RETURN VARCHAR2 IS
182 pa_check_status VARCHAR2(30);  /* For Bug 1969501 */
183 BEGIN
184    IF (( l_invoice_id = p_invoice_id ) and (l_status_type = p_status_type)) THEN
185       RETURN l_invoice_status;
186    ELSE
187       l_invoice_id := p_invoice_id;
188       l_status_type := p_status_type;
189 
190       pa_check_status := pa_integration.check_ap_invoices(p_invoice_id,p_status_type);
191 
192       IF pa_check_status = 'N' THEN
193          l_invoice_status := 'N';
194       ELSIF pa_check_status = 'PA_INV_CANCELLED' THEN
195          l_invoice_status := 'C';
196       ELSE
197          l_invoice_status := 'Y';
198       END IF;
199       RETURN l_invoice_status;
200    END IF;
201 END ap_invoice_status;
202 
203 ---------------------------------------------------------------------------
204 --This Procedure refresh_pa_cache() is used by get_raw_cdl_date and get_raw_cdl_recvr_pa_date
205 --for caching purposes. Global variables defined in PAXPINTS.pls are used for caching.
206 ---------------------------------------------------------------------------
207 
208 PROCEDURE refresh_pa_cache ( p_org_id   IN NUMBER ,
209                              p_expenditure_item_date  IN DATE ,
210                              p_accounting_date IN DATE,
211                              p_caller_flag     IN VARCHAR2
212                            )
213 IS
214 -- local variables
215   l_earliest_start_date  DATE ;
216   l_earliest_end_date  DATE ;
217   l_earliest_period_name pa_cost_distribution_lines_all.pa_period_name%TYPE;
218   l_pa_date           DATE ;
219   l_start_date        DATE ;               -- start date for the l_pa_date.
220   l_end_date          DATE ;               -- end date for the l_pa_date ( equals l_pa_date ).
221   l_period_name pa_cost_distribution_lines_all.pa_period_name%TYPE;
222 
223   l_prof_new_gldate_derivation VARCHAR2(1) := 'N' ;
224 
225 BEGIN
226   /* Changed from value_specific to value for bug 5472333 */
227   l_prof_new_gldate_derivation := NVL(fnd_profile.value('PA_EN_NEW_GLDATE_DERIVATION'), 'N') ;
228 
229   IF( l_prof_new_gldate_derivation = 'Y' )
230   THEN
231 /*
232  *SQL to select the earliest open PA_DATE.
233  *Select the earliest open date ONLY if the global earliest date is NOT yet populated.
234  *Because , earliest pa_date will remain the same for a run.
235  */
236 
237  IF ( p_caller_flag = 'R' AND g_r_earliest_pa_start_date IS NULL ) OR
238     ( p_caller_flag = 'P' AND g_p_earliest_pa_start_date IS NULL ) THEN
239 
240 -- Note : This SQL uses the p_accounting_date filter criteria.
241 
242       SELECT pap1.start_date
243             ,pap1.end_date
244             ,pap1.period_name
245         INTO l_earliest_start_date
246             ,l_earliest_end_date
247             ,l_earliest_period_name
248         FROM pa_periods_all pap1
249        WHERE pap1.status IN ('O','F')
250          AND pap1.org_id = p_org_id
251          AND pap1.start_date = ( SELECT MIN(pap.start_date)
252                                    FROM pa_periods_all pap
253                                   WHERE status IN ('O','F')
254                                     AND org_id = p_org_id
255                                );
256  END IF ;
257 
258 -- SQL to select the PA_DATE for the current EI.
259 /* Code fix for Bug 1657231...
260    Added Begin... Exception...END to Handle No_Data_Found Exception */
261 
262 /*
263  * EPP.
264  * Modified the following sql to get p_accounting_date as l_pa_date
265  * rather then end_date.
266  */
267 BEGIN  /* Added for Bug 1657231 */
268       SELECT pap.start_date
269             ,pap.end_date
270             ,p_accounting_date
271             ,pap.period_name
272         INTO l_start_date
273             ,l_end_date
274             ,l_pa_date
275             ,l_period_name
276         FROM pa_periods_all pap
277        WHERE pap.status in ('O','F')
278          AND pap.end_date >= TRUNC(p_expenditure_item_date)
279          AND p_accounting_date BETWEEN pap.start_date and pap.end_date
280          AND org_id = p_org_id ;
281 
282 EXCEPTION
283    WHEN NO_DATA_FOUND THEN
284    l_pa_date := NULL;
285    l_period_name := NULL;
286 END; /* Added for Bug 1657231 */
287 
288 /*If the l_pa_date obtained is NULL, try to find a pa_date without the accounting-date
289  *check. This approach was used even previously.
290  *This SQL will FAIL - if there are more than one row in pa_periods_all - with the same end_date.
291  */
292 
293       IF ( l_pa_date IS NULL )
294       THEN
295         SELECT pap1.start_date
296               ,pap1.end_date
297               ,pap1.start_date
298               ,pap1.period_name
299           INTO l_start_date
300               ,l_end_date
301               ,l_pa_date
302               ,l_period_name
303           FROM pa_periods_all pap1
304          WHERE pap1.org_id = p_org_id /*Added While  fixing bug 1657231*/
305            AND pap1.start_date = ( SELECT MIN(pap.start_date)
306                                      FROM pa_periods_all pap
307                                     WHERE status IN ('O','F')
308                                       AND pap.start_date >= TRUNC(p_expenditure_item_date)
309                                       AND org_id = p_org_id
310                                  );
311       END IF; -- l_pa_date IS NULL
312 
313   ELSE -- profile option is not set.
314     /*
315      *SQL to select the earliest open PA_DATE.
316      *Select the earliest open date ONLY if the global earliest date is NOT yet populated.
317      *Because , earliest pa_date will remain the same for a run.
318      */
319 
320      IF ( p_caller_flag = 'R' AND g_r_earliest_pa_start_date IS NULL ) OR
321         ( p_caller_flag = 'P' AND g_p_earliest_pa_start_date IS NULL ) THEN
322 
323     -- Note : This SQL uses the p_accounting_date filter criteria.
324 
325           SELECT pap1.start_date
326                 ,pap1.end_date
327                 ,pap1.period_name
328             INTO l_earliest_start_date
329                 ,l_earliest_end_date
330                 ,l_earliest_period_name
331             FROM pa_periods_all pap1
332            WHERE pap1.status IN ('O', 'F')
333              AND pap1.org_id =  p_org_id
334              AND pap1.end_date = ( SELECT MIN(pap.end_date)
335                                      FROM pa_periods_all pap
336                                     WHERE pap.status IN ('O','F')
337      --                               AND p_accounting_date BETWEEN pap.start_date AND pap.end_date /* commented for bug 1982225 */
338                                       AND pap.org_id = p_org_id
339                                  );
340      END IF ;
341 
342     -- SQL to select the PA_DATE for the current EI.
343     /* Code fix for Bug 1657231...
344        Added Begin... Exception...END to Handle No_Data_Found Exception */
345 
346     BEGIN  /* Added for Bug 1657231 */
347           SELECT pap.start_date
348                 ,pap.end_date
349                 ,pap.end_date
350                 ,pap.period_name
351             INTO l_start_date
352                 ,l_end_date
353                 ,l_pa_date
354                 ,l_period_name
355             FROM pa_periods_all pap
356            WHERE status in ('O','F')
357              AND pap.end_date >= TRUNC(p_expenditure_item_date)
358              AND p_accounting_date BETWEEN pap.start_date and pap.end_date
359              AND org_id = p_org_id ;
360 
361     EXCEPTION
362        WHEN NO_DATA_FOUND THEN
363        l_pa_date := NULL;
364        l_period_name := NULL;
365     END; /* Added for Bug 1657231 */
366 
367     /*If the l_pa_date obtained is NULL, try to find a pa_date without the accounting-date
368      *check. This approach was used even previously.
369      *This SQL will FAIL - if there are more than one row in pa_periods_all - with the same end_date.
370      */
371 
372           IF ( l_pa_date IS NULL )
373           THEN
374             SELECT pap1.start_date
375                   ,pap1.end_date
376                   ,pap1.end_date
377                   ,pap1.period_name
378               INTO l_start_date
379                   ,l_end_date
380                   ,l_pa_date
381                   ,l_period_name
382               FROM pa_periods_all pap1
383              WHERE pap1.end_date = ( SELECT MIN(pap.end_date)
384                                       FROM pa_periods_all pap
385                                      WHERE pap.status IN ('O','F')
386                                        AND pap.end_date >= TRUNC(p_expenditure_item_date)
387                                        AND pap.org_id = p_org_id
388                                    )
389                AND pap1.org_id = p_org_id; /* Added While  fixing bug 1657231
390                                                              Although not related to the bug */
391           END IF;
392   END IF; -- profile check
393 
394       /*
395        * Populate global variables.
396        */
397       IF ( p_caller_flag = 'R' ) THEN
398         -- Populate receiver cache.
399         g_r_earliest_pa_start_date   := l_earliest_start_date ;
400         g_r_earliest_pa_end_date     := l_earliest_end_date ;
401         g_r_earliest_pa_period_name  := l_earliest_period_name ;
402         g_recvr_org_id            := p_org_id ;
403         g_recvr_pa_start_date     := l_start_date ;
404         g_recvr_pa_end_date       := l_end_date ;
405         g_recvr_pa_date           := l_pa_date ;
406         g_recvr_pa_period_name     := l_period_name ;
407       ELSIF ( p_caller_flag = 'P' ) THEN
408         -- Populate provider cache
409         g_p_earliest_pa_start_date  := l_earliest_start_date ;
410         g_p_earliest_pa_end_date    := l_earliest_end_date ;
411         g_p_earliest_pa_period_name := l_earliest_period_name ;
412         g_prvdr_org_id           := p_org_id ;
413         g_prvdr_pa_start_date    := l_start_date ;
414         g_prvdr_pa_end_date      := l_end_date ;
415         g_prvdr_pa_date          := l_pa_date ;
416         g_prvdr_pa_period_name    := l_period_name ;
417       END IF; -- caller flag
418 
419 EXCEPTION
420   WHEN NO_DATA_FOUND THEN
421     /*
422      * Earliest dates are NULLed to ensure that the cache gets
423      * refreshed the next time.
424      */
425       IF ( p_caller_flag = 'R' ) THEN
426         -- Populate receiver cache.
427         g_r_earliest_pa_start_date   := NULL ;
428         g_r_earliest_pa_end_date     := NULL ;
429         g_r_earliest_pa_period_name  := NULL ;
430         g_recvr_pa_start_date     := NULL ;
431         g_recvr_pa_end_date       := NULL ;
432         g_recvr_pa_date           := NULL ;
433         g_recvr_pa_period_name     := NULL ;
434       ELSIF ( p_caller_flag = 'P' ) THEN
435         -- Populate provider cache
436         g_p_earliest_pa_start_date  := NULL ;
437         g_p_earliest_pa_end_date    := NULL ;
438         g_p_earliest_pa_period_name := NULL ;
439         g_prvdr_pa_start_date    := NULL ;
440         g_prvdr_pa_end_date      := NULL ;
441         g_prvdr_pa_date          := NULL ;
442         g_recvr_pa_period_name    := NULL ;
443       END IF; -- caller flag
444   WHEN OTHERS THEN
445      RAISE ;
446 
447 END refresh_pa_cache ;
448 
449 -------------------------------------------------------------------------------
450 -- Function - get_raw_cdl_pa_date
451 -- Comments are at Package specification level.
452 -- This function is created for Bug No : 1103257. Function will be called from
453 -- PAVVIT process ( Suppllier invoice interface from payables module ). This
454 -- function will ensure that PA_DATE populated for Raw CDLs will be always
455 -- Greater than Payables Accounting date for Raw CDLs.
456 --------------------------------------------------------------------------
457 --This function was modified to use caching. The actual DB access happens in
458 -- pa_integration.refresh_pa_cache().
459 --This is to get the pa_date for the provider part. The receiver part is done
460 -- by get_raw_cdl_recvr_pa_date().
461 --------------------------------------------------------------------------
462 FUNCTION get_raw_cdl_pa_date ( p_expenditure_item_date  IN DATE,
463                                p_accounting_date        IN DATE,
464                                p_org_id                 IN NUMBER
465                              )
466 RETURN DATE
467 IS
468   l_prof_new_gldate_derivation VARCHAR2(1);
469 BEGIN
470   /* Changed from value_specific to value for bug 5472333 */
471   l_prof_new_gldate_derivation := NVL(fnd_profile.value('PA_EN_NEW_GLDATE_DERIVATION'), 'N') ;
472 
473 
474   IF ( g_p_earliest_pa_start_date IS NOT NULL
475        and p_org_id = g_prvdr_org_id ) /* 1982225. cache should be referred only if orgs are same */
476 
477   THEN
478     -- values are already available in the provider_cache.
479     -- so, check the provider_cache and return pa_date accordingly.
480 
481     IF ( l_prof_new_gldate_derivation = 'Y')
482     THEN
483         IF ( p_accounting_date BETWEEN g_prvdr_pa_start_date AND g_prvdr_pa_end_date AND
484              p_expenditure_item_date  <= g_prvdr_pa_start_date )
485         THEN
486           return ( p_accounting_date ) ;
487         ELSIF ( p_accounting_date <= g_p_earliest_pa_start_date AND
488                 p_expenditure_item_date  <= g_p_earliest_pa_start_date )
489         THEN
490           g_prvdr_pa_start_date  := g_p_earliest_pa_start_date;
491           g_prvdr_pa_end_date    := g_p_earliest_pa_end_date;
492           g_prvdr_pa_period_name := g_p_earliest_pa_period_name;
493           return ( g_prvdr_pa_start_date ) ;
494         END IF ; -- p_accounting_date
495     ELSE
496       IF ( p_accounting_date BETWEEN g_prvdr_pa_start_date AND g_prvdr_pa_end_date AND
497             p_expenditure_item_date <= g_prvdr_pa_end_date )
498       THEN
499         return ( g_prvdr_pa_end_date );
500       ELSIF ( p_accounting_date <= g_p_earliest_pa_end_date AND
501               p_expenditure_item_date  <= g_p_earliest_pa_end_date )
502       THEN
503         g_prvdr_pa_start_date  := g_p_earliest_pa_start_date;
504         g_prvdr_pa_end_date    := g_p_earliest_pa_end_date;
505         g_prvdr_pa_period_name := g_p_earliest_pa_period_name;
506         return ( g_prvdr_pa_end_date ) ;
507       END IF; -- p_accounting_date
508     END IF ; -- profile
509   END IF ; -- g_p_earliest_pa_start_date
510 
511   /* If control comes here, it means that EITHER the cache is empty OR
512    * the provider Cache is NOT reusable.
513    * Access the DB and refresh cache and return pa_date.
514    */
515 
516     pa_integration.refresh_pa_cache( p_org_id , p_expenditure_item_date, p_accounting_date, 'P' );
517     RETURN ( g_prvdr_pa_date ) ;
518 EXCEPTION
519   WHEN OTHERS THEN
520     RAISE ;
521 
522 END get_raw_cdl_pa_date;
523 -------------------------------------------------------------------------------------------------------
524 --This is to get the pa_date for the receiver part. The provider part is done
525 -- by get_raw_cdl_pa_date().
526 --------------------------------------------------------------------------
527 
528 /**This is to get the pa_date for the receiver part **/
529 FUNCTION get_raw_cdl_recvr_pa_date ( p_expenditure_item_date  IN DATE,
530                                      p_accounting_date        IN DATE ,
531                                      p_org_id                 IN NUMBER
532                                    )
533 RETURN DATE
534 IS
535   l_prof_new_gldate_derivation VARCHAR2(1);
536 BEGIN
537   /* Changed from value_specific to value for bug 5472333 */
538   l_prof_new_gldate_derivation := NVL(fnd_profile.value('PA_EN_NEW_GLDATE_DERIVATION'), 'N') ;
539 
540   IF ( g_r_earliest_pa_start_date IS NOT NULL
541        and p_org_id = g_recvr_org_id )  /* 1982225. cache should be referred only if orgs are same */
542   THEN
543      -- receiver cache IS available.
544      -- Hence, try to re-use the receiver cache.
545 
546     IF ( l_prof_new_gldate_derivation = 'Y' )
547     THEN
548       IF ( p_accounting_date BETWEEN g_recvr_pa_start_date AND g_recvr_pa_end_date AND
549            p_expenditure_item_date <= g_recvr_pa_start_date )
550       THEN
551         return ( p_accounting_date ) ;
552       ELSIF ( p_accounting_date <= g_r_earliest_pa_start_date AND
553               p_expenditure_item_date <= g_r_earliest_pa_start_date )
554       THEN
555         g_recvr_pa_start_date  := g_p_earliest_pa_start_date;
556         g_recvr_pa_end_date    := g_p_earliest_pa_end_date;
557         g_recvr_pa_period_name := g_p_earliest_pa_period_name;
558         return ( g_recvr_pa_start_date ) ;
559       END IF ;
560     ELSE
561       IF ( p_accounting_date BETWEEN g_recvr_pa_start_date AND g_recvr_pa_end_date AND
562            p_expenditure_item_date <= g_recvr_pa_end_date )
563       THEN
564         return ( p_accounting_date ) ;
565       ELSIF ( p_accounting_date <= g_r_earliest_pa_end_date AND
566               p_expenditure_item_date <= g_r_earliest_pa_end_date )
567       THEN
568         g_recvr_pa_start_date  := g_p_earliest_pa_start_date;
569         g_recvr_pa_end_date    := g_p_earliest_pa_end_date;
570         g_recvr_pa_period_name := g_p_earliest_pa_period_name;
571         return ( g_recvr_pa_end_date ) ;
572       END IF ;
573     END IF; -- profile
574 
575     -- receiver cache is EMPTY.
576     -- Try to use the provider cache.
577 
578   ELSIF ( g_p_earliest_pa_start_date IS NOT NULL    /* 1982225 . we should check if prvdr cache is available or not. */
579           and g_prvdr_org_id = p_org_id )
580   THEN
581     IF ( l_prof_new_gldate_derivation = 'Y' )
582     THEN
583       IF ( p_accounting_date BETWEEN g_prvdr_pa_start_date AND g_prvdr_pa_end_date AND
584            p_expenditure_item_date <= g_prvdr_pa_start_date )
585       THEN
586          -- copy provider cache to receiver cache.
587          g_recvr_org_id               := g_prvdr_org_id ;
588          g_r_earliest_pa_start_date   := g_p_earliest_pa_start_date  ;
589          g_r_earliest_pa_end_date     := g_p_earliest_pa_end_date  ;
590          g_r_earliest_pa_period_name  := g_p_earliest_pa_period_name  ;
591          g_recvr_pa_start_date        := g_prvdr_pa_start_date ;
592          g_recvr_pa_end_date          := g_prvdr_pa_end_date ;
593          g_recvr_pa_period_name       := g_prvdr_pa_period_name ;
594          g_recvr_pa_date              := g_prvdr_pa_date ;
595          return ( p_accounting_date ) ;
596       ELSIF ( p_accounting_date <= g_p_earliest_pa_start_date AND
597               p_expenditure_item_date <= g_p_earliest_pa_start_date )
598       THEN
599          -- copy provider cache to receiver cache.
600          g_recvr_org_id               := g_prvdr_org_id ;
601          g_r_earliest_pa_start_date   := g_p_earliest_pa_start_date  ;
602          g_r_earliest_pa_end_date     := g_p_earliest_pa_end_date  ;
603          g_r_earliest_pa_period_name  := g_p_earliest_pa_period_name  ;
604          g_recvr_pa_start_date        := g_p_earliest_pa_start_date ;
605          g_recvr_pa_end_date          := g_p_earliest_pa_end_date ;
606          g_recvr_pa_period_name       := g_p_earliest_pa_period_name ;
607          g_recvr_pa_date              := g_prvdr_pa_date ;
608          return ( g_recvr_pa_start_date ) ;
609       END IF; --p_accounting_date
610     ELSE -- profile not set
611       IF ( p_accounting_date BETWEEN g_prvdr_pa_start_date AND g_prvdr_pa_end_date AND
612            p_expenditure_item_date <= g_prvdr_pa_end_date )
613       THEN
614          -- copy provider cache to receiver cache.
615          g_recvr_org_id               := g_prvdr_org_id ;
616          g_r_earliest_pa_start_date   := g_p_earliest_pa_start_date  ;
617          g_r_earliest_pa_end_date     := g_p_earliest_pa_end_date  ;
618          g_r_earliest_pa_period_name  := g_p_earliest_pa_period_name  ;
619          g_recvr_pa_start_date        := g_prvdr_pa_start_date ;
620          g_recvr_pa_end_date          := g_prvdr_pa_end_date ;
621          g_recvr_pa_period_name       := g_prvdr_pa_period_name ;
622          g_recvr_pa_date              := g_prvdr_pa_date ;
623          return ( g_recvr_pa_end_date ) ;
624       ELSIF ( p_accounting_date <= g_p_earliest_pa_end_date AND
625               p_expenditure_item_date <= g_p_earliest_pa_end_date )
626       THEN
627          -- copy provider cache to receiver cache.
628          g_recvr_org_id               := g_prvdr_org_id ;
629          g_r_earliest_pa_start_date   := g_p_earliest_pa_start_date  ;
630          g_r_earliest_pa_end_date     := g_p_earliest_pa_end_date  ;
631          g_r_earliest_pa_period_name  := g_p_earliest_pa_period_name  ;
632          g_recvr_pa_start_date        := g_p_earliest_pa_start_date ;
633          g_recvr_pa_end_date          := g_p_earliest_pa_end_date ;
634          g_recvr_pa_period_name       := g_p_earliest_pa_period_name ;
635          g_recvr_pa_date              := g_prvdr_pa_date ;
636          return ( g_p_earliest_pa_end_date ) ;
637       END IF; --p_accounting_date
638     END IF ;  -- profile
639   END IF ; -- recvr cache check
640  /*
641   *If control comes here,
642   *EITHER receiver cache is EMPTY or ( Both provider AND receiver caches are NOT reusable )
643   *hence hit the DB and populate/refresh receiver cache.
644   *then return g_recvr_pa_date.
645   */
646 
647     pa_integration.refresh_pa_cache ( p_org_id , p_expenditure_item_date , p_accounting_date, 'R' );
648     RETURN ( g_recvr_pa_date ) ;
649 EXCEPTION
650     WHEN OTHERS THEN
651       RAISE ;
652 END get_raw_cdl_recvr_pa_date ;
653 -------------------------------------------------------------------------------------------------------
654 
655 -- FUnction get_burden_cdl_pa_date
656 -- This function is created for Bug no : 1103257. FUnction will be called by
657 -- PACODTBC process (Distribute total burden cost). FUnction will ruturn the
658 -- Date to be populated as PA_DATE for Burden CDLs. FUnction will be called
659 -- only when the C and D types of the rows will be created for Supplier
660 -- Invoices.
661 ---------------------------------------------------------------------------
662 /*
663  * EPP.
664  * This function is NOT used anymore. Instead pa_utils2.get_pa_date is used
665  * since the functionality is same in both the procedures. Only the parameter
666  * is different.
667  */
668 FUNCTION get_burden_cdl_pa_date ( p_raw_cdl_date  IN DATE )
669     RETURN DATE
670 IS
671     l_pa_period_end_date  DATE;
672 BEGIN
673    SELECT     MIN(pap.end_date)
674      INTO     l_pa_period_end_date
675      FROM     pa_periods pap
676     WHERE     pap.status in ( 'O', 'F')
677       AND     pap.end_date >= p_raw_cdl_date;
678 
679    RETURN     l_pa_period_end_date;
680 END get_burden_cdl_pa_date;
681 ---------------------------------------------------------------------------
682 --End FUnction get_burden_cdl_pa_date
683 ---------------------------------------------------------------------------
684 /*
685  * EPP.
686  * This function can be called for both Provider and Receiver gl dates
687  * by passing the appropriate parameters.
688  */
689 FUNCTION get_gl_period_name ( p_gl_date         IN pa_cost_distribution_lines_all.gl_date%TYPE
690                              ,p_set_of_books_id IN pa_implementations_all.set_of_books_id%TYPE
691                             )
692 RETURN pa_cost_distribution_lines_all.gl_period_name%TYPE
693 IS
694     l_gl_period_name pa_cost_distribution_lines_all.gl_period_name%TYPE;
695     l_gl_start_date  DATE;
696     l_gl_end_date    DATE;
697 BEGIN
698 
699     If (trunc(p_gl_date) between trunc(G_PrevPdStDate) and trunc(G_PrevPdEdDate)) AND
700        G_PrevSOBId = p_set_of_books_id Then
701 
702        l_gl_period_name := G_PrevPeriodName;
703 
704     Else
705           SELECT PERIOD.period_name, PERIOD.start_date, PERIOD.end_date
706             INTO l_gl_period_name, l_gl_start_date, l_gl_end_date
707             FROM GL_PERIOD_STATUSES PERIOD
708            WHERE PERIOD.set_of_books_id = p_set_of_books_id
709              AND PERIOD.application_id = Pa_Period_Process_Pkg.Application_Id
710              AND PERIOD.adjustment_period_flag = 'N'
711              AND p_gl_date BETWEEN PERIOD.start_date AND PERIOD.end_date
712          ;
713 
714         G_PrevPeriodName := l_gl_period_name;
715         G_PrevPdStDate   := l_gl_start_date;
716         G_PrevPdEdDate   := l_gl_end_date;
717         G_PrevSOBId      := p_set_of_books_id;
718 
719      End If;
720 
721      RETURN     l_gl_period_name;
722 EXCEPTION
723 WHEN NO_DATA_FOUND
724 THEN
725   l_gl_period_name := NULL;
726   RETURN l_gl_period_name;
727 END get_gl_period_name;
728 ---------------------------------------------------------------------------
729 
730 /*
731  * The period information calculation is same for all transactions coming
732  * into PA thro transaction import. The following procedure does not distinguish
733  * between system linkages.
734  */
735 PROCEDURE get_period_information ( p_expenditure_item_date IN pa_expenditure_items_all.expenditure_item_date%TYPE
736                                   ,p_prvdr_gl_date IN pa_cost_distribution_lines_all.gl_date%TYPE
737                                   ,p_line_type IN pa_cost_distribution_lines_all.line_type%TYPE
738                                   ,p_prvdr_org_id IN pa_expenditure_items_all.org_id%TYPE
739                                   ,p_recvr_org_id IN pa_expenditure_items_all.org_id%TYPE
740                                   ,p_prvdr_sob_id IN pa_implementations_all.set_of_books_id%TYPE
741                                   ,p_recvr_sob_id IN pa_implementations_all.set_of_books_id%TYPE
742                                   ,x_prvdr_pa_date OUT NOCOPY pa_cost_distribution_lines_all.pa_date%TYPE
743                                   ,x_prvdr_pa_period_name OUT NOCOPY pa_cost_distribution_lines_all.pa_period_name%TYPE
744                                   ,x_prvdr_gl_period_name OUT NOCOPY pa_cost_distribution_lines_all.gl_period_name%TYPE
745                                   ,x_recvr_pa_date OUT NOCOPY pa_cost_distribution_lines_all.recvr_pa_date%TYPE
746                                   ,x_recvr_pa_period_name OUT NOCOPY pa_cost_distribution_lines_all.recvr_pa_period_name%TYPE
747                                   ,x_recvr_gl_date OUT NOCOPY pa_cost_distribution_lines_all.recvr_gl_date%TYPE
748                                   ,x_recvr_gl_period_name OUT NOCOPY pa_cost_distribution_lines_all.recvr_gl_period_name%TYPE
749                                   ,x_return_status OUT NOCOPY NUMBER
750                                   ,x_error_code OUT NOCOPY VARCHAR2
751                                   ,x_error_stage OUT NOCOPY NUMBER
752                                  )
753 IS
754     l_prvdr_pa_date        pa_cost_distribution_lines_all.pa_date%TYPE;
755     l_prvdr_pa_period_name pa_periods.period_name%TYPE;
756     l_prvdr_gl_period_name gl_periods.period_name%TYPE;
757 
758     l_recvr_pa_date        pa_cost_distribution_lines_all.pa_date%TYPE;
759     l_recvr_pa_period_name pa_periods.period_name%TYPE;
760     l_recvr_gl_date        pa_cost_distribution_lines_all.gl_date%TYPE;
761     l_recvr_gl_period_name gl_periods.period_name%TYPE;
762 
763     l_pa_gl_app_id NUMBER := 8721;
764     l_gl_app_id NUMBER := 101;
765 
766   /*
767    * Processing related variables.
768    */
769   l_return_status              VARCHAR2(1) := FND_API.G_RET_STS_UNEXP_ERROR;
770   l_error_code                 VARCHAR2(30);
771   l_error_stage                VARCHAR2(30);
772   l_debug_mode                 VARCHAR2(1);
773   l_stage                      NUMBER ;
774 
775   l_prof_new_gldate_derivation VARCHAR2(1) := 'N';
776   l_use_same_pa_gl_period_prvdr VARCHAR2(1) := 'N';
777   l_use_same_pa_gl_period_recvr VARCHAR2(1) := 'N';
778 BEGIN
779   pa_debug.init_err_stack('pa_integration.get_period_information');
780 
781   fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
782   l_debug_mode := NVL(l_debug_mode, 'N');
783 
784   pa_debug.set_process('PLSQL','LOG',l_debug_mode);
785 
786   l_stage := 100;
787   IF l_debug_mode = 'Y' THEN
788    pa_debug.g_err_stage := TO_CHAR(l_stage) || ':From get_period_information';
789    pa_debug.write_file(pa_debug.g_err_stage);
790   END IF;
791 
792   /*
793    * Populating setup related variables.
794    */
795   /* Changed from value_specific to value for bug 5472333 */
796   l_prof_new_gldate_derivation := NVL(fnd_profile.value('PA_EN_NEW_GLDATE_DERIVATION'), 'N') ;
797   l_use_same_pa_gl_period_prvdr := NVL(PA_PERIOD_PROCESS_PKG.Use_Same_PA_GL_Period(p_prvdr_org_id), 'N');
798   l_use_same_pa_gl_period_recvr := NVL(PA_PERIOD_PROCESS_PKG.Use_Same_PA_GL_Period(p_recvr_org_id), 'N');
799 
800     IF ( l_prof_new_gldate_derivation = 'Y' )
801     THEN
802       l_stage := 200;
803             /*
804              * Get Gl periods based on ei date.
805              */
806             l_prvdr_gl_period_name := pa_integration.get_gl_period_name( p_gl_date => p_prvdr_gl_date
807                                                                         ,p_set_of_books_id => p_prvdr_sob_id
808                                                                        );
809 
810             -- Bug 2248543 Added provider and receiver org_id check
811             if ( p_prvdr_org_id <> p_recvr_org_id ) then
812                 l_recvr_gl_date := pa_utils2.get_recvr_gl_date( p_reference_date => p_expenditure_item_date
813                                                            ,p_application_id => l_pa_gl_app_id
814                                                            ,p_set_of_books_id => p_recvr_sob_id
815                                                           );
816                 l_recvr_gl_period_name := pa_utils2.g_recvr_gl_period_name;
817             else
818                 l_recvr_gl_date := p_prvdr_gl_date;
819                 l_recvr_gl_period_name := l_prvdr_gl_period_name;
820             end if;
821 
822             /*
823              * Deriving PA period information for Provider.
824              */
825             IF ( l_use_same_pa_gl_period_prvdr = 'Y' )
826             THEN
827               l_stage := 300;
828               /*
829                * Copy Gl period information to Pa periods.
830                */
831               l_prvdr_pa_date := p_prvdr_gl_date;
832               l_prvdr_pa_period_name := l_prvdr_gl_period_name;
836                * Get Pa periods based on ei date.
833             ELSE -- implementation option is not set
834               l_stage := 400;
835               /*
837                */
838 
839               l_prvdr_pa_date := pa_utils2.get_pa_date
840                                                       ( p_ei_date  => p_expenditure_item_date
841                                                        ,p_gl_date  => SYSDATE
842                                                        ,p_org_id   => p_prvdr_org_id
843                                                       );
844               l_prvdr_pa_period_name := pa_utils2.g_prvdr_pa_period_name;
845 
846             END IF; -- implementations option
847             /*
848              * Deriving PA period information for Receiver.
849              */
850             IF ( l_use_same_pa_gl_period_recvr = 'Y' )
851             THEN
852               l_stage := 425;
853               /*
854                * Copy Gl period information to Pa periods.
855                */
856               l_recvr_pa_date := l_recvr_gl_date;
857               l_recvr_pa_period_name := l_recvr_gl_period_name;
858             ELSE -- implementation option is not set
859               l_stage := 450;
860               /*
861                * Get Pa periods based on ei date.
862                */
863 
864               -- Bug 2248543 Added provider and receiver org_id check
865               if ( p_prvdr_org_id <> p_recvr_org_id ) then
866                  l_recvr_pa_date := pa_utils2.get_recvr_pa_date
867                                                       ( p_ei_date  => p_expenditure_item_date
868                                                        ,p_gl_date  => SYSDATE
869                                                        ,p_org_id   => p_recvr_org_id
870                                                       );
871                  l_recvr_pa_period_name := pa_utils2.g_recvr_pa_period_name;
872               else
873                  l_recvr_pa_date := l_prvdr_pa_date;
874                  l_recvr_pa_period_name := l_prvdr_pa_period_name;
875               end if;
876 
877             END IF; -- implementations option
878     ELSE -- profile option is not set.
879       l_stage := 500;
880       /*
881        * Get Pa periods based on ei date.
882        */
883          l_prvdr_pa_date := pa_integration.get_raw_cdl_pa_date
884                                                       ( p_expenditure_item_date => p_expenditure_item_date
885                                                        ,p_accounting_date => p_prvdr_gl_date
886                                                        ,p_org_id => p_prvdr_org_id
887                                                       );
888          l_prvdr_pa_period_name := g_prvdr_pa_period_name;
889 
890          /*
891           * recvr_gl_date is not available from txn import.
892           * should find a way out.
893           */
894          -- Bug 2248543 Added provider and receiver org_id check
895          if ( p_prvdr_org_id <> p_recvr_org_id ) then
896             l_recvr_pa_date := pa_utils2.get_recvr_pa_date
897                                                       ( p_ei_date => p_expenditure_item_date
898                                                        ,p_gl_date => SYSDATE
899                                                        ,p_org_id => p_recvr_org_id
900                                                       );
901             l_recvr_pa_period_name := pa_utils2.g_recvr_pa_period_name;
902          else
903             l_recvr_pa_date := l_prvdr_pa_date;
904             l_recvr_pa_period_name := l_prvdr_pa_period_name;
905          end if;
906 
907       /*
908        * Get Gl periods based on above derived Pa date.
909        */
910          l_prvdr_gl_period_name := get_gl_period_name( p_gl_date => p_prvdr_gl_date
911                                                       ,p_set_of_books_id => p_prvdr_sob_id
912                                                      );
913 
914          -- Bug 2248543 Added provider and receiver org_id check
915          if ( p_prvdr_org_id <> p_recvr_org_id) then
916              l_recvr_gl_date := pa_utils2.get_recvr_gl_date( p_reference_date => l_recvr_pa_date
917                                                         ,p_application_id => l_gl_app_id
918                                                         ,p_set_of_books_id => p_recvr_sob_id
919                                                        );
920              l_recvr_gl_period_name := pa_utils2.g_recvr_gl_period_name;
921          else
922              l_recvr_gl_date := p_prvdr_gl_date;
923              l_recvr_gl_period_name := l_prvdr_gl_period_name;
924          end if;
925 
926     END IF; -- profile option
927     l_stage := 600;
928 
929     /*
930      * Populate the out variables.
931      */
932     x_prvdr_pa_date := l_prvdr_pa_date;
933     x_prvdr_pa_period_name := l_prvdr_pa_period_name;
934     x_prvdr_gl_period_name := l_prvdr_gl_period_name;
935 
936     x_recvr_pa_date := l_recvr_pa_date;
937     x_recvr_pa_period_name := l_recvr_pa_period_name;
938     x_recvr_gl_date := l_recvr_gl_date;
939     x_recvr_gl_period_name := l_recvr_gl_period_name;
940 
941     x_return_status := 0;
942 
943     -- reset the error stack
944     PA_DEBUG.reset_err_stack;
945 
946 EXCEPTION
947   WHEN NO_DATA_FOUND THEN
948     x_prvdr_pa_date := NULL;
949     x_prvdr_pa_period_name := NULL;
950     x_prvdr_gl_period_name := NULL;
951 
952     x_recvr_pa_date := NULL;
953     x_recvr_pa_period_name := NULL;
954     x_recvr_gl_date := NULL;
955     x_recvr_gl_period_name := NULL;
956   WHEN OTHERS THEN
957      RAISE ;
958 END; -- get_period_information
959 
960 
961 END pa_integration;