DBA Data[Home] [Help]

PACKAGE BODY: APPS.PA_INVOICE_ACTIONS

Source


1 Package Body PA_Invoice_Actions as
2 /* $Header: PAXVIACB.pls 120.10 2011/04/01 22:43:24 apaul ship $ */
3 
4 /*----------------- Private Procedure/Function Declarations -----------------*/
5 
6 /*----------------------------------------------------------------------------+
7  | This Private Procedure Update_Approve_Invoices Updates                     |
8  | PA_DRAFT_INVOICES_ALL table with invoice approval columns                  |
9  +----------------------------------------------------------------------------*/
10   Procedure Update_Approve_Invoices ( P_Project_ID         in  number,
11                                       P_Draft_Invoice_Num  in  number,
12                                       P_User_ID            in  number,
13                                       P_Employee_ID        in  number) is
14   BEGIN
15 
16     UPDATE PA_Draft_Invoices_ALL
17        SET Approved_Date         = sysdate,
18            Approved_by_person_id = P_Employee_ID,
19            Last_Update_Date      = sysdate,
20            Last_Updated_By       = P_User_ID
21      WHERE Project_ID            = P_Project_ID
22        AND Draft_Invoice_Num     = P_Draft_Invoice_Num;
23 
24   EXCEPTION
25     WHEN OTHERS THEN
26       RAISE;
27   END Update_Approve_Invoices;
28 
29 /*----------------------------------------------------------------------------+
30  | This Private Procedure Update_Unapprove_Invoices Updates                   |
31  | PA_DRAFT_INVOICES_ALL table with invoice approval columns as NULL          |
32  +----------------------------------------------------------------------------*/
33   Procedure Update_Unapprove_Invoices ( P_Invoice_Set_ID     in  number,
34                                         P_User_ID            in  number) is
35   BEGIN
36 
37     UPDATE PA_Draft_Invoices_ALL
38        SET Approved_Date         = NULL,
39            Approved_by_person_id = NULL,
40            Released_Date         = NULL,
41            Released_by_person_id = NULL,
42            RA_Invoice_Number     = NULL,
43            Invoice_Date          = NULL,
44            Last_Update_Date      = sysdate,
45            Last_Updated_By       = P_User_ID
46      WHERE Invoice_Set_ID        = P_Invoice_Set_ID;
47 
48   EXCEPTION
49     WHEN OTHERS THEN
50       RAISE;
51   END Update_Unapprove_Invoices;
52 
53 /*----------------------------------------------------------------------------+
54  | This Private Procedure Update_Release_Invoices Updates                     |
55  | PA_DRAFT_INVOICES_ALL table with invoice Release attributes                |
56  +----------------------------------------------------------------------------*/
57   Procedure Update_Release_Invoices ( P_Project_ID               in  number,
58                                       P_Draft_Invoice_Num        in  number,
59                                       P_RA_Invoice_Date          in  date,
60                                       P_RA_Invoice_Num           in  varchar2,
61                                       P_User_ID                  in  number,
62                                       P_Employee_ID              in  number,
63 				      P_Credit_Memo_Reason_Code  in  varchar2) is
64   BEGIN
65 
66     UPDATE PA_Draft_Invoices_ALL
67        SET Released_Date           = sysdate,
68            Released_by_person_id   = P_Employee_ID,
69            RA_Invoice_Number       = P_RA_Invoice_Num,
70            Invoice_Date            = P_RA_Invoice_Date,
71            Last_Update_Date        = sysdate,
72            Last_Updated_By         = P_User_ID,
73 	   Credit_Memo_Reason_Code = P_Credit_Memo_Reason_Code /* Bug #2728431*/
74      WHERE Project_ID              = P_Project_ID
75        AND Draft_Invoice_Num       = P_Draft_Invoice_Num;
76 
77 
78   EXCEPTION
79     WHEN OTHERS THEN
80       RAISE;
81   END Update_Release_Invoices;
82 
83 
84 /*----------------------------------------------------------------------------+
85  | This Private Procedure Update_Unrelease_Invoices Updates                   |
86  | PA_DRAFT_INVOICES_ALL table with invoice Release attributes as NULL        |
87  +----------------------------------------------------------------------------*/
88   Procedure Update_Unrelease_Invoices ( P_Invoice_Set_ID     in  number,
89                                         P_User_ID            in  number) is
90   BEGIN
91 
92     UPDATE PA_Draft_Invoices_ALL
93        SET Released_Date           = NULL,
94            Released_by_person_id   = NULL,
95            RA_Invoice_Number       = NULL,
96            Invoice_Date            = NULL,
97            Last_Update_Date        = sysdate,
98            Last_Updated_By         = P_User_ID,
99            Credit_memo_reason_code = NULL    /*  Bug #2728431*/
100      WHERE Invoice_Set_ID        = P_Invoice_Set_ID;
101 
102 
103   EXCEPTION
104     WHEN OTHERS THEN
105       RAISE;
106   END Update_Unrelease_Invoices;
107 
108 
109 /*----------------------------------------------------------------------------+
110  | This Private Procedure Insert_Distrbution_Warning Inserts draft Invoice    |
111  | distribution warning.                                                      |
112  +----------------------------------------------------------------------------*/
113   Procedure Insert_Distrbution_Warning ( P_Project_ID         in  number,
114                                          P_Draft_Invoice_Num  in  number,
115                                          P_User_ID            in  number,
116                                          P_Request_ID         in  number,
117                                          P_Invoice_Set_ID     in  number,
118                                          P_Error_Message_Code in  varchar2) is
119 
120     l_error_message   pa_lookups.meaning%TYPE;
121 
122   BEGIN
123 
124     BEGIN
125       SELECT Meaning
126         INTO l_error_message
127         FROM PA_Lookups
128        WHERE Lookup_Type = 'BILLING EXTENSION MESSAGES'
129          AND Lookup_Code = P_Error_Message_Code;
130 
131     EXCEPTION
132       WHEN NO_DATA_FOUND THEN
133         l_error_message := P_Error_Message_Code;
134     END;
135 
136     IF (P_Invoice_Set_ID is NULL) THEN
137 
138       INSERT INTO PA_DISTRIBUTION_WARNINGS
139       (
140       PROJECT_ID, DRAFT_INVOICE_NUM, LAST_UPDATE_DATE, LAST_UPDATED_BY,
141       CREATION_DATE, CREATED_BY, REQUEST_ID, WARNING_MESSAGE
142       )
143       VALUES
144       (
145       P_Project_ID, P_Draft_Invoice_Num, sysdate, P_User_ID,
146       sysdate, P_User_ID, P_Request_ID, l_error_message
147       );
148 
149     ELSE
150 
151       INSERT INTO PA_DISTRIBUTION_WARNINGS
152       (
153       PROJECT_ID, DRAFT_INVOICE_NUM, LAST_UPDATE_DATE, LAST_UPDATED_BY,
154       CREATION_DATE, CREATED_BY, REQUEST_ID, WARNING_MESSAGE
155       )
156       SELECT Project_ID, Draft_Invoice_Num, sysdate, P_User_ID,
157              sysdate, P_User_ID, P_Request_ID, l_error_message
158         FROM PA_Draft_Invoices_ALL
159        WHERE Invoice_Set_ID = P_Invoice_Set_ID;
160 
161     END IF;
162 
163   EXCEPTION
164     WHEN OTHERS THEN
165       RAISE;
166   END Insert_Distrbution_Warning;
167 
168 
169  /*----------------------------------------------------------------------------+
170  |   This Private Procedure Validate_Credit_Memo_Reason validates the          |
171  |  credit memo reason_Code                                                    |
172  +----------------------------------------------------------------------------*/
173  Procedure Validate_Credit_Memo_Reason( P_Project_ID               in  number,
174                                         P_Draft_Invoice_Num        in  number,
175                                         P_RA_Invoice_Date          in  date,
176 			                P_Credit_Memo_Reason_Code  in out  NOCOPY varchar2, --File.Sql.39 bug 4440895
177                                         X_Error_Message_Code       out NOCOPY varchar2) is --File.Sql.39 bug 4440895
178  l_Credit_memo_Reason_flag    pa_implementations.credit_Memo_Reason_Flag%TYPE :='N';
179  l_credit_memo_exist          VARCHAR2(1):='N';
180  l_credit_memo_reason_valid   VARCHAR2(1):='N';
181  Cursor Credit_Memo_Reason_Flag is
182    SELECT Credit_Memo_Reason_Flag
183    FROM pa_implementations;
184 
185 Cursor Credit_Memo_exist is
186   SELECT 'Y'
187   FROM dual
188   WHERE EXISTS(SELECT draft_invoice_num
189                FROM pa_draft_invoices i
190                WHERE i.project_id = P_Project_ID
191                AND i.draft_invoice_num = P_Draft_Invoice_Num
192                AND i.draft_invoice_num_credited IS NOT NULL);
193 
194 Cursor Credit_Memo_Reason_Valid is
195   SELECT 'Y' FROM dual
196   WHERE EXISTS( select lookup_code
197                 from   fnd_lookup_values_vl
198                 where  lookup_type='CREDIT_MEMO_REASON'
199 	        and    lookup_code = P_Credit_Memo_Reason_Code
200                 and    enabled_flag='Y'
201                 and    P_RA_invoice_date between start_date_active and nvl(end_date_active,P_RA_invoice_date));
202 
203 
204 BEGIN
205   X_Error_Message_Code :=NULL;
206   /* Checking the implementation options for Credit Memo Reason Required */
207   OPEN Credit_Memo_Reason_Flag;
208   FETCH Credit_Memo_Reason_Flag into l_Credit_Memo_Reason_Flag;
209   CLOSE Credit_Memo_Reason_Flag;
210 
211   /* Checking Whether its a Credit Memo Invoice */
212   OPEN Credit_Memo_exist;
213   FETCH Credit_Memo_exist into l_Credit_Memo_exist;
214 
215   IF Credit_Memo_exist%NOTFOUND then
216      l_Credit_Memo_exist := 'N';
217   END IF;
218 
219   CLOSE Credit_Memo_exist;
220 
221   /* Checking Valid Credit Memo Reason Code */
222   IF P_Credit_Memo_Reason_Code IS NOT NULL THEN
223      OPEN Credit_Memo_Reason_valid;
224      FETCH Credit_Memo_Reason_valid into l_Credit_Memo_Reason_valid;
225      IF Credit_Memo_Reason_Valid%NOTFOUND then
226         l_Credit_Memo_Reason_valid := 'N';
227      END IF;
228      CLOSE Credit_Memo_Reason_valid;
229   END IF;
230 
231   IF l_credit_memo_exist ='Y' THEN
232      IF l_Credit_Memo_Reason_Flag ='Y' THEN
233         IF P_Credit_Memo_Reason_Code IS NOT NULL THEN
234            IF l_Credit_Memo_Reason_valid <>'Y' THEN
235               X_Error_Message_Code := 'PA_IN_INV_CR_MEMO_REASON';
236               RETURN;
237            END IF;
238         ELSE
239            X_Error_Message_Code := 'PA_IN_REQ_CR_MEMO_REASON';
240            RETURN;
241         END IF;
242      ELSE
243         IF P_Credit_Memo_Reason_Code IS NOT NULL THEN
244            IF l_Credit_Memo_Reason_valid <>'Y' THEN
245               X_Error_Message_Code := 'PA_IN_INV_CR_MEMO_REASON';
246               RETURN;
247            END IF;
248         END IF;
249      END IF;/* End of l_Credit_Memo_Reason_Flag ='Y'*/
250 
251   ELSE
252      P_Credit_Memo_Reason_Code:=NULL;
253   END IF;/* End of l_credit_memo_exist ='Y'*/
254 
255  END Validate_Credit_Memo_Reason;
256 
257 /*------------- End of Private Procedure/Function Declarations ---------------*/
258 
259 
260 /*----------------- Public Procedure/Function Declarations -------------------*/
261 
262 /*----------------------------------------------------------------------------+
263  |      For Details/Comments Refer Package Specification Comments             |
264  +----------------------------------------------------------------------------*/
265   Procedure Validate_Approval ( P_Project_ID         in  number,
266                                 P_Draft_Invoice_Num  in  number,
267                                 P_Validation_Level   in  varchar2,
268                                 X_Error_Message_Code out NOCOPY varchar2 ) is --File.Sql.39 bug 4440895
269 
270      l_customer_id            pa_draft_invoices_v.customer_id%TYPE;
271      l_generation_error_flag  pa_draft_invoices_v.generation_error_flag%TYPE;
272      l_approved_date          pa_draft_invoices_v.approved_date%TYPE;
273      l_project_status_code    pa_draft_invoices_v.project_status_code%TYPE;
274      l_dummy                  number;
275      l_err_msg_code           varchar2(30);
276 
277 
278 /* Bug#4940211 - Performance Issue for calling the pa_draft_invoices_v
279    Fix : commented the old code and Geting
280          the value from pa_project_all and pa_draft_invoices table
281 
282      Cursor Inv_Cur is
283        SELECT i.customer_id, i.generation_error_flag,
284               i.approved_date , i.project_status_code
285          FROM pa_draft_invoices_v i
286         WHERE i.project_id = P_Project_ID
287           AND i.draft_invoice_num = P_Draft_Invoice_Num;
288 */
289 
290     Cursor Inv_cur is
291         SELECT i.customer_id, i.generation_error_flag,
292                i.approved_date, prj.project_status_code project_status_code
293          FROM  pa_draft_invoices i,
294                pa_projects_all prj
295         WHERE  prj.project_id = P_Project_ID
296           AND  i.project_id = prj.project_id
297           AND  i.draft_invoice_num = P_Draft_Invoice_Num;
298 
299 
300 
301      Cursor Cust_Cur is
302 /* TCA changes
303        SELECT 1
304          FROM RA_CUSTOMERS
305         WHERE customer_id = l_customer_id
306           AND NVL(status, 'A') <> 'A'
307           AND customer_prospect_code = 'CUSTOMER';
308 */
309        SELECT 1
310          FROM HZ_CUST_ACCOUNTS
311         WHERE cust_account_id = l_customer_id
312           AND NVL(status, 'A') <> 'A';
313 --          AND customer_prospect_code = 'CUSTOMER';
314 
315   BEGIN
316     -- Reset Output Parameters
317     X_Error_Message_Code := NULL;
318 
319     IF P_Validation_Level = 'R' THEN         /* Record Level Validation */
320 
321       OPEN Inv_Cur;
322       FETCH Inv_Cur into l_customer_id,  l_generation_error_flag,
323                          l_approved_date,l_project_status_code;
324       CLOSE Inv_Cur;
325 
326       /* Check Project Status */
327       /* Remove Project Status Check as discussed
328       IF (PA_Project_Stus_Utils.Is_Project_Status_Closed(l_project_status_code)
329                                           = 'Y') THEN
330         X_Error_Message_Code := 'PA_EX_CLOSED_PROJECT';
331         GOTO all_done;
332       END IF;*/
333 
334       /* Bug#1499480:Check whether action 'GENERATE_INV' is enabled for Project Status */
335       IF (PA_Project_Utils.Check_Prj_Stus_Action_Allowed(l_project_status_code,'GENERATE_INV')
336                                           = 'N') THEN
337         X_Error_Message_Code := 'PA_INV_ACTION_INVALID';
338         GOTO all_done;
339       END IF;
340 
341 
342       /* Check Generation Error */
343       IF (l_generation_error_flag = 'Y') THEN
344         X_Error_Message_Code := 'PA_IN_NO_APP_GEN_ERR';
345         GOTO all_done;
346       END IF;
347 
348       /* Check Invoice Status */
349       IF (l_approved_date is not NULL) THEN
350         X_Error_Message_Code := 'PA_IN_ALREADY_APPROVED';
351         GOTO all_done;
352       END IF;
353 
354       /* Check Customer Status */
355       l_dummy := 0;
356       OPEN Cust_Cur;
357       Fetch Cust_Cur into l_dummy;
358       CLOSE Cust_Cur;
359 
360       IF (l_dummy > 0) THEN
361         X_Error_Message_Code := 'PA_EX_INACTIVE_CUSTOMER';
362         GOTO all_done;
363       END IF;
364 
365 
366     ELSIF P_Validation_Level = 'C' THEN      /* Commit Level Validation */
367 
368       NULL;
369 
370     END IF;   /* Validation Level Checks */
371 
372     <<all_done>>
373       NULL;
374 
375   EXCEPTION
376     WHEN OTHERS THEN
377         RAISE;
378   END Validate_Approval;
379 
380 
381 
382 /*----------------------------------------------------------------------------+
383  |      For Details/Comments Refer Package Specification Comments             |
384  +----------------------------------------------------------------------------*/
385   Procedure Validate_Release  ( P_Project_ID              in  number,
386                                 P_Draft_Invoice_Num       in  number,
387                                 P_Validation_Level        in  varchar2,
388                                 P_User_ID                 in  number,
389                                 P_RA_Invoice_Date         in  date,
390                                 P_RA_Invoice_Num          in  varchar2,
391                                 P_Credit_Memo_Reason_Code in out  NOCOPY varchar2, --File.Sql.39 bug 4440895
392                                 X_RA_Invoice_Num          out NOCOPY varchar2, --File.Sql.39 bug 4440895
393                                 X_Error_Message_Code      out NOCOPY varchar2) is --File.Sql.39 bug 4440895
394 
395      l_entry_method    pa_implementations.user_defined_invoice_num_code%TYPE;
396      l_num_type        pa_implementations.manual_invoice_num_type%TYPE;
397 
398      l_dummy           number;
399      l_customer_id     number;
400      l_err_msg_code    varchar2(30);
401      l_RA_Invoice_Num  pa_draft_invoices_v.RA_Invoice_Number%TYPE;
402      l_status          number;
403      l_bill_to	         number;
404      l_ship_to	         number;
405 	  l_Error_Message_Code VARCHAR2(80):=NULL;
406 
407      l_invoice_category  pa_draft_invoices_v.invoice_category%TYPE;
408      l_bill_ship_to_customer_id number; /*Added for customer account relation enhancement*/
409      Cursor Imp_Cur is
410        SELECT user_defined_invoice_num_code, manual_invoice_num_type
411          FROM pa_implementations;
412 
413      Cursor Imp_Cur_Inter is
414        SELECT CC_MANUAL_INVOICE_NUM_CODE, CC_MANUAL_INVOICE_NUM_TYPE
415          FROM pa_implementations;
416 
417      /* Added for Bug 2941112 */
418      l_draft_inv_num_cr    number;
419 
420      l_Credit_Memo_Reason_Code    varchar2(100);
421 
422   BEGIN
423 
424     /* ATG Changes */
425 
426        l_Credit_Memo_Reason_Code := P_Credit_Memo_Reason_Code;
427 
428 
429     -- Reset Output Parameters
430     X_Error_Message_Code := NULL;
431     -- Bug 682284
432     /* Get customer, ship_to_address_id, bill_to_address_id
433        for this draft Invoice */
434     BEGIN
435 
436 -- IC Changes
437 -- Invoice category field is added here to classify the invoice
438 -- into "INTERNAL INVOICE' and "EXTERNAL INVOICE"
439 --
440 /*PROJCUST.bill_to_customer_id is added for customer account relation enhancement*/
441        SELECT PROJCUST.customer_id,PROJCUST.bill_to_customer_id,PROJCUST.bill_to_address_id,
442               PROJCUST.ship_to_address_id,
443               decode(nvl(PROJTYPE.cc_prvdr_flag,'N'),
444                          'Y', 'INTERNAL-INVOICE',
445                          decode(nvl(PROJCUST.bill_another_project_flag,'N'),
446                                 'Y', 'INTERNAL-INVOICE',
447                                 'EXTERNAL-INVOICE'))
448        INTO  l_customer_id,l_bill_ship_to_customer_id, l_bill_to, l_ship_to, l_invoice_category
449        FROM pa_draft_invoices INV, pa_agreements_all  AGREE, /* fix bug 2082864 for MCB2 */
450             pa_project_customers PROJCUST,
451             pa_projects PROJ,
452             pa_project_types PROJTYPE
453        WHERE INV.project_id = P_Project_id
454        AND INV.draft_invoice_num = P_Draft_Invoice_Num
455        AND AGREE.agreement_id = INV.agreement_id
456        AND PROJCUST.customer_id = AGREE.customer_id
457        AND PROJCUST.project_id = P_Project_id
458        AND PROJ.project_id = INV.project_id
459        AND PROJ.project_type = PROJTYPE.project_type;
460 
461     EXCEPTION
462 
463        WHEN NO_DATA_FOUND THEN
464 /*          X_Error_Message_Code := 'PA_INV_NO_BILL_TO_ADDRESS'; commented for customer account relation enhancement*/
465             X_Error_Message_Code := 'PA_INV_NO_CUSTOMER';
466             GOTO all_done;
467 
468     END;
469 
470     /* Check for bill_to_address_id */
471 
472     IF (l_bill_to IS NULL) THEN
473         X_Error_Message_Code := 'PA_INV_NO_BILL_TO_ADDRESS';
474         GOTO all_done;
475     END IF;
476 
477    /* Check for ship_to_address_id */
478     IF (l_ship_to IS NULL) THEN
479         X_Error_Message_Code := 'PA_INV_NO_SHIP_TO_ADDRESS';
480         GOTO all_done;
481     END IF;
482 
483    /* Check for bill_to_contact_id */
484 
485 /* Commneting for bug 4879331 as we are no more validating if billing contact is
486    populated or not.
487     BEGIN
488 
489        SELECT null INTO l_dummy
490        FROM sys.dual
491        WHERE EXISTS ( SELECT project_id
492                       FROM pa_project_contacts
493                       WHERE project_id = P_project_id
494                       AND customer_id = l_customer_id
495                       AND bill_ship_customer_id=l_bill_ship_to_customer_id -- Added for customer account relation
496                                                                             -- enhancement
497                       AND project_contact_type_code = 'BILLING');
498 
499     EXCEPTION
500 
501        WHEN NO_DATA_FOUND THEN
502             X_Error_Message_Code := 'PA_INV_NO_BILL_TO_CONTACT';
503             GOTO all_done;
504 
505     END;
506 End Bug 4879331. */
507     -- End Bug 682284
508 
509     /* Fix for bug 2941112  */
510     BEGIN
511          SELECT nvl(draft_invoice_num_credited,0)
512          INTO   l_draft_inv_num_cr
513          FROM   pa_draft_invoices
514          WHERE  project_id = p_project_id
515          AND    draft_invoice_num = P_Draft_Invoice_Num;
516     EXCEPTION
517        WHEN NO_DATA_FOUND THEN
518             NULL;
519     END;
520 
521 /* Commneting for bug 4879331 as we are no more validating if billing contact is
522    populated or not.
523     IF ( l_draft_inv_num_cr = 0 )
524     THEN
525         BEGIN
526 -- bug 4325231
527 --              SELECT null INTO l_dummy
528 --              FROM dual
529 --              WHERE EXISTS ( SELECT project_id
530 --                             FROM   pa_draft_invoices di, ra_contacts rc
531 --                             WHERE  di.project_id = p_project_id
532 --                             AND    di.draft_invoice_num = P_Draft_Invoice_Num
533 --                             AND    di.bill_to_contact_id = rc.contact_id
534 --                             AND    nvl(rc.status,'N') = 'A'
535 --                            );
536              SELECT null INTO l_dummy
537              FROM dual
538              WHERE EXISTS ( SELECT project_id
539                             FROM   pa_draft_invoices di, hz_cust_account_roles rc
540                             WHERE  di.project_id = p_project_id
541                             AND    di.draft_invoice_num = P_Draft_Invoice_Num
542                             AND    di.bill_to_contact_id = rc.cust_account_role_id
543                             AND    nvl(rc.status,'N') = 'A'
544                            );
545        EXCEPTION
546        WHEN NO_DATA_FOUND THEN
547             X_Error_Message_Code := 'PA_BIL_CONT_NOT_ACT';
548             GOTO all_done;
549        END;
550     END IF;
551 
552 End bug 4879331. */
553 
554 if l_invoice_category = 'EXTERNAL-INVOICE'  then
555     OPEN Imp_Cur;
556     FETCH Imp_Cur into l_entry_method, l_num_type;
557     CLOSE Imp_Cur;
558 else
559     OPEN Imp_Cur_Inter;
560     FETCH Imp_Cur_Inter into l_entry_method, l_num_type;
561     CLOSE Imp_Cur_Inter;
562 end if;
563     IF P_Validation_Level IN ('R','F_INV_DT','F_INV_NUM')
564     THEN         /* Record Level Validation/Field level */
565 
566       /* RA invoice number checks for mannual numbering type */
567       IF (l_entry_method <> 'AUTOMATIC')
568       AND ( P_Validation_level IN ( 'R','F_INV_NUM'))  THEN
569 
570         /* RA invoice number should be entered */
571         IF (P_RA_Invoice_Num is null) THEN
572           X_Error_Message_Code := 'PA_IN_ENT_INV_NUMBER';
573           GOTO all_done;
574         END IF;
575 
576         /* Check for RA invoice number numeric */
577         IF (l_num_type = 'NUMERIC') THEN
578           BEGIN
579             select to_number(P_RA_Invoice_Num)
580               into l_dummy
581               from dual;
582           EXCEPTION
583              WHEN INVALID_NUMBER THEN
584                 X_Error_Message_Code := 'PA_IN_ENT_NUM_INV_NUMBER';
585                 GOTO all_done;
586              WHEN OTHERS THEN
587                RAISE;
588           END;
589         END IF;
590       END IF;  /* end of checks for mannual numbering type */
591 
592       IF  (P_Validation_Level IN ('R','F_INV_DT'))
593       THEN
594        /* Inv date should be entered */
595        IF (P_RA_Invoice_Date is NULL) THEN
596          X_Error_Message_Code := 'PA_IN_ENT_INV_DATE';
597          GOTO all_done;
598        END IF;
599 
600        /* Crediting Inv Date should be greater than Inv date */
601        l_dummy := 0;
602        SELECT COUNT(*)
603          INTO l_dummy
604         FROM pa_draft_invoices_all cm, pa_draft_invoices_all i
605        WHERE cm.project_id = P_Project_ID
606          AND cm.draft_invoice_num = P_Draft_Invoice_Num
607          AND cm.project_id = i.project_id
608          AND i.draft_invoice_num = cm.draft_invoice_num_credited
609          AND i.invoice_date > P_RA_Invoice_Date;
610 
611        IF (l_dummy > 0) THEN
612          X_Error_Message_Code := 'PA_IN_CM_INV_DATE';
613          GOTO all_done;
614        END IF;
615        /* Call to procedure to validate Credit Memo Reason :Enhancement bug 2728431*/
616        IF  (P_Validation_Level ='R') THEN
617 
618            Validate_Credit_Memo_Reason(P_Project_ID,P_Draft_Invoice_Num,P_RA_Invoice_Date,
619     	                               P_Credit_Memo_Reason_Code,l_Error_Message_Code);
620 
621           IF (l_Error_Message_Code IS NOT NULL) THEN
622             X_Error_Message_Code := l_Error_Message_Code;
623             GOTO all_done;
624           END IF;
625        END IF;
626      END IF;/* End Checking based on Record Level or Item level */
627     ELSIF P_Validation_Level = 'C' THEN      /* Commit Level Validation */
628 
629        /* Check lower Invoice numbers have been released */
630        l_dummy := 0;
631        SELECT count(*)
632          INTO l_dummy
633          FROM pa_draft_invoices_all
634         WHERE project_id = P_Project_ID
635           AND draft_invoice_num < P_Draft_Invoice_Num
636           AND released_date is null
637           AND nvl(generation_error_flag, 'N') = 'N';
638 
639        IF (l_dummy > 0) THEN
640           X_Error_Message_Code := 'PA_UNREL_INVOICES_EXIST';
641           GOTO all_done;
642        END IF;
643 
644        IF (l_entry_method = 'AUTOMATIC') THEN
645         /* Added for bug 5924290 to get the invoice status. If released then 1 else 0 */
646         begin
647         SELECT 1
648         into l_dummy
649         FROM PA_DRAFT_INVOICES_ALL
650         WHERE PROJECT_ID =P_Project_ID
651         AND DRAFT_INVOICE_NUM = P_Draft_Invoice_Num
652         AND RELEASED_DATE IS NOT NULL;
653         exception
654         when others
655         then
656         l_dummy := 0;
657         end;
658 
659 /* Added if condition for bug 5924290. If released then no need to call PA_UTILS_SQNUM_PKG.get_unique_invoice_num
660    to increment the auto number. */
661          IF l_dummy = 0 THEN
662          PA_UTILS_SQNUM_PKG.get_unique_invoice_num(l_invoice_category,
663                            P_User_ID ,l_RA_Invoice_Num , l_status);
664          END IF;
665        ELSE
666          /* RA Inv Number is entered (Mannual Method). Check Unique */
667          l_RA_Invoice_Num := P_RA_Invoice_Num;
668 
669          l_dummy := 0;
670          SELECT count(*)
671            INTO l_dummy
672            FROM pa_draft_invoices i,
673                 pa_projects  p,
674                 pa_project_types pt,
675                 pa_agreements_all AGREE, /* fix bug 2082864 for MCB2 */
676                 pa_project_customers PROJCUST
677           WHERE i.ra_invoice_number      = l_RA_Invoice_Num
678             AND NOT EXISTS ( SELECT 'x'
679                                FROM pa_draft_invoices x
680                               WHERE x.project_id = P_Project_ID
681                                 AND x.draft_invoice_num = P_Draft_Invoice_Num
682                                 AND x.project_id = i.project_id
683                                 AND x.draft_invoice_num = i.draft_invoice_num)
684             AND i.project_id = p.project_id
685             AND pt.project_type = p.project_type
686             AND AGREE.agreement_id = i.agreement_id
687             AND PROJCUST.customer_id = AGREE.customer_id
688             AND projcust.project_id = p.project_id   /* added for bug#2634995 */
689             AND decode(nvl(pt.cc_prvdr_flag,'N'),
690                               'Y', 'INTERNAL-INVOICE',
691                               decode(nvl(PROJCUST.bill_another_project_flag,'N'),
692                                      'Y', 'INTERNAL-INVOICE',
693                                      'EXTERNAL-INVOICE'))
694                  = l_invoice_category;
695 
696 
697           IF (l_dummy > 0 ) THEN
698             X_Error_Message_Code := 'PA_IN_RA_INV_NUMBER_NOT_UNIQUE';
699             GOTO all_done;
700           END IF;
701 
702        END IF;
703 
704           X_Ra_Invoice_Num := l_RA_Invoice_Num;
705        /* Call to procedure to validate Credit Memo Reason :Enhancement bug 2728431*/
706        Validate_Credit_Memo_Reason(P_Project_ID,P_Draft_Invoice_Num,P_RA_Invoice_Date,
707 	                          P_Credit_Memo_Reason_Code,l_Error_Message_Code);
708 
709        IF (l_Error_Message_Code IS NOT NULL) THEN
710           X_Error_Message_Code := l_Error_Message_Code;
711           GOTO all_done;
712        END IF;
713 
714        /*  Start of Bug 3344912 - Check if lower invoices have Generation Error */
715        l_dummy := 0;
716 
717        SELECT count(*)
718          INTO l_dummy
719          FROM pa_draft_invoices_all
720         WHERE project_id = P_Project_ID
721           AND draft_invoice_num < P_Draft_Invoice_Num
722           AND released_date is null
723           AND nvl(generation_error_flag, 'N') = 'Y';
724 
725        IF (l_dummy > 0) THEN
726           X_Error_Message_Code := 'PA_GEN_ERR_INV_EXIST';
727           GOTO all_done;
728        END IF;
729        /* End of Bug 3344912 */
730 
731     END IF; /* Validate Level Checks */
732 
733     <<all_done>>
734       NULL;
735 
736   EXCEPTION
737     WHEN OTHERS THEN
738         /* ATG Changes */
739             P_Credit_Memo_Reason_Code := l_Credit_Memo_Reason_Code ;
740             X_RA_Invoice_Num  := null;
741 
742         RAISE;
743   END Validate_Release;
744 
745 /* Overloaded procedure validate_release for credit memo reason */
746   Procedure Validate_Release  ( P_Project_ID              in  number,
747                                 P_Draft_Invoice_Num       in  number,
748                                 P_Validation_Level        in  varchar2,
749                                 P_User_ID                 in  number,
750                                 P_RA_Invoice_Date         in  date,
751                                 P_RA_Invoice_Num          in  varchar2,
752                                 X_RA_Invoice_Num          out NOCOPY varchar2, --File.Sql.39 bug 4440895
753                                 X_Error_Message_Code      out NOCOPY varchar2) is --File.Sql.39 bug 4440895
754 
755 new_excp        exception;
756 BEGIN
757 Raise new_excp;
758 END Validate_Release ;
759 
760 
761 /*----------------------------------------------------------------------------+
762  |      For Details/Comments Refer Package Specification Comments             |
763  +----------------------------------------------------------------------------*/
764   Procedure validate_multi_Customer ( P_Invoice_Set_ID     in  number,
765                                       X_Error_Message_Code out NOCOPY varchar2) is --File.Sql.39 bug 4440895
766     l_dummy number;
767   BEGIN
768 
769     X_Error_Message_Code := NULL;
770     l_dummy := 0;
771 
772     SELECT count(*)
773       INTO l_dummy
774       FROM PA_Draft_Invoices_ALL i
775      WHERE i.invoice_set_id    = P_Invoice_Set_ID
776        AND i.customer_bill_split not in (0, 100)
777        AND (   (    (i.approved_date is not null)
778                 AND EXISTS ( SELECT 'APPROVED ERROR'
779                                FROM pa_draft_invoices ia
780                                WHERE ia.project_id = i.project_id
781                                  AND ia.invoice_set_id = i.invoice_set_id
782                                  AND ia.approved_date is null))
783             OR (    (i.released_date is not null)
784                 AND EXISTS ( SELECT 'RELEASED ERROR'
785                                FROM pa_draft_invoices ir
786                                WHERE ir.project_id = i.project_id
787                                  AND ir.invoice_set_id = i.invoice_set_id
788                                  AND ir.released_date is null)));
789 
790     IF (l_dummy > 0) THEN
791       X_Error_Message_Code := 'PA_REL_ALL_DR_INV';
792     END IF;
793 
794   EXCEPTION
795     WHEN OTHERS THEN
796       RAISE;
797   END validate_multi_Customer;
798 
799 
800 /*----------------------------------------------------------------------------+
801  |      For Details/Comments Refer Package Specification Comments             |
802  +----------------------------------------------------------------------------*/
803   Procedure Post_Update_Release ( P_Project_ID         in  number,
804                                   P_Draft_Invoice_Num  in  number,
805                                   P_User_ID            in  number,
806                                   P_Employee_ID        in  number) is
807 
808 
809 /* Commented for bug 3088395 */ /* The following SQL statement was uncommented for bug 3872496 */
810     CURSOR EI_BILL_HOLD_CUR IS
811        SELECT ei.expenditure_item_id
812          FROM pa_expenditure_items_all ei, pa_tasks t
813         WHERE ei.bill_hold_flag = 'O'
814           AND ei.task_id = t.task_id
815           AND t.project_id = P_Project_ID;
816 
817 
818 /* The following SQL statement was commented for bug 3872496 */
819 /*Added for bug 3088395
820     CURSOR EI_BILL_HOLD_CUR IS
821        SELECT ei.expenditure_item_id
822          FROM pa_expenditure_items_all ei
823         WHERE ei.bill_hold_flag = 'O'      /*Bill Hold Once
824           AND ei.project_id = P_Project_ID;
825 */
826 
827 
828     l_outcome          varchar2(100);
829     l_num_processed    number;
830     l_num_rejected     number;
831     l_dummy            number;
832     l_msg_application  VARCHAR2(30) :='PA';
833     l_msg_type         VARCHAR2(1) := 'E';
834     l_msg_token1       Varchar2(240) := '';
835     l_msg_token2       Varchar2(240) :='';
836     l_msg_token3       Varchar2(240) :='';
837     l_msg_count        Number ;
838 
839 
840   BEGIN
841 
842     /* Releasing bill event based revenue */
843     UPDATE pa_draft_revenues dr
844     SET    dr.last_update_date      = sysdate,
845            dr.last_updated_by       = P_User_ID,
846            dr.released_date         = sysdate,
847            dr.last_update_login     = P_Employee_ID
848     WHERE  dr.project_id            = P_Project_ID
849     AND    dr.generation_error_flag = 'N'
850     AND    dr.released_date        IS  NULL
851     AND    dr.draft_revenue_num <=
852               (SELECT max(rdl.draft_revenue_num)
853                FROM   pa_cust_event_rev_dist_lines rdl
854                WHERE  rdl.project_id             = P_Project_ID
855                AND    rdl.draft_invoice_num      = P_Draft_Invoice_Num);
856 
857 
858 /* Releasing Revenue based on Automatic Events which have both revenue and
859    invoice amounts -For bug 5401384 - base bug 5246804*/
860 
861  UPDATE pa_draft_revenues dr
862     SET    dr.last_update_date      = sysdate,
863            dr.last_updated_by       = P_User_ID,
864            dr.released_date         = sysdate,
865            dr.last_update_login     = P_Employee_ID
866     WHERE  dr.project_id            = P_Project_ID
867     AND    dr.generation_error_flag = 'N'
868     AND    dr.released_date        IS  NULL
869     AND    dr.draft_revenue_num <=
870               (SELECT max(rdl.draft_revenue_num)
871                FROM   pa_cust_event_rev_dist_lines rdl
872                WHERE  rdl.project_id             = P_Project_ID
873                and    exists /* check if the event is an automatic event */
874                       (select 1
875                        from pa_events e, pa_event_types et
876                        where e.project_id = rdl.project_id
877                        and e.event_num = rdl.event_num
878                        and nvl(e.task_id,-99) = nvl(rdl.task_id,-99)
879                        and e.event_type = et.event_type
880                        and et.event_type_classification = 'AUTOMATIC')
881                AND    exists /* check if the invoice released is related to this automatic event */
882                       (select 1
883                        from pa_draft_invoice_items dii
884                        where dii.project_id = rdl.project_id
885 		       and dii.draft_invoice_num = P_Draft_Invoice_Num
886                        and dii.event_num is not null
887                        and dii.event_num = rdl.event_num
888                        and nvl(dii.event_task_id, -99) = nvl(rdl.task_id, -99)));
889 
890 /* End of Changes for bug 5401384 - Base Bug 5246804 */
891 
892 
893     /* Releasing Expenditure item based revenue */
894     UPDATE pa_draft_revenues dr
895     SET    dr.last_update_date      =  sysdate,
896            dr.last_updated_by       =  P_User_ID,
897            dr.released_date         =  sysdate,
898            dr.last_update_login     =  P_Employee_ID
899     WHERE  dr.project_id            =  P_Project_ID
900     AND    dr.generation_error_flag = 'N'
901     AND    dr.released_date        IS  NULL
902     AND    dr.draft_revenue_num <=
903                 /* Commented code fix for bug 2968645
904               (SELECT max(rdl.draft_revenue_num)
905                FROM   pa_cust_rev_dist_lines rdl
906                WHERE  rdl.project_id             = P_Project_ID
907                AND    rdl.draft_invoice_num      = P_Draft_Invoice_Num); */
908                /* Bug fix for bug 2968645 Starts here */
909                (SELECT max(rdl1.draft_revenue_num)
910                FROM   pa_cust_rev_dist_lines rdl1
911                WHERE  rdl1. expenditure_item_id in
912                                 (       SELECT  expenditure_item_id
913                                         FROM    pa_cust_rev_dist_lines rdl2
914                                         WHERE   rdl2.project_id = P_Project_ID
915                                         AND     rdl2.draft_invoice_num = P_Draft_Invoice_Num));
916                /* Bug fix for bug 2968645 Ends here */
917 
918 
919 
920     /* Release One Time EI BILL Holds */
921     FOR EI_BILL_HOLD_REC in EI_BILL_HOLD_CUR
922     LOOP
923       pa_adjustments.adjust (X_adj_action          => 'BILLING HOLD RELEASE',
924                              X_module              => 'PAXINADI',
925                              X_user                => P_User_ID,
926                              X_login               => P_Employee_ID,
927                              X_project_id          => P_Project_ID,
928                              X_adjust_level        => 'I',    -- item level
929                              X_expenditure_item_id =>
930                                           EI_BILL_HOLD_REC.expenditure_item_id,
931                              X_outcome             => l_outcome,
932                              X_num_processed       => l_num_processed,
933                              X_num_rejected        => l_num_rejected,
934                              X_msg_application     => l_msg_application,
935                              X_msg_type            => l_msg_type,
936                              X_msg_token1          => l_msg_token1,
937                              X_msg_token2          => l_msg_token2,
938                              X_msg_token3          => l_msg_token3,
939                              X_msg_count           => l_msg_count );
940 
941     END LOOP;
942 
943     /* Release One Time Event BILL Holds */
944     UPDATE pa_events
945       SET bill_hold_flag    = 'N',
946           last_update_date  = sysdate,
947           last_updated_by   = P_User_ID,
948           last_update_login = P_Employee_ID
949     WHERE project_id = P_Project_ID
950       AND bill_hold_flag || '' = 'O';
951 
952   EXCEPTION
953     WHEN OTHERS THEN
954       RAISE;
955   END Post_Update_Release;
956 
957 /*----------------------------------------------------------------------------+
958  |      For Details/Comments Refer Package Specification Comments             |
959  +----------------------------------------------------------------------------*/
960   Procedure Client_Extn_Driver( P_Request_ID         in  number,
961                                 P_User_ID            in  number,
962                                 P_Calling_Place      in  varchar2,
963                                 P_Project_ID         in  number ) is
964 
965     l_employee_id        number;
966 
967     l_project_id         number;
968     l_prv_project_id     number;
969     l_draft_invoice_num  number;
970     l_invoice_set_id     number;
971     l_prv_invoice_set_id number;
972     l_tmp_invoice_set_id number;
973     l_invoice_class      varchar2(15);
974     l_action_flag        varchar2(1);
975     l_err_msg_code       varchar2(30);
976     l_status             number;
977     l_dummy              number;
978     l_invoice_amount     number;
979     l_project_amount     number;
980     l_inv_currency_code  varchar2(15);
981     l_project_currency_code  varchar2(15);
982 
983     l_ra_invoice_num     varchar2(20);
984     l_tmp_ra_invoice_num varchar2(20);
985     l_ra_invoice_date    date;
986     l_Credit_memo_reason_code pa_draft_invoices_all.credit_memo_reason_Code%TYPE;
987 
988     /* Cursor for Select All Unapproved invoices created in This Run */
989     CURSOR UNAPP_INV_CUR is
990       SELECT i.project_id,
991              nvl(i.invoice_set_id, 0),
992              i.draft_invoice_num,
993              decode(P_Calling_Place, 'INV_CR_MEMO',
994                 decode(i.draft_invoice_num_credited, NULL, 'INVOICE',
995                         'CREDIT_MEMO'), P_Calling_Place) invoice_class,
996              sum(ii.amount),
997              p.project_currency_code,
998              i.inv_currency_code,
999              sum(ii.inv_amount)
1000         FROM pa_projects p,
1001              pa_draft_invoices i,
1002              pa_draft_invoice_items ii
1003        WHERE p.project_id = i.project_id
1004          AND i.project_id = ii.project_id
1005          AND i.draft_invoice_num = ii.draft_invoice_num
1006          AND i.request_id = P_Request_ID
1007          AND i.approved_date is null
1008          AND nvl(i.generation_error_flag, 'N') = 'N'
1009          AND (i.project_id+0 = P_Project_ID or P_Project_ID is NULL)
1010     GROUP BY i.project_id,
1011              nvl(i.invoice_set_id, 0),
1012              i.draft_invoice_num,
1013              decode(P_Calling_Place, 'INV_CR_MEMO',
1014                 decode(i.draft_invoice_num_credited, NULL, 'INVOICE',
1015                         'CREDIT_MEMO'), P_Calling_Place),
1016              p.project_currency_code,
1017              i.inv_currency_code
1018     ORDER BY i.project_id, i.draft_invoice_num; /*Added order by clause for bug 6009706 */
1019 
1020 
1021     /* Cursor for Select All Unreleased invoices created in This Run */
1022     CURSOR UNREL_INV_CUR is
1023       SELECT i.project_id,
1024              nvl(i.invoice_set_id, 0),
1025              i.draft_invoice_num,
1026              decode(P_Calling_Place, 'INV_CR_MEMO',
1027                 decode(i.draft_invoice_num_credited, NULL, 'INVOICE',
1028                         'CREDIT_MEMO'), P_Calling_Place) invoice_class,
1029              sum(ii.amount),
1030              p.project_currency_code,
1031              i.inv_currency_code,
1032              sum(ii.inv_amount)
1033         FROM pa_projects p,
1034              pa_draft_invoices i,
1035              pa_draft_invoice_items ii
1036        WHERE p.project_id = i.project_id
1037          AND i.project_id = ii.project_id
1038          AND i.draft_invoice_num = ii.draft_invoice_num
1039          AND i.request_id = P_Request_ID
1040          AND i.approved_date is not null
1041          AND i.released_date is null   /* For bug 2863710 */
1042          AND nvl(i.generation_error_flag, 'N') = 'N'
1043          AND (i.project_id+0 = P_Project_ID or P_Project_ID is NULL)
1044     GROUP BY i.project_id,
1045              nvl(i.invoice_set_id, 0),
1046              i.draft_invoice_num,
1047              decode(P_Calling_Place, 'INV_CR_MEMO',
1048                 decode(i.draft_invoice_num_credited, NULL, 'INVOICE',
1049                         'CREDIT_MEMO'), P_Calling_Place),
1050              p.project_currency_code,
1051              i.inv_currency_code
1052     ORDER BY i.project_id, i.draft_invoice_num; /*Added order by clause for bug 6009706 */
1053 
1054 
1055     /* Cursor for Select All invoices Released in This Run */
1056     CURSOR RELEASED_INV_CUR is
1057       SELECT i.project_id,
1058              i.draft_invoice_num
1059         FROM pa_draft_invoices i
1060        WHERE i.request_id = P_Request_ID
1061          AND i.released_date is not null;
1062 
1063   BEGIN
1064 
1065     /*------------------------------------------------------------------+
1066      |    Get Employee ID corresponding to User ID                      |
1067      +------------------------------------------------------------------*/
1068      BEGIN
1069 /* nvl added for the resolution of the bug 1510535 */
1070        SELECT nvl(Employee_ID,0)
1071          INTO l_employee_id
1072          FROM FND_USER
1073         WHERE User_ID = P_User_ID;
1074 
1075      EXCEPTION
1076        WHEN NO_DATA_FOUND THEN
1077          l_employee_id := 0;
1078      END;
1079 
1080 
1081     /*------------------------------------------------------------------+
1082      |    Select The Invoices that were created in this run             |
1083      |    For a single run of generate Draft invoice program this API   |
1084      |    will be called once for Invoice/Credit Memo, Write Off or     |
1085      |    Cancellation of an invoice.                                   |
1086      +------------------------------------------------------------------*/
1087 
1088     /*------------------------------------------------------------------+
1089      |    Select UnApproved Invoices that were Created in this run      |
1090      +------------------------------------------------------------------*/
1091 
1092     -- Initialize Local Variables
1093     l_prv_project_id := 0;
1094     l_prv_invoice_set_id := 0;
1095     l_tmp_invoice_set_id := 0;
1096 
1097     OPEN UNAPP_INV_CUR;
1098 
1099     LOOP
1100       FETCH UNAPP_INV_CUR into l_project_id, l_invoice_set_id,
1101                              l_draft_invoice_num,
1102                              l_invoice_class,
1103                              l_project_amount,
1104                              l_project_currency_code,
1105                              l_inv_currency_code,
1106                              l_invoice_amount;
1107 
1108       EXIT WHEN UNAPP_INV_CUR%NOTFOUND;
1109 
1110       l_tmp_invoice_set_id := l_invoice_set_id;
1111 
1112       /* Lock The Project */
1113       IF (l_project_id <> l_prv_project_id) THEN
1114          SELECT Project_ID
1115            INTO l_dummy
1116            FROM PA_Projects_ALL
1117           WHERE Project_ID = l_project_id
1118          FOR UPDATE OF LAST_UPDATE_DATE;
1119 
1120          l_prv_project_id := l_project_id;
1121 
1122       END IF;
1123 
1124       -- Initialize Output Variables
1125       l_action_flag     := NULL;
1126       l_status          := NULL;
1127 
1128       PA_Client_Extn_Inv_Actions.Approve_Invoice( l_project_id,
1129                                                   l_draft_invoice_num,
1130                                                   l_invoice_class,
1131                                                   l_project_amount,
1132                                                   l_project_currency_code,
1133                                                   l_inv_currency_code,
1134                                                   l_invoice_amount,
1135                                                   l_action_flag,
1136                                                   l_Status);
1137 
1138       /* Check Extension Application Error */
1139       IF l_Status > 0 THEN
1140          Insert_Distrbution_Warning ( l_Project_ID, l_draft_invoice_num,
1141                                       P_User_ID, P_Request_ID, NULL,
1142                                       'PA_CLIENT_EXTN_APP_ERROR');
1143          GOTO FETCH_NEXT_UNAPP_REC;
1144       END IF;
1145 
1146       /* Check Extension Oracle Error */
1147       IF l_Status < 0 THEN
1148          Insert_Distrbution_Warning ( l_Project_ID, l_draft_invoice_num,
1149                                       P_User_ID, P_Request_ID, NULL,
1150                                       'PA_CLIENT_EXTN_ORACLE_ERROR');
1151          GOTO FETCH_NEXT_UNAPP_REC;
1152       END IF;
1153 
1154       /* At This Point Approval Billing Extension has returned success */
1155       IF (nvl(l_action_flag, 'N') = 'Y') THEN
1156         l_err_msg_code := NULL;
1157         /* Record Level Validations */
1158         PA_Invoice_Actions.Validate_Approval( l_Project_ID,
1159                                               l_draft_invoice_num, 'R',
1160                                               l_err_msg_code);
1161         IF l_err_msg_code is null THEN
1162           /* Commit Level Validations */
1163           PA_Invoice_Actions.Validate_Approval( l_Project_ID,
1164                                                 l_draft_invoice_num, 'C',
1165                                                 l_err_msg_code);
1166         END IF;
1167 
1168         IF l_err_msg_code is null THEN
1169           /* Approve Invoices */
1170           Update_Approve_Invoices( l_Project_ID, l_draft_invoice_num,
1171                                    P_User_ID, l_employee_id);
1172         ELSE
1173           Insert_Distrbution_Warning ( l_Project_ID, l_draft_invoice_num,
1174                                        P_User_ID, P_Request_ID, NULL,
1175                                        l_err_msg_code);
1176          GOTO FETCH_NEXT_UNAPP_REC;
1177 
1178         END IF;
1179 
1180       END IF;
1181 
1182       <<FETCH_NEXT_UNAPP_REC>>
1183 
1184       /* Check for Multiple Customers */
1185       IF ((l_invoice_set_id     <> l_prv_invoice_set_id) AND
1186           (l_invoice_set_id     <> 0)                    AND
1187           (l_prv_invoice_set_id <> 0))                   THEN
1188 
1189          PA_Invoice_Actions.Validate_Multi_Customer (l_prv_invoice_set_id,
1190                                                      l_err_msg_code);
1191 
1192          IF l_err_msg_code is not null THEN
1193            Insert_Distrbution_Warning ( NULL, NULL, P_User_ID, P_Request_ID,
1194                                         l_prv_invoice_set_id, l_err_msg_code);
1195            Update_Unapprove_Invoices ( l_prv_invoice_set_id, P_User_ID);
1196          END IF;
1197 
1198          l_prv_invoice_set_id := l_invoice_set_id;
1199 
1200       END IF;
1201 
1202 
1203     END LOOP;
1204 
1205     IF ( l_tmp_invoice_set_id <> 0) THEN
1206 
1207        PA_Invoice_Actions.Validate_Multi_Customer (l_invoice_set_id,
1208                                                    l_err_msg_code);
1209 
1210        IF l_err_msg_code is not null THEN
1211          Insert_Distrbution_Warning ( NULL, NULL, P_User_ID, P_Request_ID,
1212                                       l_invoice_set_id, l_err_msg_code);
1213          Update_Unapprove_Invoices ( l_invoice_set_id, P_User_ID);
1214        END IF;
1215     END IF;
1216 
1217     CLOSE UNAPP_INV_CUR;
1218 
1219     COMMIT;
1220 
1221 
1222     /*------------------------------------------------------------------+
1223      |    Select UnReleased Invoices that were Created in this run      |
1224      +------------------------------------------------------------------*/
1225 
1226     -- Initialize Local Variables
1227     l_prv_project_id := 0;
1228     l_prv_invoice_set_id := 0;
1229     l_tmp_invoice_set_id := 0;
1230 
1231     OPEN UNREL_INV_CUR;
1232 
1233     LOOP
1234       FETCH UNREL_INV_CUR into l_project_id, l_invoice_set_id,
1235                              l_draft_invoice_num,
1236                              l_invoice_class,
1237                              l_project_amount,
1238                              l_project_currency_code,
1239                              l_inv_currency_code,
1240                              l_invoice_amount;
1241 
1242       EXIT WHEN UNREL_INV_CUR%NOTFOUND;
1243 
1244       l_tmp_invoice_set_id := l_invoice_set_id;
1245 
1246       /* Lock The Project */
1247       IF (l_project_id <> l_prv_project_id) THEN
1248          SELECT Project_ID
1249            INTO l_dummy
1250            FROM PA_Projects_ALL
1251           WHERE Project_ID = l_project_id
1252          FOR UPDATE OF LAST_UPDATE_DATE;
1253 
1254          l_prv_project_id := l_project_id;
1255 
1256       END IF;
1257 
1258 
1259       -- Initialize Output and temporary Variables
1260       l_action_flag             := NULL;
1261       l_ra_invoice_date         := NULL;
1262       l_ra_invoice_num          := NULL;
1263       l_tmp_ra_invoice_num      := NULL;
1264       l_status                  := NULL;
1265       l_Credit_memo_reason_code := NULL;
1266 
1267 
1268       PA_Client_Extn_Inv_Actions.Release_Invoice( l_project_id,
1269                                                   l_draft_invoice_num,
1270                                                   l_invoice_class,
1271                                                   l_project_amount,
1272                                                   l_project_currency_code,
1273                                                   l_inv_currency_code,
1274                                                   l_invoice_amount,
1275                                                   l_action_flag,
1276                                                   l_ra_invoice_date,
1277                                                   l_ra_invoice_num,
1278                                                   l_Status,
1279                                                   l_Credit_memo_reason_code);
1280 
1281       /* Check Extension Application Error */
1282       IF l_Status > 0 THEN
1283          Insert_Distrbution_Warning ( l_Project_ID, l_draft_invoice_num,
1284                                       P_User_ID, P_Request_ID, NULL,
1285                                       'PA_CLIENT_EXTN_APP_ERROR');
1286          GOTO FETCH_NEXT_UNREL_REC;
1287       END IF;
1288 
1289       /* Check Extension Oracle Error */
1290       IF l_Status < 0 THEN
1291          Insert_Distrbution_Warning ( l_Project_ID, l_draft_invoice_num,
1292                                       P_User_ID, P_Request_ID, NULL,
1293                                       'PA_CLIENT_EXTN_ORACLE_ERROR');
1294          GOTO FETCH_NEXT_UNREL_REC;
1295       END IF;
1296 
1297       /* At This Point Release  Billing Extension has returned success */
1298       IF (nvl(l_action_flag, 'N') = 'Y') THEN
1299         l_err_msg_code := NULL;
1300         /* Record Level Validations */
1301         PA_Invoice_Actions.Validate_Release ( l_Project_ID,
1302                                               l_draft_invoice_num, 'R',
1303                                               P_User_ID, l_ra_invoice_date,
1304                                               l_ra_invoice_num,
1305                                               l_Credit_memo_reason_code,
1306                                               l_tmp_ra_invoice_num,
1307                                               l_err_msg_code);
1308         IF l_err_msg_code is null THEN
1309           /* Commit Level Validations */
1310           PA_Invoice_Actions.Validate_Release ( l_Project_ID,
1311                                                 l_draft_invoice_num, 'C',
1312                                                 P_User_ID, l_ra_invoice_date,
1313                                                 l_ra_invoice_num,
1314                                                 l_Credit_memo_reason_code,
1315                                                 l_tmp_ra_invoice_num,
1316                                                 l_err_msg_code);
1317         END IF;
1318 
1319         IF l_err_msg_code is null THEN
1320           /* Release Invoices */
1321           l_ra_invoice_num := l_tmp_ra_invoice_num;
1322           Update_Release_Invoices( l_Project_ID, l_draft_invoice_num,
1323                                    l_ra_invoice_date, l_ra_invoice_num,
1324                                    P_User_ID, l_employee_id,l_Credit_memo_reason_code);
1325         ELSE
1326           Insert_Distrbution_Warning ( l_Project_ID, l_draft_invoice_num,
1327                                        P_User_ID, P_Request_ID, NULL,
1328                                        l_err_msg_code);
1329          GOTO FETCH_NEXT_UNREL_REC;
1330 
1331         END IF;
1332 
1333       END IF;
1334 
1335       <<FETCH_NEXT_UNREL_REC>>
1336 
1337       /* Check for Multiple Customers */
1338       IF ((l_invoice_set_id     <> l_prv_invoice_set_id) AND
1339           (l_invoice_set_id     <> 0)                    AND
1340           (l_prv_invoice_set_id <> 0))                   THEN
1341 
1342          PA_Invoice_Actions.Validate_Multi_Customer (l_prv_invoice_set_id,
1343                                                      l_err_msg_code);
1344 
1345          IF l_err_msg_code is not null THEN
1346            Insert_Distrbution_Warning ( NULL, NULL, P_User_ID, P_Request_ID,
1347                                         l_prv_invoice_set_id, l_err_msg_code);
1348            Update_Unrelease_Invoices ( l_prv_invoice_set_id, P_User_ID);
1349          END IF;
1350 
1351          l_prv_invoice_set_id := l_invoice_set_id;
1352 
1353       END IF;
1354 
1355     END LOOP;
1356 
1357     IF ( l_tmp_invoice_set_id <> 0) THEN
1358 
1359        PA_Invoice_Actions.Validate_Multi_Customer (l_invoice_set_id,
1360                                                    l_err_msg_code);
1361 
1362        IF l_err_msg_code is not null THEN
1363          Insert_Distrbution_Warning ( NULL, NULL, P_User_ID, P_Request_ID,
1364                                       l_invoice_set_id, l_err_msg_code);
1365          Update_Unrelease_Invoices ( l_invoice_set_id, P_User_ID);
1366        END IF;
1367     END IF;
1368 
1369     CLOSE UNREL_INV_CUR;
1370 
1371     /* Do the Post Release update for all the released Records */
1372     FOR CUR_REC in RELEASED_INV_CUR
1373     LOOP
1374       PA_Invoice_Actions.Post_Update_Release(CUR_REC.Project_ID,
1375                                              CUR_REC.Draft_Invoice_Num,
1376                                              P_User_ID,
1377                                              l_employee_id);
1378     END LOOP;
1379 
1380     COMMIT;
1381 
1382 
1383   EXCEPTION
1384     WHEN OTHERS THEN
1385         RAISE;
1386   END Client_Extn_Driver;
1387 
1388   /* Begin Concession invoice modification */
1389 
1390   /*-----------------------------------------------------------------------------------------+
1391    |   Procedure  :   check_concurrency_issue                                                |
1392    |   Purpose    :   To ensure that no two users do credit processing on the same draft     |
1393    |                  at the same time                                                       |
1394    |   Parameters :                                                                          |
1395    |     ==================================================================================  |
1396    |     Name                             Mode    Description                                |
1397    |     ==================================================================================  |
1398    |     p_project_id          IN      Project ID                                            |
1399    |     p_draft_invoice_num   IN      Draft invoice for which credit action is to be done   |
1400    |     p_rec_version_number  IN      Record version number of the draft invoice as         |
1401    |                                   retrieved by the user
1402    |     x_return_status       OUT     Return status of this procedure                       |
1403    |     x_msg_count           OUT     Error message count                                   |
1404    |     x_msg_data            OUT     Error message                                         |
1405    |     ==================================================================================  |
1406    +----------------------------------------------------------------------------------------*/
1407   Procedure check_concurrency_issue (
1408              p_project_id             IN NUMBER,
1409              p_draft_invoice_num      IN NUMBER,
1410              p_rec_version_number  IN NUMBER,
1411              x_return_status          OUT   NOCOPY VARCHAR2,
1412              x_msg_count              OUT   NOCOPY NUMBER,
1413              x_msg_data               OUT   NOCOPY VARCHAR2) IS
1414 
1415 
1416          l_return_status            VARCHAR2(30) := NULL;
1417          l_msg_count                NUMBER       := NULL;
1418          l_msg_data                 VARCHAR2(250) := NULL;
1419 
1420          l_record_version_number	NUMBER;
1421          l_cnt_recs	                NUMBER;
1422 
1423          l_last_credit_request_id   NUMBER;
1424          l_phase                    varchar2(255);
1425          l_status                   varchar2(255);
1426          l_dev_phase                varchar2(255);
1427          l_dev_status               varchar2(255);
1428          l_message                  varchar2(255);
1429 
1430 
1431   BEGIN
1432 
1433       x_return_status    := FND_API.G_RET_STS_SUCCESS;
1434       x_msg_count        := 0;
1435 
1436 
1437       /* Get the current record version number in draft invoice table */
1438 
1439       select record_version_number, last_credit_request_id
1440       into l_record_version_number, l_last_credit_request_id
1441       from pa_draft_invoices
1442       where project_id = p_project_id
1443       and draft_invoice_num = p_draft_invoice_num;
1444 
1445       /* Check that it matches the one passed by the calling process */
1446 
1447       if  (nvl(p_rec_version_number,0) <> nvl(l_record_version_number,0)) then
1448 	  l_return_status := FND_API.G_RET_STS_ERROR;
1449 	  l_msg_data := 'PA_REC_ALREADY_UPDATED';
1450 	  /*  This means that another session has updated the record_version_number and fired
1451 	      the concurrent request for invoice processing since the start of the current session.
1452 		  Hence the current session needs to rollback and restart in order to include the changes
1453 		  from the other session.
1454        */
1455           rollback;
1456 	  RAISE FND_API.G_EXC_ERROR;
1457       End if;
1458 
1459       /* Check the last request identifier that was run for crediting the current invoice
1460 	     and get the status of the last run
1461        */
1462 
1463          if (l_last_credit_request_id is not null) then
1464 
1465 		 /* The status needs to be checked only if there was a last run
1466 		  */
1467 
1468             if (FND_CONCURRENT.GET_REQUEST_STATUS
1469                 (
1470                   l_last_credit_request_id,
1471                   null,  --  pa_schema_name
1472                   null,  --  request_name
1473                   l_phase,
1474                   l_status,
1475                   l_dev_phase,
1476                   l_dev_status,
1477                   l_message
1478                 )) then
1479               null;
1480             end if;
1481         /* For reference the possible combinations of dev_phase and dev_status
1482 		   for the last run are:
1483 
1484            PENDING  NORMAL
1485                     STANDBY
1486                     SCHEDULED
1487                     PAUSED
1488            RUNNING  NORMAL
1489                     WAITING
1490                     RESUMING
1491                     TERMINATING
1492            COMPLETE NORMAL
1493                     ERROR
1494                     WARNING
1495                     CANCELLED
1496                     TERMINATED
1497            INACTIVE DISABLED
1498                     ON_HOLD
1499                     NO_MANAGER
1500                     SUSPENDED
1501          */
1502 
1503 
1504              if       (l_dev_phase = 'PENDING' or
1505                        l_dev_phase = 'RUNNING' or
1506                        l_dev_phase = 'INACTIVE'
1507                       ) then
1508                       l_return_status := FND_API.G_RET_STS_ERROR;
1509                       l_msg_data := 'PA_CREDIT_IN_PROGRESS';
1510 	  /*  This means that the request for invoice processing fired by another session is still in
1511 	      progress.  Hence the current session needs to rollback and restart after the prior request
1512 		  has been completed, and no more changes are pending from the prior request, in order to
1513 		  include the changes from the other session.
1514        */
1515 	                  ROLLBACK;
1516                       RAISE FND_API.G_EXC_ERROR;
1517              elsif   (l_dev_phase = 'COMPLETE') then
1518                       null;
1519              end if;
1520 
1521          end if; -- (l_last_credit_request_id is not null)
1522 
1523   EXCEPTION
1524 
1525        WHEN FND_API.G_EXC_ERROR THEN
1526              x_return_status := l_return_status;
1527              x_msg_count := l_msg_count;
1528              x_msg_data := l_msg_data;
1529 
1530        WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1531              x_return_status := l_return_status;
1532              x_msg_count := l_msg_count;
1533              x_msg_data := l_msg_data;
1534 
1535        WHEN others then
1536             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1537             x_msg_count := l_msg_count;
1538             x_msg_data := SUBSTR(SQLERRM,1,100);
1539 
1540   END check_concurrency_issue;
1541 
1542   /*----------------------------------------------------------------------------------------------+
1543    |   Procedure  :   validate_invoice_amount                                                     |
1544    |   Purpose    :   To validate the net invoice amount for Write-Off/Concession                 |
1545    |   Parameters :                                                                               |
1546    |     ==================================================================================       |
1547    |     Name                       Mode    Description                                           |
1548    |     ==================================================================================       |
1549    |     p_project_id               IN      Project ID                                            |
1550    |     p_credit_action            IN      Indicates if credit is WRITE-OFF/CONCESSION           |
1551    |     p_credit_action_type       IN      Indicates if credit action type is                    |
1552    |                                        SUMMARY/GROUP/LINES                                   |
1553    |     p_draft_invoice_num        IN      Draft invoice for which credit action is to be done   |
1554    |     p_invoice_amount           IN      Invoice amount of the draft invoice for which credit  |
1555    |                                          action is to be done.                               |
1556    |     p_net_inv_amount           IN      Net invoice amount of the selected lines.             |
1557    |     p_credit_amount            IN      Total entered credit amount.                          |
1558    |     p_balance due              IN      Due amount in AR.                                     |
1559    |     x_tot_credited_amt         OUT     Total credited amount applied on invoice.             |
1560    |     x_return_status            OUT     Return status of this procedure                       |
1561    |     x_msg_count                OUT     Error message count                                   |
1562    |     x_msg_data                 OUT     Error message                                         |
1563    |     ==================================================================================       |
1564    +---------------------------------------------------------------------------------------------*/
1565 
1566   Procedure validate_invoice_amount (
1567              p_project_id             IN NUMBER,
1568              p_credit_action          IN VARCHAR2,
1569              p_credit_action_type     IN VARCHAR2,
1570              p_draft_invoice_num      IN NUMBER,
1571              p_invoice_amount         IN NUMBER,
1572              p_net_inv_amount         IN NUMBER,
1573              p_credit_amount          IN NUMBER,
1574              p_balance_due            IN NUMBER,
1575              x_tot_credited_amt       OUT   NOCOPY NUMBER,
1576              x_return_status          OUT   NOCOPY VARCHAR2,
1577              x_msg_count              OUT   NOCOPY NUMBER,
1578              x_msg_data               OUT   NOCOPY VARCHAR2)   IS
1579 
1580          l_return_status            VARCHAR2(30) := NULL;
1581          l_msg_count                NUMBER       := NULL;
1582          l_msg_data                 VARCHAR2(250) := NULL;
1583 
1584          l_tot_credited_amt         NUMBER ;
1585 
1586     /* Bug 9459594 */
1587     l_intercompany_flag VARCHAR2(1) := 'N';
1588     CURSOR overapplication_csr IS
1589            SELECT NVL(typ.allow_overapplication_flag,'N')
1590            FROM   pa_implementations imp,
1591                   ra_batch_sources bs,
1592                   ra_cust_trx_types typ
1593            WHERE  decode(l_intercompany_flag,'N',imp.invoice_batch_source_id,
1594                          imp.cc_ic_ar_batch_source_id) = bs.batch_source_id
1595            and    bs.default_inv_trx_type = typ.cust_trx_type_id;
1596     l_overapplication_flag            VARCHAR2(1) := 'N';
1597 
1598     CURSOR get_intercompany_flag_csr IS
1599            SELECT NVL(ptype.cc_prvdr_flag, 'N')
1600            FROM   pa_projects proj,
1601                   pa_project_types ptype
1602            WHERE  proj.PROJECT_ID = p_project_id
1603            AND    proj.PROJECT_TYPE = ptype.PROJECT_TYPE;
1604 
1605     CURSOR get_centralized_flag_csr IS
1606            SELECT DECODE(CENTRALIZED_INVOICING_FLAG, 'N', 'Y', 'N')
1607            FROM   PA_IMPLEMENTATIONS;
1608     l_use_inv_org_flag VARCHAR2(1)  := 'N';
1609 
1610     CURSOR get_misc_details_csr IS
1611            SELECT IMP.business_group_id,
1612                   IMP.proj_org_structure_version_id,
1613                   BASELANG.language_code,
1614                   INV.invoice_date,
1615                   PROJ.Carrying_Out_Organization_ID
1616            FROM   pa_implementations IMP,
1617                   fnd_languages BASELANG,
1618                   pa_draft_invoices_all INV,
1619                   pa_projects PROJ
1620            WHERE  INV.project_id = p_project_id
1621            AND    INV.draft_invoice_num = p_draft_invoice_num
1622            AND    BASELANG.installed_flag = 'B'
1623            AND    PROJ.project_id = p_project_id;
1624     l_business_group_id pa_implementations.business_group_id%TYPE;
1625     l_org_st_ver_id pa_implementations.proj_org_structure_version_id%TYPE;
1626     l_base_language fnd_languages.language_code%TYPE;
1627     l_invoice_date  pa_draft_invoices_all.invoice_date%TYPE;
1628     l_carry_out_org_id  pa_projects.Carrying_Out_Organization_ID%TYPE;
1629 
1630     x_trx_type      VARCHAR2(10);
1631     x_cm_trx_type   VARCHAR2(10);
1632     x_error_status  NUMBER;
1633     x_error_message PA_LOOKUPS.DESCRIPTION%TYPE;
1634 
1635     CURSOR overapplication_csr_2 IS
1636            SELECT NVL(typ.allow_overapplication_flag,'N')
1637            FROM   ra_cust_trx_types typ
1638            WHERE  typ.cust_trx_type_id = TO_NUMBER(x_trx_type);
1639 
1640   BEGIN
1641 
1642       x_return_status    := FND_API.G_RET_STS_SUCCESS;
1643       x_msg_count        := 0;
1644       x_tot_credited_amt := 0;
1645 
1646      /* First Check - Check if Invoice Amount is negative.
1647                       Write-Off/Concession cannot be performed when Invoice Amount is negative. */
1648 
1649           IF  sign(p_invoice_amount) <> 1  THEN
1650 
1651                     l_return_status := FND_API.G_RET_STS_ERROR;
1652                     l_msg_data := 'PA_IN_CRD_NOT_POSITIVE';
1653                     l_msg_count := 1;
1654 
1655                     RAISE FND_API.G_EXC_ERROR;
1656 
1657           END IF;
1658 
1659      /* Second Check - Check if net invoice amount of the selected lines is negative.
1660                       Write-Off/Concession cannot be performed when net invoice amount of the
1661                        selected lines is negative. */
1662           IF  (p_credit_action_type in ('GROUP', 'LINE'))THEN
1663               IF sign(p_net_inv_amount) <> 1 THEN
1664 
1665                     l_return_status := FND_API.G_RET_STS_ERROR;
1666                     l_msg_data := 'PA_IN_LINE_CRD_NOT_POSITIVE';
1667                     l_msg_count := 1;
1668 
1669                     RAISE FND_API.G_EXC_ERROR;
1670               END IF;
1671           END IF;
1672 
1673       BEGIN
1674 
1675           /* Get the total credited amount for the selected invoice in Oracle Projects. */
1676 
1677           SELECT ABS(nvl(SUM(nvl(ii.inv_amount,0)),0))
1678           INTO	l_tot_credited_amt
1679           FROM	pa_draft_invoices i,
1680                 pa_draft_invoice_items ii
1681           WHERE	i.project_id = p_project_id
1682           AND	ii.project_id = i.project_id
1683           AND	ii.draft_invoice_num = i.draft_invoice_num
1684           AND   i.draft_invoice_num_credited = p_draft_invoice_num
1685           AND	i.canceled_flag IS NULL
1686           AND	i.generation_error_flag = 'N';
1687 
1688           x_tot_credited_amt := l_tot_credited_amt;
1689 
1690       EXCEPTION
1691 
1692          WHEN NO_DATA_FOUND THEN
1693 
1694               l_tot_credited_amt := 0;
1695 
1696       END;
1697 
1698      /* Third Check - The following check is for over-credit application.  We allow
1699                        over-credit application only for credit action Concession. */
1700 
1701            IF ( p_invoice_amount < (l_tot_credited_amt + p_credit_amount) ) THEN
1702 
1703                /* The IF part is for credit action CONCESSION
1704                   This check is to warn the user that the Credit amount entered is going to result
1705                      to over-credit.  If user chooses to continue, Concession Invoice will get
1706                      processed otherwise no. */
1707 	       IF p_credit_action = 'CONCESSION'  THEN
1708                   /* Bug 9459594 */
1709                   OPEN get_intercompany_flag_csr;
1710                   FETCH get_intercompany_flag_csr
1711                         INTO l_intercompany_flag;
1712                   CLOSE get_intercompany_flag_csr;
1713 
1714                   IF (l_intercompany_flag = 'Y')
1715                   THEN
1716                     l_use_inv_org_flag := 'N';
1717                   ELSE
1718                     OPEN get_centralized_flag_csr;
1719                     FETCH get_centralized_flag_csr
1720                           INTO l_use_inv_org_flag;
1721                     CLOSE get_centralized_flag_csr;
1722                   END IF;
1723 
1724                   IF (l_use_inv_org_flag = 'Y') THEN
1725                     OPEN get_misc_details_csr;
1726                     FETCH get_misc_details_csr
1727                           INTO l_business_group_id,
1728                                l_org_st_ver_id,
1729                                l_base_language,
1730                                l_invoice_date,
1731                                l_carry_out_org_id;
1732                     CLOSE get_misc_details_csr;
1733                     -- Call pa_invoice_xfer.get_trx_crmemo_types to
1734                     -- get trx_type_id. Get overapplication flag for
1735                     -- trx_type_id.
1736                     pa_invoice_xfer.get_trx_crmemo_types(
1737                              P_business_group_id=> l_business_group_id,
1738                              P_carrying_out_org_id => l_carry_out_org_id,
1739                              P_proj_org_struct_version_id => l_org_st_ver_id,
1740                              p_basic_language => l_base_language,
1741                              p_trans_date => l_invoice_date,
1742                              P_trans_type => x_trx_type,
1743                              P_crmo_trx_type => x_cm_trx_type,
1744                              P_error_status  => x_error_status,
1745                              P_error_message => x_error_message);
1746                     IF (x_error_status = 1) THEN
1747                       l_return_status := FND_API.G_RET_STS_ERROR;
1748                       l_msg_count     := 1;
1749                       l_msg_data      := x_error_message;
1750                       RAISE FND_API.G_EXC_ERROR;
1751                     ELSE
1752                       -- Get overapplication_flag for x_trx_type
1753                       OPEN overapplication_csr_2;
1754                       FETCH overapplication_csr_2
1755                             INTO l_overapplication_flag;
1756                       CLOSE overapplication_csr_2;
1757                     END IF;
1758 
1759                   ELSE
1760                     OPEN overapplication_csr;
1761                     FETCH overapplication_csr
1762                           INTO l_overapplication_flag;
1763                     CLOSE overapplication_csr;
1764                   END IF;
1765 
1766                   /* Bug 9459594 */
1767 
1768                   l_return_status := FND_API.G_RET_STS_ERROR;
1769                   IF (NVL(l_overapplication_flag,'N') = 'Y') THEN
1770                     l_msg_data := 'PA_OVER_CREDIT_INV';
1771                   ELSE
1772                     l_msg_data := 'PA_OVER_CREDIT_INV_ERR';
1773                   END IF;
1774 
1775                   l_msg_count := 1;
1776 
1777                   RAISE FND_API.G_EXC_ERROR;
1778 
1779                ELSE
1780                /* The ELSE part is for credit action WRITE-OFF */
1781                   /* The balance due in PA should not be <= 0.
1782                       Write-Off cannot be performed if balance due <= 0. */
1783                   IF sign(p_invoice_amount - l_tot_credited_amt) <> 1 THEN
1784                      l_return_status := FND_API.G_RET_STS_ERROR;
1785                      --l_msg_data := 'PA_IN_CRD_NOT_POSITIVE';
1786                      l_msg_data := 'PA_IN_CRD_NOT_POSITIVE_WO'; --Created new message for Bug3725206
1787                      l_msg_count := 1;
1788 
1789                      RAISE FND_API.G_EXC_ERROR;
1790 
1791                   ELSE
1792                   /* The entered credit amount should not exceed the balance due in PA. */
1793                      l_return_status := FND_API.G_RET_STS_ERROR;
1794                      l_msg_data := 'PA_IN_CRD_NOT_EXCEED_BAL';
1795                      l_msg_count := 1;
1796 
1797                      RAISE FND_API.G_EXC_ERROR;
1798 
1799                   END IF;
1800 
1801                END IF;
1802 
1803            END IF;
1804 
1805      /* Fourth check - The entered credit amount should not exceed the balance due in AR
1806                        for credit action Write-Off. */
1807           IF p_credit_action = 'WRITE_OFF'  THEN
1808                   IF p_credit_amount > p_balance_due THEN
1809                      l_return_status := FND_API.G_RET_STS_ERROR;
1810                      l_msg_data := 'PA_IN_CRD_EXCEED';
1811                      l_msg_count := 1;
1812 
1813                      RAISE FND_API.G_EXC_ERROR;
1814                   END IF;
1815           END IF;
1816 
1817       /* Initialises the credit related columns as previous credit data might have not been wiped out */
1818 
1819       pa_invoice_actions.init_draft_inv_lines(
1820                  p_project_id        => p_project_id,
1821                  p_draft_invoice_num => p_draft_invoice_num,
1822                  x_return_status     => l_return_status,
1823                  x_msg_count         => l_msg_count,
1824                  x_msg_data          => l_msg_data );
1825 
1826       IF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1827 
1828             RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1829 
1830       ELSIF l_return_status = FND_API.G_RET_STS_ERROR THEN
1831 
1832             RAISE FND_API.G_EXC_ERROR;
1833 
1834       END IF;
1835 
1836 
1837      /* Fifth check - The total credit amount should not be zero
1838 	                except for the credit_action_type of LINE.
1839          The purpose of this check is to not allow credit that total to zero in the header
1840          but allow the same if it is distributed over separate lines - eg +100 and -100 in 2 lines
1841       */
1842 
1843 	  IF     sign(nvl(p_credit_amount,0))=0    THEN
1844 
1845 	         if p_credit_action_type = 'LINE'  then
1846                     null;
1847                  else
1848                     l_return_status := FND_API.G_RET_STS_ERROR;
1849                     l_msg_data := 'PA_IN_ENT_CREDIT_AMT';
1850                     l_msg_count := 1;
1851 
1852                     RAISE FND_API.G_EXC_ERROR;
1853 
1854 		 end if;
1855           END IF;
1856 
1857      /* Sixth check - the total credit amount should not be negative */
1858 --For bug 4231721 :Changing the if condition from <>1 to <0 So that check is valid only is Credit amount <0
1859 	  IF  sign(nvl(p_credit_amount,0)) < 0    THEN
1860 
1861              l_return_status := FND_API.G_RET_STS_ERROR;
1862              l_msg_data := 'PA_SU_NEGATIVE_NUM_NOT_ALLOWED';
1863              l_msg_count := 1;
1864 
1865              RAISE FND_API.G_EXC_ERROR;
1866 
1867 	  END IF;
1868 
1869 
1870   EXCEPTION
1871 
1872        WHEN FND_API.G_EXC_ERROR THEN
1873              x_return_status := l_return_status;
1874              x_msg_count := l_msg_count;
1875              x_msg_data := l_msg_data;
1876 
1877             /* ATG Changes */
1878              x_tot_credited_amt := null;
1879 
1880        WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1881              x_return_status := l_return_status;
1882              x_msg_count := l_msg_count;
1883              x_msg_data := l_msg_data;
1884 
1885             /* ATG Changes */
1886              x_tot_credited_amt := null;
1887 
1888        WHEN others then
1889             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1890             x_msg_count := l_msg_count;
1891             x_msg_data := SUBSTR(SQLERRM,1,100);
1892 
1893             /* ATG Changes */
1894              x_tot_credited_amt := null;
1895 
1896   END validate_invoice_amount;
1897 
1898   /*-----------------------------------------------------------------------------------------+
1899    |   Procedure  :   init_draft_inv_lines                                                   |
1900    |   Purpose    :   To initialize the credit related columns in draft invoice lines table  |
1901    |   Parameters :                                                                          |
1902    |     ==================================================================================  |
1903    |     Name                             Mode    Description                                |
1904    |     ==================================================================================  |
1905    |     p_project_id          IN      Project ID                                            |
1906    |     p_draft_invoice_num   IN      Draft invoice for which credit action is to be done   |
1907    |     x_return_status       OUT     Return status of this procedure                       |
1908    |     x_msg_count           OUT     Error message count                                   |
1909    |     x_msg_data            OUT     Error message                                         |
1910    |     ==================================================================================  |
1911    +----------------------------------------------------------------------------------------*/
1912 
1913   PROCEDURE init_draft_inv_lines(
1914              p_project_id        IN     NUMBER,
1915              p_draft_invoice_num IN     NUMBER,
1916              x_return_status     OUT   NOCOPY VARCHAR2,
1917              x_msg_count         OUT   NOCOPY NUMBER,
1918              x_msg_data          OUT   NOCOPY VARCHAR2)   IS
1919 
1920 
1921          l_return_status            VARCHAR2(30) := NULL;
1922          l_msg_count                NUMBER       := NULL;
1923          l_msg_data                 VARCHAR2(250) := NULL;
1924 
1925   BEGIN
1926 
1927       x_return_status    := FND_API.G_RET_STS_SUCCESS;
1928       x_msg_count        := 0;
1929 
1930       /* Update credit_process_flag, credit_amount to NULL */
1931 
1932       update pa_draft_invoice_items
1933       set credit_process_flag = NULL,
1934           credit_amount = NULL
1935       where project_id = p_project_id
1936       and   draft_invoice_num = p_draft_invoice_num;
1937 
1938   EXCEPTION
1939 
1940        WHEN others then
1941             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1942             x_msg_count := l_msg_count;
1943             x_msg_data := SUBSTR(SQLERRM,1,100);
1944 
1945 
1946   END init_draft_inv_lines;
1947 
1948 
1949   /*----------------------------------------------------------------------------------------------+
1950    |   Procedure  :   update_credit_qual_lines                                                    |
1951    |   Purpose    :   To mark the draft invoice lines which have been selected for                |
1952    |                  crediting                                                                   |
1953    |   Parameters :                                                                               |
1954    |     ==================================================================================       |
1955    |     Name                       Mode    Description                                           |
1956    |     ==================================================================================       |
1957    |     p_project_id               IN      Project ID                                            |
1958    |     p_credit_action            IN      Indicates if credit is WRITE-OFF/CONCESSION           |
1959    |     p_credit_action_type       IN      Indicates if credit action type is                    |
1960    |                                        SUMMARY/GROUP/LINES                                   |
1961    |     p_draft_invoice_num        IN      Draft invoice for which credit action is to be done   |
1962    |     p_draft_invoice_line_num   IN      Draft invoice line which has to be credited           |
1963    |     p_line_credit_amount       IN      Total credit amount on the invoice                    |
1964    |     x_return_status            OUT     Return status of this procedure                       |
1965    |     x_msg_count                OUT     Error message count                                   |
1966    |     x_msg_data                 OUT     Error message                                         |
1967    |     ==================================================================================       |
1968    +---------------------------------------------------------------------------------------------*/
1969 
1970   Procedure update_credit_qual_lines (
1971              p_project_id             IN NUMBER,
1972              p_credit_action          IN VARCHAR2,
1973              p_credit_action_type     IN VARCHAR2,
1974              p_draft_invoice_num      IN NUMBER,
1975              p_draft_invoice_line_num IN NUMBER,
1976              p_line_credit_amount     IN NUMBER,
1977              x_return_status          OUT   NOCOPY VARCHAR2,
1978              x_msg_count              OUT   NOCOPY NUMBER,
1979              x_msg_data               OUT   NOCOPY VARCHAR2)   IS
1980 
1981          l_return_status            VARCHAR2(30) := NULL;
1982          l_msg_count                NUMBER       := NULL;
1983          l_msg_data                 VARCHAR2(250) := NULL;
1984 
1985   BEGIN
1986 
1987       x_return_status    := FND_API.G_RET_STS_SUCCESS;
1988       x_msg_count        := 0;
1989 
1990       /* In the case of credit action type  at
1991 
1992          a) Invoice SUMMARY level all the lines of the invoice has to be credited.
1993             Basically the total credit amount will be pro-rated across all the lines. Credit amount will not
1994             be populated in the lines as this scenario exists currently and should go through the same flow.
1995             Only the credit_process_flag will be set to 'Y' for all lines. This is required to indicate that
1996             while calculating the rounding difference the sum of ALL line amounts (credit invoice) should match
1997             the credit amount entered by the user. In this case p_line_credit_amount/p_draft_invoice_line_num will be null
1998 
1999          b) GROUP level (user selects specific lines and gives credit amount which has to pro-rated only on those lines)
2000             The total credit amount will be pro-rated across the specified lines by subsequent API's. The line selected for
2001             crediting by the user will be specified by p_draft_invoice_line_num. Since the credit amount will be given as one
2002             whole amount, p_line_credit_amount will be NULL. Credit_process_flag will be set to 'Y' for the line specified
2003             by p_draft_invoice_line_num. While calculating the rounding difference the sum of line amounts
2004             SELECTED BY USER (INFERRED BY CREDIT_PROCESS_FLAG) should match the credit amount entered by the user.
2005             In this case p_line_credit_amount will be null
2006 
2007          c) LINES level (user selects the line and specifies the credit amount on the line)
2008             No pro-ration of credit amount is to be performed as it is specified one on one on the line.  No rounding also
2009             needs to be checked. Both p_line_credit_amount/p_draft_invoice_line_num will be specified
2010 
2011          Both (b) and (c) will be called in a loop for as many lines selected by the user in Invoice Review Form
2012        */
2013 
2014       if p_credit_action_type = 'SUMMARY' then
2015 
2016          /* Update all lines of draft_invoice_items for credit_process_flag = 'Y' */
2017 
2018          update pa_draft_invoice_items
2019          set credit_process_flag = 'Y'
2020          where project_id = p_project_id
2021          and   draft_invoice_num = p_draft_invoice_num
2022          /* Added for Payroll Billing ER #11896864 - Start */
2023          and   NVL(credit_process_flag, 'N') <> 'X';
2024          /* Added for Payroll Billing ER #11896864 - End */
2025 
2026       else
2027 
2028 
2029          if p_credit_action_type = 'GROUP' then
2030 
2031             /* Update specific line of draft_invoice_items for credit_process_flag = 'Y' */
2032 
2033             update pa_draft_invoice_items
2034             set credit_process_flag = 'Y'
2035             where project_id = p_project_id
2036             and   draft_invoice_num = p_draft_invoice_num
2037             and   line_num = p_draft_invoice_line_num
2038             /* Added for Payroll Billing ER #11896864 - Start */
2039             and   NVL(credit_process_flag, 'N') <> 'X';
2040             /* Added for Payroll Billing ER #11896864 - End */
2041 
2042          elsif p_credit_action_type = 'LINE' then
2043 
2044             /* Update specific line of draft_invoice_items for credit_process_flag = 'Y'and credit_amount = p_line_credit_amount */
2045 
2046             update pa_draft_invoice_items
2047             set credit_process_flag = 'Y',
2048                 credit_amount = p_line_credit_amount
2049             where project_id = p_project_id
2050             and   draft_invoice_num = p_draft_invoice_num
2051             and   line_num = p_draft_invoice_line_num
2052             /* Added for Payroll Billing ER #11896864 - Start */
2053             and   NVL(credit_process_flag, 'N') <> 'X';
2054             /* Added for Payroll Billing ER #11896864 - End */
2055 
2056          end if;
2057 
2058       end if;
2059 
2060   EXCEPTION
2061 
2062        WHEN others then
2063             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2064             x_msg_count := l_msg_count;
2065             x_msg_data := SUBSTR(SQLERRM,1,100);
2066 
2067   END update_credit_qual_lines;
2068 
2069   /*----------------------------------------------------------------------------------------------+
2070    |   Procedure  :   validate_line_credit_amount                                                 |
2071    |   Purpose    :   To validate the credit amount on the specificed invoice line                |
2072    |   Parameters :                                                                               |
2073    |     ==================================================================================       |
2074    |     Name                       Mode    Description                                           |
2075    |     ==================================================================================       |
2076    |     p_project_id               IN      Project ID                                            |
2077    |     p_credit_action            IN      Indicates if credit is WRITE-OFF/CONCESSION           |
2078    |     p_credit_action_type       IN      Indicates if credit action type is                    |
2079    |                                        SUMMARY/GROUP/LINES                                   |
2080    |     p_draft_invoice_num        IN      Draft invoice for which credit action is to be done   |
2081    |     p_draft_invoice_line_num   IN      Draft invoice line which has to be credited           |
2082    |     p_inv_amount               IN      Invoice amount on the specified invoice line          |
2083    |     p_credit_amount            IN      Credit amount on the specified invoice line           |
2084    |     x_return_status            OUT     Return status of this procedure                       |
2085    |     x_msg_count                OUT     Error message count                                   |
2086    |     x_msg_data                 OUT     Error message                                         |
2087    |     ==================================================================================       |
2088    +---------------------------------------------------------------------------------------------*/
2089 
2090   Procedure validate_line_credit_amount (
2091              p_project_id             IN NUMBER,
2092              p_credit_action          IN VARCHAR2,
2093              p_credit_action_type     IN VARCHAR2,
2094              p_draft_invoice_num      IN NUMBER,
2095              p_draft_invoice_line_num IN NUMBER,
2096              p_inv_amount             IN NUMBER,
2097              p_credit_amount          IN NUMBER,
2098              x_return_status          OUT   NOCOPY VARCHAR2,
2099              x_msg_count              OUT   NOCOPY NUMBER,
2100              x_msg_data               OUT   NOCOPY VARCHAR2)   IS
2101 
2102          l_return_status            VARCHAR2(30) := NULL;
2103          l_msg_count                NUMBER       := NULL;
2104          l_msg_data                 VARCHAR2(250) := NULL;
2105 
2106 
2107   BEGIN
2108 
2109       x_return_status    := FND_API.G_RET_STS_SUCCESS;
2110       x_msg_count        := 0;
2111 
2112       /*  If credit is performed at GROUP, the total credit amount passed should not exceed the
2113           total selected line invoice amount for credit action WRITE-OFF.  For Concession, we allow
2114           over credit application. */
2115 
2116       IF p_credit_action_type = 'GROUP' THEN
2117 
2118       /* First check - Total credit amount should not exceed the net invoice amount of the selected
2119                         lines.  This is true for Write-Off only. */
2120          IF p_credit_action = 'CONCESSION' THEN
2121             NULL;
2122          ELSE
2123             IF p_credit_amount > p_inv_amount THEN
2124                l_return_status := FND_API.G_RET_STS_ERROR;
2125                l_msg_data :=  'PA_IN_CRD_NOT_EXCEED_BAL';
2126 
2127                RAISE FND_API.G_EXC_ERROR;
2128             END IF;
2129          END IF;
2130 
2131       ELSE
2132         /* This ELSE part is for the line credit amount check when the user
2133               chooses to enter the credit amount by line. */
2134 
2135         /* First check - Line credit amount should be greater than zero */
2136 
2137          IF p_credit_amount = 0  THEN
2138             l_return_status := FND_API.G_RET_STS_ERROR;
2139             l_msg_data := 'PA_IN_ENT_CREDIT_AMT';
2140             l_msg_count := 1;
2141 
2142             RAISE FND_API.G_EXC_ERROR;
2143 
2144          END IF;
2145 
2146         /* Second check - Line credit amount should be of the same sign as the line invoice amount */
2147 
2148          IF sign(p_inv_amount) <> sign(p_credit_amount) THEN
2149             l_return_status := FND_API.G_RET_STS_ERROR;
2150             l_msg_data := 'PA_IN_CRD_SIGN_INV';
2151             l_msg_count := 1;
2152 
2153             RAISE FND_API.G_EXC_ERROR;
2154 
2155          END IF;
2156       END IF;
2157 
2158 
2159        /* Check that credit amount does not exceed invoice amount on the line
2160           This check has been removed from here since the check needs to be done in forms
2161           because we allow over-credit on the line for CONCESSION
2162        */
2163 
2164 
2165   EXCEPTION
2166 
2167        WHEN FND_API.G_EXC_ERROR THEN
2168              x_return_status := l_return_status;
2169              x_msg_count := l_msg_count;
2170              x_msg_data := l_msg_data;
2171 
2172        WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2173              x_return_status := l_return_status;
2174              x_msg_count := l_msg_count;
2175              x_msg_data := l_msg_data;
2176 
2177        WHEN others then
2178             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2179             x_msg_count := l_msg_count;
2180             x_msg_data := SUBSTR(SQLERRM,1,100);
2181 
2182   END validate_line_credit_amount;
2183 
2184   /*-----------------------------------------------------------------------------------------+
2185    |   Procedure  :   distribute_credit_amount                                               |
2186    |   Purpose    :   To pro-rate the total credit amount across the lines selected for      |
2187    |                  crediting on the specified invoice                                     |
2188    |   Parameters :                                                                          |
2189    |     ==================================================================================  |
2190    |     Name                             Mode    Description                                |
2191    |     ==================================================================================  |
2192    |     p_project_id          IN      Project ID                                            |
2193    |     p_credit_action       IN      Indicates if credit is WRITE-OFF/CONCESSION           |
2194    |     p_credit_action_type  IN      Indicates if credit action type is                    |
2195    |                                   SUMMARY/GROUP/LINES                                   |
2196    |     p_draft_invoice_num   IN      Draft invoice for which credit action is to be done   |
2197    |     p_total_credit_amount IN      Total credit amount on the invoice                    |
2198    |     x_return_status       OUT     Return status of this procedure                       |
2199    |     x_msg_count           OUT     Error message count                                   |
2200    |     x_msg_data            OUT     Error message                                         |
2201    |     ==================================================================================  |
2202    +----------------------------------------------------------------------------------------*/
2203 
2204 
2205   Procedure distribute_credit_amount (
2206              p_project_id             IN NUMBER,
2207              p_credit_action          IN VARCHAR2,
2208              p_credit_action_type     IN VARCHAR2,
2209              p_draft_invoice_num      IN NUMBER,
2210              p_total_credit_amount    IN NUMBER,
2211              x_return_status          OUT   NOCOPY VARCHAR2,
2212              x_msg_count              OUT   NOCOPY NUMBER,
2213              x_msg_data               OUT   NOCOPY VARCHAR2)   IS
2214 
2215       l_inv_amount   NUMBER;
2216       l_inv_currency_code VARCHAR2(3);
2217       l_return_status            VARCHAR2(30) := NULL;
2218       l_msg_count                NUMBER       := NULL;
2219       l_msg_data                 VARCHAR2(250) := NULL;
2220 
2221   BEGIN
2222 
2223       x_return_status    := FND_API.G_RET_STS_SUCCESS;
2224       x_msg_count        := 0;
2225 
2226 --      insert into bss_conc (serial_no, proc_ind) values (1, 'DIST_CREDIT_AMT');
2227 
2228       /* This API will be called only in the case of GROUP/LINE level as SUMMARY will go through the existing
2229          flow as defined in paisql.lpc
2230          In case of GROUP, the total credit amount has to be pro-rated across the user selected lines indicated by
2231          credit_process_flag = 'Y'
2232          In case of LINES the credit amount is already populated  on the lines that are to be credited
2233          In case of GROUP/LINES, after the credit amount is populated in the standard lines, corresponding retention lines
2234          are also to be credited . A separate API distribute_credit_amount_retn will be called to do the same */
2235 
2236       if p_credit_action_type = 'GROUP' then
2237 
2238             /* Get the sum of invoice amount of the user selected lines (credit_process_flag = 'Y'). Apply the ratio
2239             of p_total_credit_amount over sum_invoice_amount on the line invoice amount. Inv_currency_code is required
2240             to define the precision of the computed credit amount */
2241 
2242             select sum(dii.inv_amount), max(di.inv_currency_code)
2243             into l_inv_amount, l_inv_currency_code
2244             from pa_draft_invoice_items dii, pa_draft_invoices di
2245             where di.project_id = p_project_id
2246             and   di.draft_invoice_num = p_draft_invoice_num
2247             and   dii.project_id = di.project_id
2248             and   dii.draft_invoice_num = di.draft_invoice_num
2249             and   nvl(dii.credit_process_flag,'N') = 'Y' ;
2250 
2251             update pa_draft_invoice_items dii
2252             set credit_amount =
2253                   pa_currency.round_trans_currency_amt(
2254                             (inv_amount * (p_total_credit_amount/l_inv_amount)),
2255                             rtrim(l_inv_currency_code))
2256             where project_id = p_project_id
2257             and   draft_invoice_num = p_draft_invoice_num
2258             and   nvl(dii.credit_process_flag,'N') = 'Y' ;
2259 
2260       end if;
2261 
2262       /* Call API to calculate credit amount for corresponding retention lines */
2263 
2264       pa_invoice_actions.distribute_credit_amount_retn(
2265                  p_project_id        => p_project_id,
2266                  p_draft_invoice_num => p_draft_invoice_num,
2267                  x_return_status     => l_return_status,
2268                  x_msg_count         => l_msg_count,
2269                  x_msg_data          => l_msg_data );
2270 
2271       IF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
2272 
2273             RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2274 
2275       ELSIF l_return_status = FND_API.G_RET_STS_ERROR THEN
2276 
2277             RAISE FND_API.G_EXC_ERROR;
2278 
2279       END IF;
2280 
2281 
2282 
2283   EXCEPTION
2284 
2285         WHEN FND_API.G_EXC_ERROR THEN
2286              ROLLBACK;
2287              x_return_status := l_return_status;
2288              x_msg_count := l_msg_count;
2289              x_msg_data := l_msg_data;
2290 
2291         WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2292              ROLLBACK;
2293              x_return_status := l_return_status;
2294              x_msg_count := l_msg_count;
2295              x_msg_data := l_msg_data;
2296 
2297        WHEN others then
2298             ROLLBACK;
2299             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2300             x_msg_count := l_msg_count;
2301             x_msg_data := SUBSTR(SQLERRM,1,100);
2302 
2303   END distribute_credit_amount;
2304 
2305   /*-----------------------------------------------------------------------------------------+
2306    |   Procedure  :   distribute_credit_amount_retn                                          |
2307    |   Purpose    :   To distribute the credit amount on the retention lines based on the    |
2308    |                  corresponding standard line's credit amount                            |
2309    |   Parameters :                                                                          |
2310    |     ==================================================================================  |
2311    |     Name                             Mode    Description                                |
2312    |     ==================================================================================  |
2313    |     p_project_id          IN      Project ID                                            |
2314    |     p_draft_invoice_num   IN      Draft invoice for which credit action is to be done   |
2315    |     x_return_status       OUT     Return status of this procedure                       |
2316    |     x_msg_count           OUT     Error message count                                   |
2317    |     x_msg_data            OUT     Error message                                         |
2318    |     ==================================================================================  |
2319    +----------------------------------------------------------------------------------------*/
2320 
2321 
2322   Procedure distribute_credit_amount_retn (
2323              p_project_id             IN NUMBER,
2324              p_draft_invoice_num      IN NUMBER,
2325              x_return_status          OUT   NOCOPY VARCHAR2,
2326              x_msg_count              OUT   NOCOPY NUMBER,
2327              x_msg_data               OUT   NOCOPY VARCHAR2)   IS
2328 
2329 
2330         l_retention_percentage number;
2331         l_retention_rule_id number;
2332         l_retention_line_num number;
2333         l_inv_currency_code varchar2(3);
2334 
2335         l_tot_credit_amount   number;
2336         l_amount   number;
2337         l_credit_amount   number;
2338         l_retn_credit_amount   number;
2339         l_retained_amount   number;
2340         l_line_processed    VARCHAR2(5);
2341 
2342          l_return_status            VARCHAR2(30) := NULL;
2343          l_msg_count                NUMBER       := NULL;
2344          l_msg_data                 VARCHAR2(250) := NULL;
2345 
2346   BEGIN
2347 
2348         x_return_status    := FND_API.G_RET_STS_SUCCESS;
2349         x_msg_count        := 0;
2350 
2351 /*        insert into bss_conc
2352           (serial_no, proc_ind)
2353         values(2, 'DISTRIBUTE_RETN_CREDIT');
2354 */
2355         /* Check if retention for this invoice is generated using old/new model
2356            In old model, retention% will be stamped on the draft invoice
2357 
2358            This SQL also ensures that the invoice does have RETENTION LINE */
2359 
2360         SELECT nvl(retention_percentage,0), inv_currency_code
2361         INTO l_retention_percentage, l_inv_currency_code
2362         FROM pa_draft_invoices
2363         WHERE project_id = p_project_id
2364         AND draft_invoice_num = p_draft_invoice_num
2365         AND EXISTS (select null from pa_draft_invoice_items
2366                     WHERE project_id = p_project_id
2367                     AND draft_invoice_num = p_draft_invoice_num
2368                     AND invoice_line_type = 'RETENTION');
2369 
2370        if nvl(l_retention_percentage, 0) <> 0 THEN  -- old model
2371 
2372           /* In old model, the retention credit amount will be calculated by applying the retention% on the sum of
2373              the credit amount stamped on the draft invoice lines
2374 
2375              Since retention amount is always negative, the calculated retention credit amount is multiplied by -1 */
2376 
2377           select sum(nvl(credit_amount,0))
2378           into l_tot_credit_amount
2379           from pa_draft_invoice_items
2380           where project_id = p_project_id
2381           and  draft_invoice_num = p_draft_invoice_num;
2382 
2383           l_retn_credit_amount := (-1) * (l_tot_credit_amount * l_retention_percentage)/100;
2384 
2385           /* In old model there will be only one retention line for an invoice. So credit amount is stamped on that line */
2386 
2387           update pa_draft_invoice_items
2388           set credit_amount =
2389                pa_currency.round_trans_currency_amt(l_retn_credit_amount, rtrim(l_inv_currency_code))
2390           where project_id = p_project_id
2391           and  draft_invoice_num = p_draft_invoice_num
2392           and invoice_line_type = 'RETENTION';
2393 
2394        else -- NEW MODEL
2395 
2396            /* select the standard lines which are to be credited within a loop
2397               For every line of the draft invoice item, we require the retained amount
2398                  (will be in invoice processing currency) , retention rule id and retention_line_num (indicates which line
2399                  in the draft_invoice_items corresponds to retention of this standard line.
2400                  Once we get these, store these values into local variables and set line_processed_flag to TRUE
2401                  Call compute_retn_credit_amount API with the fetched values. The logic to get these values will be:
2402 
2403               If the line represents event (event_num will be not null)
2404                  the retained amount (will be in invoice processing currency) ,
2405                  retention rule id, retention_line_num  will be stored on the line itself. Set line_processed flag to TRUE
2406 
2407               If line_processed is FALSE, then check in ERDL( Could be WRITE-ON events) with project_id, draft_invoice_num,
2408                  and line_num.  One line of draft invoice item may have multiple lines in ERDL. Since we need to get the
2409                  retention info for every retention_rule_id, we group by retention_rule_id and get sum of the amount.
2410                  Set line_processed_flag to TRUE
2411 
2412               If line_processed is FALSE, then check in RDL( Could be EI's) with project_id, draft_invoice_num,
2413                  and line_num.  One line of draft invoice item may have multiple lines in RDL. Since we need to get the
2414                  retention info for every retention_rule_id, we group by retention_rule_id and get sum of the amount.
2415                  Set line_processed_flag to TRUE
2416            */
2417 
2418            for inv_lines in (
2419                select nvl(dii.line_num,0) line_num,
2420                            nvl(dii.event_num,0) event_num,
2421                            nvl(dii.retn_draft_invoice_line_num,0) retention_line_num,
2422                            nvl(dii.retention_rule_id,-1) retention_rule_id,
2423                            nvl(dii.retained_amount,0)  retained_amount,
2424                            dii.amount          amount,
2425                            dii.credit_amount   credit_amount
2426                 from pa_draft_invoice_items dii
2427                 where project_id = p_project_id
2428                 AND draft_invoice_num = p_draft_invoice_num
2429                 AND invoice_line_type <> 'RETENTION'
2430                 AND nvl(dii.credit_amount, 0) <> 0
2431                 order by dii.line_num) LOOP
2432 
2433                 l_amount          := inv_lines.amount;
2434                 l_credit_amount   := inv_lines.credit_amount;
2435                 l_line_processed  := 'FALSE';
2436 
2437                 if nvl(inv_lines.event_num,0) <> 0 then -- events line
2438 
2439                    if nvl(inv_lines.retained_amount,0) <> 0  then -- retention exists for this line
2440 
2441                       l_line_processed  := 'TRUE';
2442                       l_retention_line_num := inv_lines.retention_line_num;
2443                       l_retention_rule_id := inv_lines.retention_rule_id;
2444                       l_retained_amount := inv_lines.retained_amount;
2445 
2446 /*                      insert into bss_conc values (3, p_project_id, p_draft_invoice_num,
2447                                                    'DII', l_retention_rule_id, l_retention_line_num,
2448                                                     l_retained_amount, l_amount, l_credit_amount, inv_lines.line_num, 'RETN');
2449 */
2450                       compute_retn_credit_amount (
2451                                      p_project_id         => p_project_id,
2452                                      p_draft_invoice_num  => p_draft_invoice_num,
2453                                      p_retention_rule_id  => l_retention_rule_id,
2454                                      p_retention_line_num => l_retention_line_num,
2455                                      p_retained_amount    => l_retained_amount,
2456                                      p_amount             => l_amount,
2457                                      p_credit_amount      => l_credit_amount,
2458                                      x_return_status      => l_return_status,
2459                                      x_msg_count          => l_msg_count,
2460                                      x_msg_data          => l_msg_data );
2461 
2462                       IF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
2463 
2464                          RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2465 
2466                       ELSIF l_return_status = FND_API.G_RET_STS_ERROR THEN
2467 
2468                          RAISE FND_API.G_EXC_ERROR;
2469 
2470                       END IF;
2471 
2472                    end if; -- retained_amount <> 0
2473 
2474                 end if; -- events line
2475 
2476                 if l_line_processed = 'FALSE' then
2477 
2478                    for erdl_lines in (
2479                        select nvl(erdl.retn_draft_invoice_line_num, -1) retention_line_num,
2480                            nvl(erdl.retention_rule_id,-1) retention_rule_id,
2481                            nvl(sum(nvl(erdl.retained_amount,0)),0) retained_amount
2482                        from pa_cust_event_rdl_all erdl
2483                        where project_id = p_project_id
2484                        AND draft_invoice_num = p_draft_invoice_num
2485                        AND draft_invoice_item_line_num = inv_lines.line_num
2486                        group by nvl(erdl.retn_draft_invoice_line_num,-1) , nvl(erdl.retention_rule_id,-1) ) LOOP
2487 
2488                        l_line_processed  := 'TRUE';
2489                        l_retention_line_num := erdl_lines.retention_line_num;
2490                        l_retention_rule_id := erdl_lines.retention_rule_id;
2491                        l_retained_amount := nvl(erdl_lines.retained_amount,0);
2492 
2493                        if l_retained_amount <> 0 then -- retention exists for this line
2494 
2495 /*                      insert into bss_conc values (4,p_project_id, p_draft_invoice_num,
2496                                                    'ERDL', l_retention_rule_id, l_retention_line_num,
2497                                                     l_retained_amount, l_amount, l_credit_amount, inv_lines.line_num, 'RETN');
2498 */
2499                           compute_retn_credit_amount (
2500                                      p_project_id         => p_project_id,
2501                                      p_draft_invoice_num  => p_draft_invoice_num,
2502                                      p_retention_rule_id  => l_retention_rule_id,
2503                                      p_retention_line_num => l_retention_line_num,
2504                                      p_retained_amount    => l_retained_amount,
2505                                      p_amount             => l_amount,
2506                                      p_credit_amount      => l_credit_amount,
2507                                      x_return_status      => l_return_status,
2508                                      x_msg_count          => l_msg_count,
2509                                      x_msg_data          => l_msg_data );
2510 
2511 
2512                           IF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
2513 
2514                                 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2515 
2516                           ELSIF l_return_status = FND_API.G_RET_STS_ERROR THEN
2517 
2518                                 RAISE FND_API.G_EXC_ERROR;
2519 
2520                           END IF;
2521 
2522                        end if; -- l_retained_amunt <> 0
2523 
2524                    end loop; -- erdl_lines cursor
2525 
2526                 end if; -- l_line_processed = 'FALSE'
2527 
2528                 if l_line_processed = 'FALSE' then
2529 
2530                    for rdl_lines in (
2531                        select nvl(rdl.retn_draft_invoice_line_num, -1) retention_line_num,
2532                            nvl(rdl.retention_rule_id,-1) retention_rule_id,
2533                            sum(nvl(rdl.retained_amount,0)) retained_amount
2534                        from pa_cust_rev_dist_lines_all rdl
2535                        where project_id = p_project_id
2536                        AND draft_invoice_num = p_draft_invoice_num
2537                        AND draft_invoice_item_line_num = inv_lines.line_num
2538                        group by nvl(rdl.retn_draft_invoice_line_num,-1) , nvl(rdl.retention_rule_id,-1) ) LOOP
2539 
2540                        l_line_processed  := 'TRUE';
2541                        l_retention_line_num := rdl_lines.retention_line_num;
2542                        l_retention_rule_id := rdl_lines.retention_rule_id;
2543                        l_retained_amount := nvl(rdl_lines.retained_amount,0);
2544 
2545                        if l_retained_amount <> 0 then -- retention exists for this line
2546 
2547 /*                      insert into bss_conc values (5, p_project_id, p_draft_invoice_num,
2548                                                    'RDL', l_retention_rule_id, l_retention_line_num,
2549                                                     l_retained_amount, l_amount, l_credit_amount, inv_lines.line_num,'RETN');
2550 */
2551                           compute_retn_credit_amount (
2552                                      p_project_id         => p_project_id,
2553                                      p_draft_invoice_num  => p_draft_invoice_num,
2554                                      p_retention_rule_id  => l_retention_rule_id,
2555                                      p_retention_line_num => l_retention_line_num,
2556                                      p_retained_amount    => l_retained_amount,
2557                                      p_amount             => l_amount,
2558                                      p_credit_amount      => l_credit_amount,
2559                                      x_return_status      => l_return_status,
2560                                      x_msg_count          => l_msg_count,
2561                                      x_msg_data          => l_msg_data );
2562 
2563                           IF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
2564 
2565                                 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2566 
2567                           ELSIF l_return_status = FND_API.G_RET_STS_ERROR THEN
2568 
2569                                 RAISE FND_API.G_EXC_ERROR;
2570 
2571                           END IF;
2572 
2573                        end if; -- l_retained_amunt <> 0
2574 
2575                    end loop; -- rdl_lines cursor
2576 
2577                 end if; -- l_line_processed = 'FALSE'
2578 
2579            end loop; -- inv_lines cursor
2580 
2581            /* Since retention credit amount in the  original invoice should be negative and precision should be based
2582               on currency code we  multiply by -1 and round the amount based on inv_currency_code
2583            */
2584            update pa_draft_invoice_items
2585            set credit_amount =
2586                      pa_currency.round_trans_currency_amt(credit_amount, rtrim(l_inv_currency_code)) * -1
2587            where project_id = p_project_id
2588            and  draft_invoice_num = p_draft_invoice_num
2589            and invoice_line_type = 'RETENTION';
2590 
2591        end if; -- NEW MODEL
2592 
2593   EXCEPTION
2594 
2595        WHEN no_data_found then
2596             pa_mcb_invoice_pkg.log_message('No retention lines');
2597 
2598         WHEN FND_API.G_EXC_ERROR THEN
2599              ROLLBACK;
2600              x_return_status := l_return_status;
2601              x_msg_count := l_msg_count;
2602              x_msg_data := l_msg_data;
2603 
2604         WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2605              ROLLBACK;
2606              x_return_status := l_return_status;
2607              x_msg_count := l_msg_count;
2608              x_msg_data := l_msg_data;
2609 
2610        WHEN others then
2611             ROLLBACK;
2612             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2613             x_msg_count := l_msg_count;
2614             x_msg_data := SUBSTR(SQLERRM,1,100);
2615 
2616   END distribute_credit_amount_retn;
2617 
2618 
2619   /*-----------------------------------------------------------------------------------------+
2620    |   Procedure  :   compute_retn_credit_amount                                             |
2621    |   Purpose    :   To compute retention credit amount based on the retention setup of     |
2622    |                  the standard lines                                                     |
2623    |   Parameters :                                                                          |
2624    |     ==================================================================================  |
2625    |     Name                             Mode    Description                                |
2626    |     ==================================================================================  |
2627    |     p_project_id          IN      Project ID                                            |
2628    |     p_draft_invoice_num   IN      Draft invoice for which retention is to be credited   |
2629    |     p_retention_rule_id   IN      Retention rule id applied on the standard line        |
2630    |     p_retention_line_num  IN      Draft invoice line num on which retention credit amt  |
2631    |                                   is to be stamped/computed                             |
2632    |     p_retained_amount     IN      Retained amount on the standard invoice line          |
2633    |     p_amount              IN      Line amount of the standard line for which retention  |
2634    |                                   credit amount is to be computed                       |
2635    |     p_credit_amount       IN      Line credit amount of the standard line for which     |
2636    |                                   retention credit amount is to be computed             |
2637    |     x_return_status       OUT     Return status of this procedure                       |
2638    |     x_msg_count           OUT     Error message count                                   |
2639    |     x_msg_data            OUT     Error message                                         |
2640    |     ==================================================================================  |
2641    +----------------------------------------------------------------------------------------*/
2642 
2643   Procedure compute_retn_credit_amount (
2644              p_project_id             IN NUMBER,
2645              p_draft_invoice_num      IN NUMBER,
2646              p_retention_rule_id      IN NUMBER,
2647              p_retention_line_num     IN NUMBER,
2648              p_retained_amount        IN NUMBER,
2649              p_amount                 IN NUMBER,
2650              p_credit_amount          IN NUMBER,
2651              x_return_status          OUT   NOCOPY VARCHAR2,
2652              x_msg_count              OUT   NOCOPY NUMBER,
2653              x_msg_data               OUT   NOCOPY VARCHAR2)   IS
2654 
2655        l_threshold_amount number;
2656        l_retention_percentage number;
2657        l_retention_amount number;
2658        l_retn_credit_amount number;
2659 
2660          l_return_status            VARCHAR2(30) := NULL;
2661          l_msg_count                NUMBER       := NULL;
2662          l_msg_data                 VARCHAR2(250) := NULL;
2663   BEGIN
2664 
2665         x_return_status    := FND_API.G_RET_STS_SUCCESS;
2666         x_msg_count        := 0;
2667 
2668         /* If the retention setup defines only the retention % (no threshold_amount, no retention amount)
2669            then this percentage will be applied on the line credit amount (p_credit_amount) to get retention
2670            credit amount
2671 
2672            If there is a threshold amount/retention amount defined, it is not possible to figure out the value of these
2673            amounts at the point invoice was generated. So we get the ratio of retained amount over line amount of the
2674            standard line on the line credit amount to get retention credit amount */
2675 
2676         select nvl(threshold_amount,0), nvl(retention_percentage,0), nvl(retention_amount,0)
2677         into l_threshold_amount, l_retention_percentage, l_retention_amount
2678         from pa_proj_retn_rules
2679         where retention_rule_id = p_retention_rule_id;
2680 
2681 
2682         if (l_threshold_amount <> 0) OR (l_retention_amount <> 0) then
2683            l_retn_credit_amount := (p_retained_amount/p_amount) * p_credit_amount ;
2684         else
2685 
2686            l_retn_credit_amount := (p_credit_amount * l_retention_percentage) / 100 ;
2687 
2688         end if;
2689 
2690 
2691         /* Since  one line of draft invoice item may have multiple lines in RDL/ERDL this procedure may be called more than
2692            once for the same line. So credit amount is acutally summed up */
2693 
2694         update pa_draft_invoice_items
2695         set credit_amount = nvl(credit_amount ,0) + l_retn_credit_amount
2696         where project_id = p_project_id
2697         and draft_invoice_num = p_draft_invoice_num
2698         and line_num =  p_retention_line_num;
2699 
2700 
2701   EXCEPTION
2702 
2703        WHEN no_data_found then
2704             pa_mcb_invoice_pkg.log_message('No retention lines');
2705 
2706        WHEN others then
2707             x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2708             x_msg_count := l_msg_count;
2709             x_msg_data := SUBSTR(SQLERRM,1,100);
2710 
2711   END compute_retn_credit_amount;
2712 
2713   /* End Concession invoice modification */
2714 
2715 /*------------- End of Public Procedure/Function Declarations ----------------*/
2716 
2717 end PA_Invoice_Actions;