DBA Data[Home] [Help]

PACKAGE BODY: APPS.IBY_DISBURSE_UI_API_PUB_PKG

Source


1 PACKAGE BODY IBY_DISBURSE_UI_API_PUB_PKG AS
2 /*$Header: ibydapib.pls 120.160.12010000.7 2008/09/26 12:31:06 vkarlapu ship $*/
3 
4  /*
5   * Declare global variables
6   */
7  G_PKG_NAME CONSTANT VARCHAR2(30) := 'IBY_DISBURSE_UI_API_PUB_PKG';
8 
9  /*
10   * List of document statuses that are used / set in this
11   * module.
12   */
13  DOC_STATUS_PMT_REMOVED  CONSTANT VARCHAR2(100) := 'REMOVED_PAYMENT_REMOVED';
14  DOC_STATUS_PMT_STOPPED  CONSTANT VARCHAR2(100) := 'REMOVED_PAYMENT_STOPPED';
15  DOC_STATUS_PMT_VOIDED   CONSTANT VARCHAR2(100) := 'REMOVED_PAYMENT_VOIDED';
16  DOC_STATUS_PMT_SPOILED  CONSTANT VARCHAR2(100) := 'REMOVED_PAYMENT_SPOILED';
17  DOC_STATUS_INS_TERM     CONSTANT VARCHAR2(100) :=
18                              'REMOVED_INSTRUCTION_TERMINATED';
19  DOC_STATUS_REQ_TERM     CONSTANT VARCHAR2(100) :=
20                              'REMOVED_REQUEST_TERMINATED';
21  DOC_STATUS_VALID        CONSTANT VARCHAR2(100) := 'VALIDATED';
22  DOC_STATUS_PAY_CREAT    CONSTANT VARCHAR2(100) := 'PAYMENT_CREATED';
23  DOC_STATUS_REJECTED     CONSTANT VARCHAR2(100) := 'REJECTED';
24  DOC_STATUS_REMOVED      CONSTANT VARCHAR2(100) := 'REMOVED';
25  DOC_STATUS_VOID_SETUP   CONSTANT VARCHAR2(100) := 'VOID_BY_SETUP';
26  DOC_STATUS_FAIL_CA      CONSTANT VARCHAR2(100) := 'FAILED_BY_CALLING_APP';
27 
28  /*
29   * List of payment statuses that are used / set in this
30   * module.
31   */
32  PAY_STATUS_INS_TERM       CONSTANT VARCHAR2(100) :=
33                                'REMOVED_INSTRUCTION_TERMINATED';
34  PAY_STATUS_REQ_TERM       CONSTANT VARCHAR2(100) :=
35                                'REMOVED_REQUEST_TERMINATED';
36  PAY_STATUS_CREATED        CONSTANT VARCHAR2(100) := 'CREATED';
37  PAY_STATUS_MODIFIED       CONSTANT VARCHAR2(100) := 'MODIFIED';
38  PAY_STATUS_MOD_BNK_ACC    CONSTANT VARCHAR2(100) :=
39                                'MODIFIED_PAYEE_BANK_ACCOUNT';
40  PAY_STATUS_INS_CREAT      CONSTANT VARCHAR2(100) := 'INSTRUCTION_CREATED';
41  PAY_STATUS_VOID           CONSTANT VARCHAR2(100) := 'VOID';
42  PAY_STATUS_REPRINT        CONSTANT VARCHAR2(100) := 'READY_TO_REPRINT';
43  PAY_STATUS_SPOILED        CONSTANT VARCHAR2(100) := 'REMOVED_DOCUMENT_SPOILED';
44  PAY_STATUS_ISSUED         CONSTANT VARCHAR2(100) := 'ISSUED';
45  PAY_STATUS_SUB_FOR_PRINT  CONSTANT VARCHAR2(100) := 'SUBMITTED_FOR_PRINTING';
46  PAY_STATUS_FORMATTED      CONSTANT VARCHAR2(100) := 'FORMATTED';
47  PAY_STATUS_TRANSMITTED    CONSTANT VARCHAR2(100) := 'TRANSMITTED';
48  PAY_STATUS_ACK            CONSTANT VARCHAR2(100) := 'ACKNOWLEDGED';
49  PAY_STATUS_BNK_VALID      CONSTANT VARCHAR2(100) := 'BANK_VALIDATED';
50  PAY_STATUS_PAID           CONSTANT VARCHAR2(100) := 'PAID';
51  PAY_STATUS_REMOVED        CONSTANT VARCHAR2(100) := 'REMOVED';
52  PAY_STATUS_VOID_SETUP     CONSTANT VARCHAR2(100) := 'VOID_BY_SETUP';
53  PAY_STATUS_VOID_OVERFLOW  CONSTANT VARCHAR2(100) := 'VOID_BY_OVERFLOW';
54  PAY_STATUS_STOPPED        CONSTANT VARCHAR2(100) := 'REMOVED_PAYMENT_STOPPED';
55  PAY_STATUS_SETUP_REPRINT  CONSTANT VARCHAR2(100) := 'VOID_BY_SETUP_REPRINT';
56  PAY_STATUS_OVERFLOW_REPRINT
57                            CONSTANT VARCHAR2(100) := 'VOID_BY_OVERFLOW_REPRINT';
58  PAY_STATUS_REJECTED       CONSTANT VARCHAR2(100) := 'REJECTED';
59  /*
60   * List of payment instruction statuses that are used / set in this
61   * module.
62   */
63  INS_STATUS_READY_TO_PRINT  CONSTANT VARCHAR2(100) :=
64                                          'CREATED_READY_FOR_PRINTING';
65  INS_STATUS_READY_TO_FORMAT CONSTANT VARCHAR2(100) :=
66                                          'CREATED_READY_FOR_FORMATTING';
67  INS_STATUS_FORMAT_TO_PRINT CONSTANT VARCHAR2(100) :=
68                                          'FORMATTED_READY_FOR_PRINTING';
69  INS_STATUS_PRINTED         CONSTANT VARCHAR2(100) :=
70                                          'PRINTED';
71  INS_STATUS_TERMINATED      CONSTANT VARCHAR2(100) := 'TERMINATED';
72  INS_STATUS_FORMATTED       CONSTANT VARCHAR2(100) := 'FORMATTED';
73  INS_STATUS_FORMATTED_ELEC  CONSTANT VARCHAR2(100) := 'FORMATTED_ELECTRONIC';
74  INS_STATUS_TRANSMITTED     CONSTANT VARCHAR2(100) := 'TRANSMITTED';
75 
76  /*
77   * List of payment request statuses that are used / set in this
78   * module.
79   */
80  REQ_STATUS_TERMINATED  CONSTANT VARCHAR2(100) := 'TERMINATED';
81 
82  /*
83   * Paper document usage reasons.
84   */
85  DOC_USE_SPOILED     CONSTANT VARCHAR2(100) := 'SPOILED';
86  DOC_USE_ISSUED      CONSTANT VARCHAR2(100) := 'ISSUED';
87 
88  /*
89   * Payment completion code.
90   */
91  PMT_COMPLETE_YES    CONSTANT VARCHAR2(10) := 'YES';
92 
93  /*
94   * List of valid processing types on the payment profile.
95   */
96  P_TYPE_PRINTED      CONSTANT VARCHAR2(100) := 'PRINTED';
97  P_TYPE_ELECTRONIC   CONSTANT VARCHAR2(100) := 'ELECTRONIC';
98 
99  /*
100   * List of process types.
101   */
102  PROCESS_TYPE_IMMEDIATE CONSTANT VARCHAR2(100) := 'IMMEDIATE';
103  PROCESS_TYPE_STANDARD  CONSTANT VARCHAR2(100) := 'STANDARD';
104  PROCESS_TYPE_MANUAL    CONSTANT VARCHAR2(100) := 'MANUAL';
105 
106 
107 /*--------------------------------------------------------------------
108  | NAME:
109  |     payment_stop_request
110  |
111  |
112  | PURPOSE:For Initiating the payment stop process. This procedure should be
113  | called only by AP. This should not be called by IBY.
114  |
115  |
116  | PARAMETERS:
117  |     IN      p_payment_id      -- id of the payment.
118  |             p_requested_by   -- User id of person who issued the void request.
119  |                                 This id will be stored as an attribute of the
120  |                                 payment.
121  |             p_request_reason
122  |             p_request_reference
123  |             p_request_date
124  |
125  |     OUT
126  |            x_return_status - Result of the API call:
127  |                                FND_API.G_RET_STS_SUCCESS indicates that a
128  |                                  callout was invoked successfully.
129  |                                  In this case the caller must COMMIT
130  |                                  the status change.
131  |
132  |                                FND_API.G_RET_STS_UNEXP_ERROR (or other) indicates
133  |                                  that API did not complete successfully.
134  |                                  In this case, the caller must issue a
135  |                                  ROLLBACK to undo all status changes.
136  |             x_msg_count
137  |             x_msg_data
138  |
139  |
140  | NOTES:
141  |
142  *---------------------------------------------------------------------*/
143  PROCEDURE payment_stop_request (
144         p_payment_id		     IN  NUMBER,
145         p_requested_by       IN  NUMBER,
146         p_request_reason     IN  VARCHAR2,
147         p_request_reference  IN  VARCHAR2,
148         p_request_date       IN  DATE,
149         x_return_status	  OUT nocopy VARCHAR2,
150         x_msg_count		    OUT nocopy NUMBER,
151         x_msg_data		    OUT nocopy VARCHAR2)
152   IS
153        l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
154                                          || '.payment_stop_request';
155 
156   BEGIN
157           print_debuginfo(l_module_name, 'ENTER');
158 
159           UPDATE iby_payments_all
160           SET STOP_REQUEST_PLACED_FLAG = 'Y',
161               STOP_REQUEST_PLACED_BY = p_requested_by,
162               STOP_REQUEST_REASON = p_request_reason,
163               STOP_REQUEST_REFERENCE= p_request_reference,
164               STOP_REQUEST_DATE = p_request_date,
165               STOP_RELEASED_FLAG = 'N',
166               STOP_RELEASED_BY = NULL,
167               STOP_RELEASE_DATE = NULL,
168               STOP_RELEASE_REASON = NULL,
169               STOP_RELEASE_REFERENCE = NULL
170 
171           WHERE
172               PAYMENT_ID = p_payment_id;
173 
174          x_return_status := FND_API.G_RET_STS_SUCCESS;
175            print_debuginfo(l_module_name, 'EXIT');
176 
177           EXCEPTION
178             WHEN OTHERS THEN
179                   x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
180                    x_msg_count := 1;
181                    x_msg_data := substr(SQLERRM,1,25);
182 
183                print_debuginfo(l_module_name, 'EXIT');
184   END payment_stop_request;
185 
186 
187   /*--------------------------------------------------------------------
188  | NAME:
189  |     payment_stop_release
190  |
191  |
192  | PURPOSE:For Releasing the stop request . This procedure should be
193  | called only by AP. This should not be called by IBY.
194  |
195  |
196  | PARAMETERS:
197  |     IN      p_payment_id      -- payment id
198  |             p_released_by   -- User id of person who issued the void request.
199  |                                 This id will be stored as an attribute of the
200  |                                 payment.
201  |             p_release_reason
202  |             p_release_reference
203  |             p_release_date
204  |
205  |     OUT     x_return_status - Result of the API call:
206  |                                FND_API.G_RET_STS_SUCCESS indicates that a
207  |                                  callout was invoked successfully.
208  |                                  In this case the caller must COMMIT
209  |                                  the status change.
210  |
211  |                                FND_API.G_RET_STS_UNEXP_ERROR (or other) indicates
212  |                                  that API did not complete successfully.
213  |                                  In this case, the caller must issue a
214  |                                  ROLLBACK to undo all status changes.
215  |             x_msg_count
216  |             x_msg_data
217  |
218  |
219  | NOTES:
220  |
221  *---------------------------------------------------------------------*/
222  PROCEDURE payment_stop_release (
223         p_payment_id		     IN  NUMBER,
224         p_released_by        IN  NUMBER,
225         p_release_reason     IN  VARCHAR2,
226         p_release_reference  IN  VARCHAR2,
227         p_release_date       IN  DATE,
228         x_return_status	     OUT nocopy VARCHAR2,
229         x_msg_count		       OUT nocopy NUMBER,
230         x_msg_data		       OUT nocopy VARCHAR2)
231   IS
232      l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
233                                          || '.payment_stop_release';
234   BEGIN
235           print_debuginfo(l_module_name, 'ENTER');
236 
237           UPDATE iby_payments_all
238           SET STOP_RELEASED_FLAG = 'Y',
239               STOP_RELEASED_BY = p_released_by,
240               STOP_RELEASE_DATE = p_release_date,
241               STOP_RELEASE_REASON = p_release_reason,
242               STOP_RELEASE_REFERENCE = p_release_reference
243 
244           WHERE
245               PAYMENT_ID = p_payment_id;
246 
247          x_return_status := FND_API.G_RET_STS_SUCCESS;
248            print_debuginfo(l_module_name, 'EXIT');
249 
250           EXCEPTION
251             WHEN OTHERS THEN
252                   x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
253                    x_msg_count := 1;
254                    x_msg_data := substr(SQLERRM,1,25);
255 
256                print_debuginfo(l_module_name, 'EXIT');
257 
258   END payment_stop_release;
259 
260 
261 
262 
263 
264 /*--------------------------------------------------------------------
265  | NAME:
266  |     remove_document_payable
267  |
268  | PURPOSE:
269  |     Invokes the callout of the calling app to remove a submitted
270  |     document payable from the payment processing cycle.
271  |
272  |     The calling application can free up the removed document, and
273  |     make it available for submission in a future payment request.
274  |
275  | PARAMETERS:
276  |     IN
277  |       p_doc_id        - ID of the document payable to be removed.
278  |       p_doc_status    - Current status of the document payable to
279  |                         be removed.
280  |
281  |     OUT
282  |       x_return_status - Result of the API call:
283  |                         FND_API.G_RET_STS_SUCCESS indicates that a
284  |                           callout was invoked successfully.
285  |                           In this case the caller must COMMIT
286  |                           the status change.
287  |
288  |                         FND_API.G_RET_STS_ERROR (or other) indicates
289  |                           that API did not complete successfully.
290  |                           In this case, the caller must issue a
291  |                           ROLLBACK to undo all status changes.
292  |
293  | RETURNS:
294  |
295  | NOTES:
296  |   Internal API, not for public use.
297  |
298  |   This API will not do a COMMIT. It is the the callers responsbility
299  |   to perform COMMIT / ROLLBACK depending upon the returned status.
300  |
301  |   The callout invoked must be handled synchronously by the
302  |   calling application. So the COMMIT / ROLLBACK should affect
303  |   the changes made to the database by the calling application as
304  |   well. This will ensure that IBY and the calling application are
305  |   in sync w.r.t. to the specified document payable.
306  |
307  *---------------------------------------------------------------------*/
308  PROCEDURE remove_document_payable (
309      p_doc_id         IN NUMBER,
310      p_doc_status     IN VARCHAR2,
311      x_return_status  OUT NOCOPY VARCHAR2
312      )
313  IS
314 
315  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
316                                          || '.remove_document_payable';
317 
318  l_rejection_id   NUMBER(15);
319 
320  /* used in forming callout procedure name */
321  l_calling_app_id NUMBER;
322  l_app_short_name VARCHAR2(200);
323  l_pkg_name       VARCHAR2(200);
324  l_callout_name   VARCHAR2(500);
325  l_stmt           VARCHAR2(1000);
326 
327  /* used in invocation of callout procedure */
328  l_api_version    CONSTANT NUMBER := 1.0;
329  l_msg_count      NUMBER;
330  l_msg_data       VARCHAR2(2000);
331 
332  /*
333   * Implementing the callout is optional for the calling app.
334   * If the calling app does not implement the hook, then
335   * the call to the hook will result in ORA-06576 error.
336   *
337   * There is no exception name associated with this code, so
338   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
339   * exception occurs, it is not fatal: we log the error and
340   * proceed.
341   *
342   * If, on the other hand, the calling app implements the
343   * callout, but the callout throws an exception, it is fatal
344   * and we must abort the program (this will be caught
345   * in WHEN OTHERS block).
346   */
347  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
348  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
349 
350  BEGIN
351 
352      print_debuginfo(l_module_name, 'ENTER');
353 
354      FND_MSG_PUB.initialize;
355 
356      /*
357       * STATUS CHANGE:
358       *
359       * UI Responsibility:
360       * document status = REMOVED
361       *
362       * API Responsibility:
363       * NONE
364       */
365 
366      /*
367       * Get the next available rejected document group id.
368       */
369      SELECT
370          IBY_REJECTED_DOCS_GROUP_S.NEXTVAL
371      INTO
372          l_rejection_id
373      FROM
374          DUAL
375      ;
376 
377      /*
378       * Update the removed document with the rejected document
379       * group id. The calling application will identify rejected
380       * documents using this id.
381       */
382      UPDATE
383          IBY_DOCS_PAYABLE_ALL
384      SET
385          rejected_docs_group_id = l_rejection_id
386      WHERE
387          document_payable_id = p_doc_id        AND
388          document_status     = p_doc_status
389      ;
390 
391      /*
392       * Get the application name of the calling app. This
393       * will be used in the callout.
394       */
395      SELECT
396          fnd.application_short_name
397      INTO
398          l_app_short_name
399      FROM
400          FND_APPLICATION      fnd,
401          IBY_DOCS_PAYABLE_ALL doc
402      WHERE
403          fnd.application_id      = doc.calling_app_id AND
404          doc.document_payable_id = p_doc_id
405      ;
406 
407      /*
408       * Get the constructed package name to use in the
409       * call out.
410       */
411      l_pkg_name := construct_callout_pkg_name(l_app_short_name);
412 
413      print_debuginfo(l_module_name, 'Constructed package name: '
414          || l_pkg_name);
415 
416      IF (l_pkg_name IS NULL) THEN
417 
418          print_debuginfo(l_module_name, 'Package name is null. '
419              || 'Raising exception.');
420 
421          APP_EXCEPTION.RAISE_EXCEPTION;
422 
423      END IF;
424 
425 
426      /*
427       * Now try to call the external app's implementation of the hook.
428       * The calling app may or may not have implemented the hook, so
429       * it's not fatal if the implementation does not exist.
430       */
431      l_callout_name := l_pkg_name || '.' || 'documents_payable_rejected';
432 
433      print_debuginfo(l_module_name, 'Attempting to invoke callout: '
434          || l_callout_name);
435 
436      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7)';
437 
438      BEGIN
439 
440          EXECUTE IMMEDIATE
441              (l_stmt)
442          USING
443              IN  l_api_version,
444              IN  FND_API.G_FALSE,
445              IN  FND_API.G_FALSE,
446              OUT x_return_status,
447              OUT l_msg_count,
448              OUT l_msg_data,
449              IN  l_rejection_id
450          ;
451 
452          /*
453           * If the called procedure did not return success,
454           * raise an exception.
455           */
456          IF (x_return_status IS NULL OR
457              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
458 
459              print_debuginfo(l_module_name, 'Fatal: External app callout '''
460                  || l_callout_name
461                  || ''', returned failure status - '
462                  || x_return_status
463                  || '. Raising exception.'
464                  );
465 
466              APP_EXCEPTION.RAISE_EXCEPTION;
467 
468          END IF;
469 
470      EXCEPTION
471 
472          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
473              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
474                  || '" not implemented by calling app '
475                  || l_app_short_name || '.');
476 
477              print_debuginfo(l_module_name, 'Skipping hook call.');
478 
479 
480          WHEN OTHERS THEN
481              print_debuginfo(l_module_name, 'Fatal: External app callout '''
482                  || l_callout_name
483                  || ''', generated exception.'
484                  );
485 
486              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
487              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
488              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
489 
490              /*
491               * Propogate exception to caller.
492               */
493              RAISE;
494      END;
495 
496      x_return_status := FND_API.G_RET_STS_SUCCESS;
497 
498      print_debuginfo(l_module_name, 'EXIT');
499 
500  EXCEPTION
501 
502      WHEN OTHERS THEN
503 
504          print_debuginfo(l_module_name, 'Exception occured when '
505              || 'removing document payable '
506              || p_doc_id
507              || ', with status '
508              || p_doc_status
509              );
510 
511          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
512          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
513          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
514          x_return_status := FND_API.G_RET_STS_ERROR;
515 
516          print_debuginfo(l_module_name, 'EXIT');
517 
518  END remove_document_payable;
519 
520 /*--------------------------------------------------------------------
521  | NAME:
522  |     remove_documents_payable
523  |
524  | PURPOSE:
525  |     Invokes a series of callouts to the calling app to remove
526  |     a set of submitted documents payable from the payment processing
527  |     cycle.
528  |
529  |     The calling application can free up the removed documents, and
530  |     make them available for submission in future payment request(s).
531  |
532  | PARAMETERS:
533  |     IN
534  |       p_doc_list        - IDs of the documents payable to be removed.
535  |                           This should be an array of document payable ids.
536  |
537  |       p_doc_status_list - Current statuses of the documents payable to
538  |                           be removed. This should be an array of statuses.
539  |
540  |     OUT
541  |       x_return_status   - Result of the API call:
542  |                         FND_API.G_RET_STS_SUCCESS indicates that all
543  |                           callouts were invoked successfully.
544  |                           In this case the caller must COMMIT
545  |                           the status changes.
546  |
547  |                         FND_API.G_RET_STS_ERROR (or other) indicates
548  |                           that at least one event did not complete
549  |                           successfully. In this case, the caller must
550  |                           issue a ROLLBACK to undo all status changes.
551  |
552  | RETURNS:
553  |
554  | NOTES:
555  |   This API will not do a COMMIT. It is the the callers responsbility
556  |   to perform COMMIT / ROLLBACK depending upon the returned status.
557  |
558  |   The callouts invoked must be handled synchronously by the
559  |   calling application. So the COMMIT / ROLLBACK should affect
560  |   the changes made to the database by the calling application as
561  |   well. This will ensure that IBY and the calling application are
562  |   in sync w.r.t. to the specified documents payable.
563  |
564  *---------------------------------------------------------------------*/
565  PROCEDURE remove_documents_payable (
566      p_doc_list         IN docPayIDTab,
567      p_doc_status_list  IN docPayStatusTab,
568      x_return_status    OUT NOCOPY VARCHAR2
569      )
570  IS
571 
572  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
573                                          || '.remove_documents_payable';
574  BEGIN
575 
576      print_debuginfo(l_module_name, 'ENTER');
577 
578      FND_MSG_PUB.initialize;
579 
580      IF (p_doc_list.COUNT = 0 OR p_doc_status_list.COUNT = 0) THEN
581 
582          print_debuginfo(l_module_name, 'Error: List of document '
583              || 'payable ids/statuses is empty'
584              || '. Returning failure response .. '
585              );
586 
587          x_return_status := FND_API.G_RET_STS_ERROR;
588 
589          print_debuginfo(l_module_name, 'EXIT');
590 
591          RETURN;
592 
593      END IF;
594 
595      IF (p_doc_list.COUNT <> p_doc_status_list.COUNT) THEN
596 
597          print_debuginfo(l_module_name, 'Error: List of document '
598              || 'payable ids must match list of document payable '
599              || 'statuses'
600              || '. Returning failure response .. '
601              );
602 
603          x_return_status := FND_API.G_RET_STS_ERROR;
604 
605          print_debuginfo(l_module_name, 'EXIT');
606 
607          RETURN;
608 
609      END IF;
610 
611      /*
612       * Start processing the documents payable, one-by-one.
613       */
614      FOR i IN p_doc_list.FIRST .. p_doc_list.LAST LOOP
615 
616          remove_document_payable (
617              p_doc_list(i),
618              p_doc_status_list(i),
619              x_return_status
620              );
621 
622          /*
623           * Check if the call to remove the document
624           * payable succeeded.
625           */
626          IF (x_return_status IS NULL OR
627 	     x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
628 
629              /*
630               * Even if a single call to remove a doc payable
631               * failed, return failure for the entire API request.
632               */
633              print_debuginfo(l_module_name, 'Removing of document '
634                  || p_doc_list(i)
635                  || ' failed.'
636                  );
637 
638              print_debuginfo(l_module_name, 'EXIT');
639 
640              /*
641               * It is the callers responsibility to rollback
642               * all the changes.
643               */
644              RETURN;
645 
646          END IF;
647 
648      END LOOP;
649 
650      x_return_status := FND_API.G_RET_STS_SUCCESS;
651 
652      print_debuginfo(l_module_name, 'Returning success response ..');
653 
654      print_debuginfo(l_module_name, 'EXIT');
655 
656  END remove_documents_payable;
657 
658 /*--------------------------------------------------------------------
659  | NAME:
660  |     remove_payment
661  |
662  |
663  | PURPOSE:
664  |     Invokes a callout of the calling app to remove a set of
665  |     submitted documents payable from the payment processing
666  |     cycle.
667  |
668  |     The calling application can free up the removed documents, and
669  |     make them available for submission in future payment request(s).
670  |
671  | PARAMETERS:
672  |     IN
673  |       p_pmt_id          - ID of the payment to be removed.
674  |
675  |       p_pmt_status_list - Current status of the payment to
676  |                           be removed.
677  |
678  |     OUT
679  |       x_return_status   - Result of the API call:
680  |                         FND_API.G_RET_STS_SUCCESS indicates that
681  |                           the callout was invoked successfully.
682  |                           In this case the caller must COMMIT
683  |                           the status changes.
684  |
685  |                         FND_API.G_RET_STS_ERROR (or other) indicates
686  |                           that tha API did not complete successfully.
687  |                           In this case, the caller must issue a
688  |                           ROLLBACK to undo all status changes.
689  |
690  | RETURNS:
691  |
692  | NOTES:
693  |   Internal API, not for public use.
694  |
695  |   This API will not do a COMMIT. It is the the callers responsibility
696  |   to perform COMMIT / ROLLBACK depending upon the returned status.
697  |
698  |   The callout invoked must be handled synchronously by the
699  |   calling application. So the COMMIT / ROLLBACK should affect
700  |   the changes made to the database by the calling application as
701  |   well. This will ensure that IBY and the calling application are
702  |   in sync w.r.t. to the specified documents payable.
703  |
704  *---------------------------------------------------------------------*/
705  PROCEDURE remove_payment (
706      p_pmt_id         IN NUMBER,
707      p_pmt_status     IN VARCHAR2,
708      x_return_status  OUT NOCOPY VARCHAR2
709      )
710  IS
711 
712  l_module_name    CONSTANT VARCHAR2(200) := G_PKG_NAME || '.remove_payment';
713 
714  l_rejection_id   NUMBER(15);
715 
716  /* used in forming callout procedure name */
717  l_calling_app_id NUMBER;
718  l_app_short_name VARCHAR2(200);
719  l_pkg_name       VARCHAR2(200);
720  l_callout_name   VARCHAR2(500);
721  l_stmt           VARCHAR2(1000);
722 
723  /* used in invocation of callout procedure */
724  l_api_version    CONSTANT NUMBER := 1.0;
725  l_msg_count      NUMBER;
726  l_msg_data       VARCHAR2(2000);
727 
728  /*
729   * Implementing the callout is optional for the calling app.
730   * If the calling app does not implement the hook, then
731   * the call to the hook will result in ORA-06576 error.
732   *
733   * There is no exception name associated with this code, so
734   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
735   * exception occurs, it is not fatal: we log the error and
736   * proceed.
737   *
738   * If, on the other hand, the calling app implements the
739   * callout, but the callout throws an exception, it is fatal
740   * and we must abort the program (this will be caught
741   * in WHEN OTHERS block).
742   */
743  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
744  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
745 
746  BEGIN
747 
748      print_debuginfo(l_module_name, 'ENTER');
749 
750      FND_MSG_PUB.initialize;
751 
752      /*
753       * STATUS CHANGE:
754       *
755       * UI Responsibility:
756       * payment status = REMOVED
757       *
758       * API Responsibility:
759       * document_status = REMOVED_PAYMENT_REMOVED
760       */
761      UPDATE
762          IBY_DOCS_PAYABLE_ALL
763      SET
764          document_status = DOC_STATUS_PMT_REMOVED,
765 
766          /*
767           * Fix for bug 4405981:
768           *
769           * The straight through flag should be set to 'N',
770           * if the document was rejected / required manual
771           * intervention.
772           */
773          straight_through_flag = 'N'
774      WHERE
775          payment_id = p_pmt_id
776      ;
777 
778      /*
779       * Get the next available rejected document group id.
780       */
781      SELECT
782          IBY_REJECTED_DOCS_GROUP_S.NEXTVAL
783      INTO
784          l_rejection_id
785      FROM
786          DUAL
787      ;
788 
789      /*
790       * Update the removed documents with the rejected document
791       * group id. The calling application will identify rejected
792       * documents using this id.
793       */
794      UPDATE
795          IBY_DOCS_PAYABLE_ALL
796      SET
797          rejected_docs_group_id = l_rejection_id
798      WHERE
799          payment_id = p_pmt_id
800      ;
801 
802      /*
803       * Get the application name of the calling app. This
804       * will be used in the callout.
805       */
806      SELECT
807          fnd.application_short_name
808      INTO
809          l_app_short_name
810      FROM
811          FND_APPLICATION           fnd,
812          IBY_PAYMENTS_ALL          pmt,
813          IBY_PAY_SERVICE_REQUESTS  req
814      WHERE
815          fnd.application_id             = req.calling_app_id             AND
816          req.payment_service_request_id = pmt.payment_service_request_id AND
817          pmt.payment_id                 = p_pmt_id
818      ;
819 
820      /*
821       * Get the constructed package name to use in the
822       * call out.
823       */
824      l_pkg_name := construct_callout_pkg_name(l_app_short_name);
825 
826      print_debuginfo(l_module_name, 'Constructed package name: '
827          || l_pkg_name);
828 
829      IF (l_pkg_name IS NULL) THEN
830 
831          print_debuginfo(l_module_name, 'Package name is null. '
832              || 'Raising exception.');
833 
834          APP_EXCEPTION.RAISE_EXCEPTION;
835 
836      END IF;
837 
838      /*
839       * Now try to call the external app's implementation of the hook.
840       * The calling app may or may not have implemented the hook, so
841       * it's not fatal if the implementation does not exist.
842       */
843      l_callout_name := l_pkg_name || '.' || 'documents_payable_rejected';
844 
845      print_debuginfo(l_module_name, 'Attempting to invoke callout: '
846          || l_callout_name);
847 
848      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7)';
849 
850      BEGIN
851 
852          EXECUTE IMMEDIATE
853              (l_stmt)
854          USING
855              IN  l_api_version,
856              IN  FND_API.G_FALSE,
857              IN  FND_API.G_FALSE,
858              OUT x_return_status,
859              OUT l_msg_count,
860              OUT l_msg_data,
861              IN  l_rejection_id
862          ;
863 
864          /*
865           * If the called procedure did not return success,
866           * raise an exception.
867           */
868          IF (x_return_status IS NULL OR
869              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
870 
871              print_debuginfo(l_module_name, 'Fatal: External app callout '''
872                  || l_callout_name
873                  || ''', returned failure status - '
874                  || x_return_status
875                  || '. Raising exception.'
876                  );
877 
878              APP_EXCEPTION.RAISE_EXCEPTION;
879 
880          END IF;
881 
882      EXCEPTION
883 
884          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
885              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
886                  || '" not implemented by calling app '
887                  || l_app_short_name || '.');
888 
889              print_debuginfo(l_module_name, 'Skipping hook call.');
890 
891 
892          WHEN OTHERS THEN
893              print_debuginfo(l_module_name, 'Fatal: External app callout '''
894                  || l_callout_name
895                  || ''', generated exception.'
896                  );
897 
898              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
899              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
900              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
901 
902              /*
903               * Propogate exception to caller.
904               */
905              RAISE;
906      END;
907 
908 
909      x_return_status := FND_API.G_RET_STS_SUCCESS;
910 
911      print_debuginfo(l_module_name, 'EXIT');
912 
913  EXCEPTION
914 
915      WHEN OTHERS THEN
916 
917          print_debuginfo(l_module_name, 'Exception occured when '
918              || 'removing payment '
919              || p_pmt_id
920              || ', with status '
921              || p_pmt_status
922              );
923 
924          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
925          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
926          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
927 
928          x_return_status := FND_API.G_RET_STS_ERROR;
929 
930          print_debuginfo(l_module_name, 'EXIT');
931 
932  END remove_payment;
933 
934 /*--------------------------------------------------------------------
935  | NAME:
936  |     remove_payments
937  |
938  | PURPOSE:
939  |     Invokes a series of callouts of the calling app to remove
940  |     a set of submitted documents payable from the payment processing
941  |     cycle.
942  |
943  |     The calling application can free up the removed documents, and
944  |     make them available for submission in future payment request(s).
945  |
946  | PARAMETERS:
947  |     IN
948  |       p_pmt_list        - IDs of the payments to be removed.
949  |                           This should be an array of payment ids. All
950  |                           the child documents payable of each of the
951  |                           specified payments will be removed.
952  |
953  |       p_pmt_status_list - Current statuses of the payments to
954  |                           be removed. This should be an array of statuses.
955  |
956  |     OUT
957  |       x_return_status   - Result of the API call:
958  |                         FND_API.G_RET_STS_SUCCESS indicates that all
959  |                           the callouts were invoked successfully.
960  |                           In this case the caller must COMMIT
961  |                           the status changes.
962  |
963  |                         FND_API.G_RET_STS_ERROR (or other) indicates
964  |                           that at least one event did not complete
965  |                           successfully. In this case, the caller must
966  |                           issue a ROLLBACK to undo all status changes.
967  |
968  | RETURNS:
969  |
970  | NOTES:
971  |   Internal API, not for public use.
972  |
973  |   This API will not do a COMMIT. It is the the callers responsbility
974  |   to perform COMMIT / ROLLBACK depending upon the returned status.
975  |
976  |   The callouts invoked must be handled synchronously by the
977  |   calling application. So the COMMIT / ROLLBACK should affect
978  |   the changes made to the database by the calling application as
979  |   well. This will ensure that IBY and the calling application are
980  |   in sync w.r.t. to the specified documents payable.
981  |
982  *---------------------------------------------------------------------*/
983  PROCEDURE remove_payments (
984      p_pmt_list         IN pmtIDTab,
985      p_pmt_status_list  IN pmtStatusTab,
986      x_return_status    OUT NOCOPY VARCHAR2
987      )
988  IS
989 
990  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME || '.remove_payments';
991 
992  BEGIN
993 
994      print_debuginfo(l_module_name, 'ENTER');
995 
996      FND_MSG_PUB.initialize;
997 
998      IF (p_pmt_list.COUNT = 0 OR p_pmt_status_list.COUNT = 0) THEN
999 
1000          print_debuginfo(l_module_name, 'Error: List of payment '
1001              || 'payable ids/statuses is empty'
1002              || '. Returning failure response .. '
1003              );
1004 
1005          x_return_status := FND_API.G_RET_STS_ERROR;
1006 
1007          print_debuginfo(l_module_name, 'EXIT');
1008 
1009          RETURN;
1010 
1011      END IF;
1012 
1013      IF (p_pmt_list.COUNT <> p_pmt_status_list.COUNT) THEN
1014 
1015          print_debuginfo(l_module_name, 'Error: List of payment '
1016              || 'ids must match list of payment statuses. '
1017              || 'Returning failure response .. '
1018              );
1019 
1020          x_return_status := FND_API.G_RET_STS_ERROR;
1021 
1022          print_debuginfo(l_module_name, 'EXIT');
1023 
1024          RETURN;
1025 
1026      END IF;
1027 
1028      /*
1029       * Start processing the payments, one-by-one.
1030       */
1031      FOR i IN p_pmt_list.FIRST .. p_pmt_list.LAST LOOP
1032 
1033          remove_payment (
1034              p_pmt_list(i),
1035              p_pmt_status_list(i),
1036              x_return_status
1037              );
1038 
1039          /*
1040           * Check if the call to remove the payment succeeded.
1041           */
1042          IF (x_return_status IS NULL OR
1043 	     x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1044 
1045              /*
1046               * Even if a single call to remove a payment
1047               * failed, return failure for the entire API request.
1048               */
1049              print_debuginfo(l_module_name, 'Removing of payment '
1050                  || p_pmt_list(i)
1051                  || ' failed.'
1052                  );
1053 
1054              print_debuginfo(l_module_name, 'EXIT');
1055 
1056              /*
1057               * It is the callers responsibility to rollback
1058               * all the changes.
1059               */
1060              RETURN;
1061 
1062          END IF;
1063 
1064      END LOOP;
1065 
1066      x_return_status := FND_API.G_RET_STS_SUCCESS;
1067 
1068      print_debuginfo(l_module_name, 'Returning success response ..');
1069 
1070      print_debuginfo(l_module_name, 'EXIT');
1071 
1072  END remove_payments;
1073 
1074 /*--------------------------------------------------------------------
1075  | NAME:
1076  |     remove_payment_request
1077  |
1078  | PURPOSE:
1079  |     Invokes a series of callouts of the calling app to remove
1080  |     all the submitted documents payable of the given payment request
1081  |     from the payment processing cycle.
1082  |
1083  |     The calling application can free up the removed documents, and
1084  |     make them available for submission in future payment request(s).
1085  |
1086  | PARAMETERS:
1087  |     IN
1088  |       p_payreq_id       - ID of the payment request which must be removed.
1089  |                           All documents payable associated with the
1090  |                           specified payment request will be removed.
1091  |
1092  |     OUT
1093  |       x_return_status   - Result of the API call:
1094  |                         FND_API.G_RET_STS_SUCCESS indicates that all
1095  |                           the callouts were invoked successfully.
1096  |                           In this case the caller must COMMIT
1097  |                           the status changes.
1098  |
1099  |                         FND_API.G_RET_STS_ERROR (or other) indicates
1100  |                           that at least one event did not complete
1101  |                           successfully. In this case, the caller must
1102  |                           issue a ROLLBACK to undo all status changes.
1103  |
1104  | RETURNS:
1105  |
1106  | NOTES:
1107  |   Internal API, not for public use.
1108  |
1109  |   This API will not do a COMMIT. It is the the callers responsbility
1110  |   to perform COMMIT / ROLLBACK depending upon the returned status.
1111  |
1112  |   The callouts invoked must be handled synchronously by the
1113  |   calling application. So the COMMIT / ROLLBACK should affect
1114  |   the changes made to the database by the calling application as
1115  |   well. This will ensure that IBY and the calling application are
1116  |   in sync w.r.t. to the specified documents payable.
1117  |
1118  *---------------------------------------------------------------------*/
1119  PROCEDURE remove_payment_request (
1120      p_payreq_id        IN  NUMBER,
1121      x_return_status    OUT NOCOPY VARCHAR2
1122      )
1123  IS
1124 
1125  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME ||
1126                                              '.remove_payment_request';
1127 
1128  l_docs_list        IBY_VALIDATIONSETS_PUB.rejectedDocTabType;
1129  l_doc_id_list      docPayIDTab;
1130  l_doc_status_list  docPayStatusTab;
1131 
1132  /*
1133   * Cursor to get list of documents along with their statuses for
1134   * the given payment service request.
1135   */
1136  CURSOR c_docs (p_payreq_id IBY_PAY_SERVICE_REQUESTS.
1137                                 payment_service_request_id%TYPE)
1138  IS
1139  SELECT
1140      doc.document_payable_id,
1141      doc.document_status
1142  FROM
1143      IBY_DOCS_PAYABLE_ALL doc
1144  WHERE
1145      doc.payment_service_request_id = p_payreq_id
1146  ;
1147 
1148  BEGIN
1149 
1150      print_debuginfo(l_module_name, 'ENTER');
1151 
1152      FND_MSG_PUB.initialize;
1153 
1154      /*
1155       * Pick up all documents for this payment request.
1156       */
1157      OPEN  c_docs(p_payreq_id);
1158      FETCH c_docs BULK COLLECT INTO l_docs_list;
1159      CLOSE c_docs;
1160 
1161      IF (l_docs_list.COUNT <> 0) THEN
1162 
1163          /*
1164           * Separate out the payment ids and the payment statuses.
1165           * This is because the rejection API expects these as
1166           * separate arrays.
1167           */
1168          FOR i IN l_docs_list.FIRST .. l_docs_list.LAST LOOP
1169              l_doc_id_list(i) := l_docs_list(i).doc_id;
1170          END LOOP;
1171 
1172          FOR i IN l_docs_list.FIRST .. l_docs_list.LAST LOOP
1173              l_doc_status_list(i) := l_docs_list(i).doc_status;
1174          END LOOP;
1175 
1176          /*
1177           * Now, remove all the documents of this request.
1178           */
1179          remove_documents_payable (
1180              l_doc_id_list,
1181              l_doc_status_list,
1182              x_return_status
1183              );
1184 
1185          /*
1186           * Check if the call to remove the documents succeeded.
1187           */
1188          IF (x_return_status IS NULL OR
1189 	     x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1190 
1191              /*
1192               * Even if a single call to remove a document
1193               * failed, return failure for the entire API request.
1194               */
1195              print_debuginfo(l_module_name, 'Removing of documents '
1196                  || 'for payment request '
1197                  || p_payreq_id
1198                  || ' failed.'
1199                  );
1200 
1201              print_debuginfo(l_module_name, 'EXIT');
1202 
1203              /*
1204               * It is the callers responsibility to rollback
1205               * all the changes.
1206               */
1207              RETURN;
1208 
1209          END IF;
1210 
1211      ELSE
1212 
1213          print_debuginfo(l_module_name, 'No documents were found for '
1214              || 'payment request id '
1215              || p_payreq_id
1216              || '. Skipping ..'
1217              );
1218 
1219      END IF;
1220 
1221      x_return_status := FND_API.G_RET_STS_SUCCESS;
1222 
1223      print_debuginfo(l_module_name, 'Returning success response ..');
1224 
1225      print_debuginfo(l_module_name, 'EXIT');
1226 
1227  END remove_payment_request;
1228 
1229 /*--------------------------------------------------------------------
1230  | NAME:
1231  |     stop_payment
1232  |
1233  |
1234  | PURPOSE:
1235  |     Invokes a callout of the calling app to remove a set of
1236  |     submitted documents payable from the payment processing
1237  |     cycle.
1238  |
1239  |     The calling application can free up the removed documents, and
1240  |     make them available for submission in future payment request(s).
1241  |
1242  | PARAMETERS:
1243  |     IN
1244  |       p_pmt_id          - ID of the payment to be stopped.
1245  |
1246  |       p_pmt_status_list - Current status of the payment to
1247  |                           be stopped.
1248  |
1249  |     OUT
1250  |       x_return_status   - Result of the API call:
1251  |                         FND_API.G_RET_STS_SUCCESS indicates that the
1252  |                           callout was invoked successfully.
1253  |                           In this case the caller must COMMIT
1254  |                           the status changes.
1255  |
1256  |                         FND_API.G_RET_STS_ERROR (or other) indicates
1257  |                           that tha API did not complete successfully.
1258  |                           In this case, the caller must issue a
1259  |                           ROLLBACK to undo all status changes.
1260  |
1261  | RETURNS:
1262  |
1263  | NOTES:
1264  |   Internal API, not for public use.
1265  |
1266  |   This API will not do a COMMIT. It is the the callers responsibility
1267  |   to perform COMMIT / ROLLBACK depending upon the returned status.
1268  |
1269  |   The callouts invoked must be handled synchronously by the
1270  |   calling application. So the COMMIT / ROLLBACK should affect
1271  |   the changes made to the database by the calling application as
1272  |   well. This will ensure that IBY and the calling application are
1273  |   in sync w.r.t. to the specified documents payable.
1274  |
1275  *---------------------------------------------------------------------*/
1276  PROCEDURE stop_payment (
1277      p_pmt_id         IN NUMBER,
1278      p_pmt_status     IN VARCHAR2,
1279      x_return_status  OUT NOCOPY VARCHAR2
1280      )
1281  IS
1282 
1283 l_module_name    CONSTANT VARCHAR2(200) := G_PKG_NAME ||'.stop_payment ';
1284 
1285  l_rejection_id   NUMBER(15);
1286 
1287  /* used in forming callout procedure name */
1288  l_calling_app_id NUMBER;
1289  l_app_short_name VARCHAR2(200);
1290  l_pkg_name       VARCHAR2(200);
1291  l_callout_name   VARCHAR2(500);
1292  l_stmt           VARCHAR2(1000);
1293 
1294  /* used in invocation of callout procedure */
1295  l_api_version    CONSTANT NUMBER := 1.0;
1296  l_msg_count      NUMBER;
1297  l_msg_data       VARCHAR2(2000);
1298 
1299 
1300 l_instr_id       IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_id%TYPE;
1301 l_valid_pmts_count NUMBER;
1302 
1303  /*
1304   * Implementing the callout is optional for the calling app.
1305   * If the calling app does not implement the hook, then
1306   * the call to the hook will result in ORA-06576 error.
1307   *
1308   * There is no exception name associated with this code, so
1309   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
1310   * exception occurs, it is not fatal: we log the error and
1311   * proceed.
1312   *
1313   * If, on the other hand, the calling app implements the
1314   * callout, but the callout throws an exception, it is fatal
1315   * and we must abort the program (this will be caught
1316   * in WHEN OTHERS block).
1317   */
1318  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
1319  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
1320 
1321  BEGIN
1322 
1323      print_debuginfo(l_module_name, 'ENTER');
1324 
1325      FND_MSG_PUB.initialize;
1326 
1327      /*
1328       * STATUS CHANGE:
1329       *
1330       * UI Responsibility:
1331       * payment status = REMOVED_PAYMENT_STOPPED
1332       *
1333       * API Responsibility:
1334       * document_status = REMOVED_PAYMENT_STOPPED
1335       */
1336      UPDATE
1337          IBY_DOCS_PAYABLE_ALL
1338      SET
1339          document_status = DOC_STATUS_PMT_STOPPED
1340      WHERE
1341          payment_id = p_pmt_id
1342      ;
1343 
1344      /*
1345       * Get the next available rejected document group id.
1346       */
1347      SELECT
1348          IBY_REJECTED_DOCS_GROUP_S.NEXTVAL
1349      INTO
1350          l_rejection_id
1351      FROM
1352          DUAL
1353      ;
1354 
1355      /*
1356       * Update the removed documents with the rejected document
1357       * group id. The calling application will identify rejected
1358       * documents using this id.
1359       */
1360      UPDATE
1361          IBY_DOCS_PAYABLE_ALL
1362      SET
1363          rejected_docs_group_id = l_rejection_id
1364      WHERE
1365          payment_id = p_pmt_id
1366      ;
1367 
1368 /* Bug 6609931 */
1369 BEGIN
1370 	SELECT
1371 	   instr.payment_instruction_id
1372 	INTO
1373 	   l_instr_id
1374 	FROM
1375 	  IBY_PAY_INSTRUCTIONS_ALL instr,
1376 	  IBY_PAYMENTS_ALL pmt
1377 	WHERE
1378 	  instr.payment_instruction_id = pmt.payment_instruction_id AND
1379 	  pmt.payment_id = p_pmt_id;
1380    EXCEPTION
1381      WHEN NO_DATA_FOUND THEN
1382            l_instr_id:=null;
1383  END;
1384 
1385 /* Bug 7028817*/
1386 /* If the payment is stopped before instruction is created,
1387 should by pass the below logic.
1388 So, having condition based on the instruction id*/
1389 
1390 IF  l_instr_id IS NOT NULL THEN
1391 
1392 	-- get the count of valid payments- which are not stopped, voided, removed
1393 	-- and overfloW/setup payment- these will not have payment reference number
1394 	   SELECT
1395 	       count(*)
1396 	  INTO
1397 	      l_valid_pmts_count
1398 	  FROM
1399 	      IBY_PAYMENTS_ALL pmt
1400 	  WHERE
1401 	    pmt.payment_instruction_id = l_instr_id AND
1402 	    pmt.payment_reference_number is not null AND
1403 	    pmt.payment_status NOT IN
1404 	      (PAY_STATUS_VOID, PAY_STATUS_REMOVED, PAY_STATUS_STOPPED, PAY_STATUS_REJECTED);
1405 
1406 
1407 	print_debuginfo(l_module_name , 'The number of valid payments : ' ||
1408 	l_valid_pmts_count);
1409 
1410 
1411 	  IF (l_valid_pmts_count = 0) THEN
1412 		/*
1413 		 * * Set the payment instruction status to TERMINATED
1414 		 * * because no valid payments now exist for this
1415 		 * * payment instruction.
1416 		 * */
1417 
1418 		UPDATE
1419 		     IBY_PAY_INSTRUCTIONS_ALL
1420 		SET
1421 		    payment_instruction_status = INS_STATUS_TERMINATED
1422 		WHERE
1423 		    payment_instruction_id = l_instr_id;
1424 
1425 			/* Also since the Payment Instruction is terminated
1426 			 * we should be unlocking the payment document which this
1427 			 * instruction may be locking to make it available for other
1428 			 * Done per bug 6852606
1429 			 */
1430 			 print_debuginfo(l_module_name, 'Trying to unlock the payment document as PI termination: ');
1431 			 UPDATE
1432 			     CE_PAYMENT_DOCUMENTS
1433 			 SET
1434 			     payment_instruction_id = NULL,
1435 			     /* Bug 6707369
1436 			      * If some of the documents are skipped, the payment
1437 			      * document's last issued check number must be updated
1438 			      */
1439 			     last_issued_document_number = nvl(
1440 				     (SELECT MAX(pmt.paper_document_number)
1441 				      FROM iby_payments_all pmt
1442 				      WHERE pmt.payment_instruction_id = l_instr_id)
1443 				      ,last_issued_document_number
1444 				      )
1445 			 WHERE
1446 			     payment_instruction_id = l_instr_id;
1447 			 print_debuginfo(l_module_name, 'Payment document unlocking successful for PI : ' || l_instr_id);
1448 
1449 	  END IF;
1450 
1451  END IF;
1452  /* ending if for the condition based on instruction id(Bug 7028817)*/
1453 
1454 
1455      /*
1456       * Get the application name of the calling app. This
1457       * will be used in the callout.
1458       */
1459      SELECT
1460          fnd.application_short_name
1461      INTO
1462          l_app_short_name
1463      FROM
1464          FND_APPLICATION           fnd,
1465          IBY_PAYMENTS_ALL          pmt,
1466          IBY_PAY_SERVICE_REQUESTS  req
1467      WHERE
1468          fnd.application_id             = req.calling_app_id             AND
1469          req.payment_service_request_id = pmt.payment_service_request_id AND
1470          pmt.payment_id                 = p_pmt_id
1471      ;
1472 
1473      /*
1474       * Get the constructed package name to use in the
1475       * call out.
1476       */
1477      l_pkg_name := construct_callout_pkg_name(l_app_short_name);
1478 
1479      print_debuginfo(l_module_name, 'Constructed package name: '
1480          || l_pkg_name);
1481 
1482      IF (l_pkg_name IS NULL) THEN
1483 
1484          print_debuginfo(l_module_name, 'Package name is null. '
1485              || 'Raising exception.');
1486 
1487          APP_EXCEPTION.RAISE_EXCEPTION;
1488 
1489      END IF;
1490 
1491      /*
1492       * Now try to call the external app's implementation of the hook.
1493       * The calling app may or may not have implemented the hook, so
1494       * it's not fatal if the implementation does not exist.
1495       */
1496      l_callout_name := l_pkg_name || '.' || 'documents_payable_rejected';
1497 
1498      print_debuginfo(l_module_name, 'Attempting to invoke callout: '
1499          || l_callout_name);
1500 
1501      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7)';
1502 
1503      BEGIN
1504 
1505          EXECUTE IMMEDIATE
1506              (l_stmt)
1507          USING
1508              IN  l_api_version,
1509              IN  FND_API.G_FALSE,
1510              IN  FND_API.G_FALSE,
1511              OUT x_return_status,
1512              OUT l_msg_count,
1513              OUT l_msg_data,
1514              IN  l_rejection_id
1515          ;
1516 
1517          /*
1518           * If the called procedure did not return success,
1519           * raise an exception.
1520           */
1521          IF (x_return_status IS NULL OR
1522              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1523 
1524              print_debuginfo(l_module_name, 'Fatal: External app callout '''
1525                  || l_callout_name
1526                  || ''', returned failure status - '
1527                  || x_return_status
1528                  || '. Raising exception.'
1529                  );
1530 
1531              APP_EXCEPTION.RAISE_EXCEPTION;
1532 
1533          END IF;
1534 
1535      EXCEPTION
1536 
1537          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
1538              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
1539                  || '" not implemented by calling app '
1540                  || l_app_short_name || '.');
1541 
1542              print_debuginfo(l_module_name, 'Skipping hook call.');
1543 
1544          WHEN OTHERS THEN
1545              print_debuginfo(l_module_name, 'Fatal: External app callout '''
1546                  || l_callout_name
1547                  || ''', generated exception.'
1548                  );
1549 
1550              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
1551              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
1552              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
1553 
1554              /*
1555               * Propogate exception to caller.
1556               */
1557              RAISE;
1558      END;
1559 
1560      x_return_status := FND_API.G_RET_STS_SUCCESS;
1561 
1562      print_debuginfo(l_module_name, 'EXIT');
1563 
1564  EXCEPTION
1565 
1566      WHEN OTHERS THEN
1567 
1568          print_debuginfo(l_module_name, 'Exception occured when '
1569              || 'stopping payment '
1570              || p_pmt_id
1571              || ', with status '
1572              || p_pmt_status
1573              );
1574 
1575          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
1576          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
1577          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
1578 
1579          x_return_status := FND_API.G_RET_STS_ERROR;
1580 
1581          print_debuginfo(l_module_name, 'EXIT');
1582 
1583  END stop_payment;
1584 
1585 /*--------------------------------------------------------------------
1586  | NAME:
1587  |     stop_payments
1588  |
1589  | PURPOSE:
1590  |     Invokes a series of callouts of the calling app to remove
1591  |     a set of submitted documents payable from the payment processing
1592  |     cycle.
1593  |
1594  |     The calling application can free up the removed documents, and
1595  |     make them available for submission in future payment request(s).
1596  |
1597  | PARAMETERS:
1598  |     IN
1599  |       p_pmt_list        - IDs of the payments to be stopped.
1600  |                           This should be an array of payment ids. All
1601  |                           the child documents payable of each of the
1602  |                           specified payments will be removed.
1603  |
1604  |       p_pmt_status_list - Current statuses of the payments to
1605  |                           be stopped. This should be an array of statuses.
1606  |
1607  |     OUT
1608  |       x_return_status   - Result of the API call:
1609  |                         FND_API.G_RET_STS_SUCCESS indicates that all
1610  |                           the callouts were invoked successfully.
1611  |                           In this case the caller must COMMIT
1612  |                           the status changes.
1613  |
1614  |                         FND_API.G_RET_STS_ERROR (or other) indicates
1615  |                           that at least one event did not complete
1616  |                           successfully. In this case, the caller must
1617  |                           issue a ROLLBACK to undo all status changes.
1618  |
1619  | RETURNS:
1620  |
1621  | NOTES:
1622  |   Internal API, not for public use.
1623  |
1624  |   This API will not do a COMMIT. It is the the callers responsbility
1625  |   to perform COMMIT / ROLLBACK depending upon the returned status.
1626  |
1627  |   The callouts invoked must be handled synchronously by the
1628  |   calling application. So the COMMIT / ROLLBACK should affect
1629  |   the changes made to the database by the calling application as
1630  |   well. This will ensure that IBY and the calling application are
1631  |   in sync w.r.t. to the specified documents payable.
1632  |
1633  *---------------------------------------------------------------------*/
1634  PROCEDURE stop_payments (
1635      p_pmt_list         IN pmtIDTab,
1636      p_pmt_status_list  IN pmtStatusTab,
1637      x_return_status    OUT NOCOPY VARCHAR2
1638      )
1639  IS
1640 
1641  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME || '.stop_payments';
1642 
1643  BEGIN
1644 
1645      print_debuginfo(l_module_name, 'ENTER');
1646 
1647      FND_MSG_PUB.initialize;
1648 
1649      IF (p_pmt_list.COUNT = 0 OR p_pmt_status_list.COUNT = 0) THEN
1650 
1651          print_debuginfo(l_module_name, 'Error: List of payment '
1652              || 'payable ids/statuses is empty'
1653              || '. Returning failure response .. '
1654              );
1655 
1656          x_return_status := FND_API.G_RET_STS_ERROR;
1657 
1658          print_debuginfo(l_module_name, 'EXIT');
1659 
1660          RETURN;
1661 
1662      END IF;
1663 
1664      IF (p_pmt_list.COUNT <> p_pmt_status_list.COUNT) THEN
1665 
1666          print_debuginfo(l_module_name, 'Error: List of payment '
1667              || 'ids must match list of payment statuses. '
1668              || 'Returning failure response .. '
1669              );
1670 
1671          x_return_status := FND_API.G_RET_STS_ERROR;
1672 
1673          print_debuginfo(l_module_name, 'EXIT');
1674 
1675          RETURN;
1676 
1677      END IF;
1678 
1679      /*
1680       * Start processing the payments, one-by-one.
1681       */
1682      FOR i IN p_pmt_list.FIRST .. p_pmt_list.LAST LOOP
1683 
1684          stop_payment (
1685              p_pmt_list(i),
1686              p_pmt_status_list(i),
1687              x_return_status
1688              );
1689 
1690          /*
1691           * Check if the call to stop the payment succeeded.
1692           */
1693          IF (x_return_status IS NULL OR
1694 	     x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1695 
1696              /*
1697               * Even if a single call to stop a payment
1698               * failed, return failure for the entire API request.
1699               */
1700              print_debuginfo(l_module_name, 'Stopping of payment '
1701                  || p_pmt_list(i)
1702                  || ' failed.'
1703                  );
1704 
1705              print_debuginfo(l_module_name, 'EXIT');
1706 
1707              /*
1708               * It is the callers responsibility to rollback
1709               * all the changes.
1710               */
1711              RETURN;
1712 
1713          END IF;
1714 
1715      END LOOP;
1716 
1717      x_return_status := FND_API.G_RET_STS_SUCCESS;
1718 
1719      print_debuginfo(l_module_name, 'Returning success response ..');
1720 
1721      print_debuginfo(l_module_name, 'EXIT');
1722 
1723  END stop_payments;
1724 
1725 /*--------------------------------------------------------------------
1726  | NAME:
1727  |     void_payment
1728  |
1729  | PURPOSE:
1730  |     Sets the status of the specified payment id to VOID in the IBY
1731  |     tables. This API is used in the AP void and reissue flow to keep
1732  |     IBY and AP tables in sync.
1733  |
1734  |     This API is meant for AP only and should not be used by the IBY UI.
1735  |     There is a separate API for voiding payments from the IBY UI - see
1736  |     void_pmt_internal(..) method.
1737  |
1738  | PARAMETERS:
1739  |     IN
1740  |       p_api_version   - Version of the API.
1741  |
1742  |       p_init_msg_list - Standard API parameter; default as FND_API.G_FALSE
1743  |
1744  |       p_pmt_id        - ID of the payment to be voided. This id will map
1745  |                         to IBY_PAYMENTS_ALL.PAYMENT_ID column.
1746  |
1747  |       p_voided_by     - User id of person who issued the void request.
1748  |                         This id will be stored as an attribute of the
1749  |                         payment.
1750  |
1751  |       p_void_date     - Date on which the void request was made.
1752  |
1753  |       p_void_reason   - Reason why this payment needs to be voided.
1754  |
1755  |     OUT
1756  |       x_return_status - Standard return status. Possible values are:
1757  |                         FND_API.G_RET_STS_SUCCESS
1758  |                           API completed successfully. Caller must
1759  |                           now COMMIT the database changes.
1760  |
1761  |                         FND_API.G_RET_STS_ERROR
1762  |                           API call failed. Caller must ROLLBACK any
1763  |                           base changes.
1764  |
1765  |       x_msg_count     - Standard msg count
1766  |
1767  |       x_msg_data      - Standard msg data
1768  |
1769  | RETURNS:
1770  |
1771  | NOTES:
1772  |  Public API.
1773  |
1774  |  This API will not do a COMMIT. It is the the callers responsbility
1775  |  to perform COMMIT / ROLLBACK depending upon the returned status.
1776  |
1777  *---------------------------------------------------------------------*/
1778  PROCEDURE void_payment (
1779      p_api_version    IN NUMBER,
1780      p_init_msg_list  IN VARCHAR2 DEFAULT FND_API.G_FALSE,
1781      p_pmt_id         IN NUMBER,
1782      p_voided_by      IN NUMBER,
1783      p_void_date      IN DATE,
1784      p_void_reason    IN VARCHAR2,
1785      x_return_status  OUT NOCOPY VARCHAR2,
1786      x_msg_count      OUT NOCOPY NUMBER,
1787      x_msg_data       OUT NOCOPY VARCHAR2
1788      )
1789  IS
1790 
1791  l_module_name   CONSTANT VARCHAR2(200) := G_PKG_NAME || '.void_payment';
1792  l_calling_app_id NUMBER;
1793 
1794  l_api_version   CONSTANT NUMBER        := 1.0;
1795  l_api_name      CONSTANT VARCHAR2(100) := 'void_payment';
1796 
1797  l_instr_id       IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_id%TYPE;
1798  l_valid_pmts_count
1799                   NUMBER;
1800 
1801  BEGIN
1802 
1803      print_debuginfo(l_module_name, 'ENTER');
1804 
1805      print_debuginfo(l_module_name, 'Parameters passed - '
1806          || 'payment id: '
1807          || p_pmt_id
1808          || ', voided by: '
1809          || p_voided_by
1810          || ', void date: '
1811          || p_void_date
1812          || ', void reason: '
1813          || p_void_reason
1814          );
1815 
1816      /* Standard call to check for API compatibility */
1817      IF NOT FND_API.Compatible_API_Call(
1818                         l_api_version,
1819                         p_api_version,
1820                         l_api_name,
1821                         G_PKG_NAME) THEN
1822 
1823          RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1824 
1825      END IF;
1826 
1827      /* Initialize message list if p_init_msg_list is set to TRUE */
1828      IF FND_API.to_boolean(p_init_msg_list) THEN
1829          FND_MSG_PUB.initialize;
1830      END IF;
1831 
1832      /* Initialize return status */
1833      x_return_status := FND_API.G_RET_STS_SUCCESS;
1834 
1835      /*
1836       * STEP I:
1837       *
1838       * Void the specified payment.
1839       */
1840      UPDATE
1841          IBY_PAYMENTS_ALL
1842      SET
1843          payment_status = PAY_STATUS_VOID,
1844          voided_by      = p_voided_by,
1845          void_date      = p_void_date,
1846          void_reason    = p_void_reason
1847      WHERE
1848          payment_id = p_pmt_id
1849      ;
1850 
1851      print_debuginfo(l_module_name, 'Payment '
1852          || p_pmt_id
1853          || ' set to void status ..'
1854          );
1855 
1856      /*
1857       * STEP II:
1858       *
1859       * Void the documents linked to this payment.
1860       */
1861      UPDATE
1862          IBY_DOCS_PAYABLE_ALL
1863      SET
1864          document_status = DOC_STATUS_PMT_VOIDED
1865      WHERE
1866          payment_id = p_pmt_id
1867      ;
1868 
1869      print_debuginfo(l_module_name, 'Documents of payment '
1870          || p_pmt_id
1871          || ' set to void status ..'
1872          );
1873 
1874      /*
1875       * STEP III:
1876       *
1877       * Fix for bug 5017119:
1878       *
1879       * After voiding this payment, check the payment instruction
1880       * to see whether any non-voided / non-removed payments
1881       * exist for this instruction.
1882       *
1883       * If this payment was the last valid payment on the instruction,
1884       * and we just voided it, then set the status of the instruction
1885       * to TERMINATED to signify that this is the final status for
1886       * the instruction.
1887       */
1888 
1889      /*
1890       * Fix for bug 5108035:
1891       *
1892       * Don't assume that every payment to be voided will have an
1893       * associated payment instruction id; a manual payment will
1894       * not have a payment instruction id for example.
1895       *
1896       *
1897       * Therefore, if we run into an exception when attempting to
1898       * get the payment instruction of the payment to be voided,
1899       * treat it as non-fatal.
1900       */
1901      BEGIN
1902 
1903          SELECT
1904              instr.payment_instruction_id
1905          INTO
1906              l_instr_id
1907          FROM
1908              IBY_PAY_INSTRUCTIONS_ALL instr,
1909              IBY_PAYMENTS_ALL         pmt
1910          WHERE
1911              instr.payment_instruction_id = pmt.payment_instruction_id AND
1912              pmt.payment_id = p_pmt_id
1913          ;
1914 
1915          print_debuginfo(l_module_name, 'Provided payment '
1916              || p_pmt_id
1917              || ' has payment instruction id '
1918              || l_instr_id
1919              || '. Checking this instruction for any remaining '
1920              || 'valid payments ..'
1921              );
1922 
1923          SELECT
1924              count(*)
1925          INTO
1926              l_valid_pmts_count
1927          FROM
1928              IBY_PAYMENTS_ALL pmt
1929          WHERE
1930              pmt.payment_instruction_id = l_instr_id AND
1931              pmt.payment_status NOT IN
1932                  (
1933                   PAY_STATUS_VOID,
1934                   PAY_STATUS_REMOVED
1935                  )
1936          ;
1937 
1938          print_debuginfo(l_module_name, 'Number of remaining valid payments '
1939              || 'for pmt instruction '
1940              || l_instr_id
1941              || ' is '
1942              || l_valid_pmts_count
1943              );
1944 
1945          IF (l_valid_pmts_count = 0) THEN
1946 
1947              /*
1948               * Set the payment instruction status to TERMINATED
1949               * because no valid payments now exist for this
1950               * payment instruction.
1951               */
1952              UPDATE
1953                  IBY_PAY_INSTRUCTIONS_ALL
1954              SET
1955                  payment_instruction_status = INS_STATUS_TERMINATED
1956              WHERE
1957                  payment_instruction_id = l_instr_id
1958              ;
1959 
1960              print_debuginfo(l_module_name, 'Status of payment instruction '
1961                  || l_instr_id
1962                  || ' updated to TERMINATED because it has no remaining '
1963                  || 'valid payments.'
1964                  );
1965 
1966 	/* Also since the Payment Instruction is terminated
1967 	 * we should be unlocking the payment document which this
1968 	 * instruction may be locking to make it available for other
1969 	 * Done per bug 6852606
1970 	 */
1971          print_debuginfo(l_module_name, 'Trying to unlock the payment document as PI termination: ');
1972 	 UPDATE
1973 	     CE_PAYMENT_DOCUMENTS
1974 	 SET
1975 	     payment_instruction_id = NULL,
1976 	     /* Bug 6707369
1977 	      * If some of the documents are skipped, the payment
1978 	      * document's last issued check number must be updated
1979 	      */
1980 	     last_issued_document_number = nvl(
1981 		     (SELECT MAX(pmt.paper_document_number)
1982 		      FROM iby_payments_all pmt
1983 		      WHERE pmt.payment_instruction_id = l_instr_id)
1984 		      ,last_issued_document_number
1985 		      )
1986 	 WHERE
1987 	     payment_instruction_id = l_instr_id;
1988          print_debuginfo(l_module_name, 'Payment document unlocking successful for PI : ' || l_instr_id);
1989 
1990          END IF;
1991 
1992      EXCEPTION
1993 
1994          WHEN OTHERS THEN
1995 
1996              print_debuginfo(l_module_name, 'Non-fatal: Exception occured '
1997                  || 'when attempting to get parent payment instruction of '
1998                  || 'payment '
1999                  || p_pmt_id
2000                  );
2001 
2002              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
2003              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
2004 
2005      END;
2006 
2007      /*
2008       * Standard call to get message count and if count is 1, get
2009       * message info.
2010       */
2011      FND_MSG_PUB.Count_And_Get(
2012                      p_encoded => FND_API.G_FALSE,
2013                      p_count   => x_msg_count,
2014                      p_data    => x_msg_data
2015                      );
2016 
2017      x_return_status := FND_API.G_RET_STS_SUCCESS;
2018      print_debuginfo(l_module_name, 'Returning success response ..');
2019 
2020      print_debuginfo(l_module_name, 'EXIT');
2021 
2022      EXCEPTION
2023 
2024          WHEN OTHERS THEN
2025 
2026              print_debuginfo(l_module_name, 'Exception occured when '
2027                  || 'attempting to void payment id '
2028                  || p_pmt_id
2029                  );
2030 
2031              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
2032              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
2033              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
2034 
2035              x_return_status := FND_API.G_RET_STS_ERROR;
2036 
2037              FND_MSG_PUB.Count_And_Get(
2038                              p_encoded => FND_API.G_FALSE,
2039                              p_count   => x_msg_count,
2040                              p_data    => x_msg_data
2041                              );
2042 
2043              print_debuginfo(l_module_name, 'Returning error response ..');
2044              print_debuginfo(l_module_name, 'EXIT');
2045 
2046              RETURN;
2047 
2048  END void_payment;
2049 
2050 /*--------------------------------------------------------------------
2051  | NAME:
2052  |     void_pmt_internal
2053  |
2054  | PURPOSE:
2055  |     Sets the status of the specified payment id to VOID in the IBY
2056  |     tables. This API is used in the IBY UI to void a payment.
2057  |
2058  |     This API is meant for IBY only and should not be used by AP.
2059  |     There is a separate public API for voiding payments from AP - see
2060  |     void_payment(..) method.
2061  |
2062  | PARAMETERS:
2063  |     IN
2064  |       p_api_version   - Version of the API.
2065  |
2066  |       p_init_msg_list - Standard API parameter; default as FND_API.G_FALSE
2067  |
2068  |       p_pmt_id        - ID of the payment to be voided. This id will map
2069  |                         to IBY_PAYMENTS_ALL.PAYMENT_ID column.
2070  |
2071  |       p_voided_by     - User id of person who issued the void request.
2072  |                         This id will be stored as an attribute of the
2073  |                         payment.
2074  |
2075  |       p_void_date     - Date on which the void request was made.
2076  |
2077  |       p_void_reason   - Reason why this payment needs to be voided.
2078  |
2079  |     OUT
2080  |       x_return_status - Standard return status. Possible values are:
2081  |                         FND_API.G_RET_STS_SUCCESS
2082  |                           API completed successfully. Caller must
2083  |                           now COMMIT the database changes.
2084  |
2085  |                         FND_API.G_RET_STS_ERROR
2086  |                           API call failed. Caller must ROLLBACK any
2087  |                           base changes.
2088  |
2089  |       x_msg_count     - Standard msg count
2090  |
2091  |       x_msg_data      - Standard msg data
2092  |
2093  | RETURNS:
2094  |
2095  | NOTES:
2096  |  Internal API, not for public use.
2097  |
2098  |  This API will not do a COMMIT. It is the the callers responsbility
2099  |  to perform COMMIT / ROLLBACK depending upon the returned status.
2100  |
2101  *---------------------------------------------------------------------*/
2102  PROCEDURE void_pmt_internal (
2103      p_api_version    IN NUMBER,
2104      p_init_msg_list  IN VARCHAR2 DEFAULT FND_API.G_FALSE,
2105      p_pmt_id         IN NUMBER,
2106      p_voided_by      IN NUMBER,
2107      p_void_date      IN DATE,
2108      p_void_reason    IN VARCHAR2,
2109      x_return_status  OUT NOCOPY VARCHAR2,
2110      x_msg_count      OUT NOCOPY NUMBER,
2111      x_msg_data       OUT NOCOPY VARCHAR2
2112      )
2113  IS
2114 
2115  l_module_name   CONSTANT VARCHAR2(200) := G_PKG_NAME || '.void_pmt_internal';
2116  l_calling_app_id NUMBER;
2117 
2118  l_api_version   CONSTANT NUMBER        := 1.0;
2119  l_api_name      CONSTANT VARCHAR2(100) := 'void_pmt_internal';
2120 
2121  /* used in forming callout procedure name */
2122  l_app_short_name VARCHAR2(200);
2123  l_pkg_name       VARCHAR2(200);
2124  l_callout_name   VARCHAR2(500);
2125  l_stmt           VARCHAR2(1000);
2126 
2127  /* used in invocation of callout procedure */
2128  l_msg_count      NUMBER;
2129  l_msg_data       VARCHAR2(2000);
2130 
2131  l_ret_flag       VARCHAR2(1) := 'Y';
2132 
2133  l_test           VARCHAR2(2000);
2134  l_org            NUMBER(15);
2135 
2136  l_instr_id       IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_id%TYPE;
2137 
2138  l_valid_pmts_count NUMBER;
2139  l_curr_pmt_status  VARCHAR2(200);
2140 
2141  /*
2142   * Implementing the callout is optional for the calling app.
2143   * If the calling app does not implement the hook, then
2144   * the call to the hook will result in ORA-06576 error.
2145   *
2146   * There is no exception name associated with this code, so
2147   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
2148   * exception occurs, it is not fatal: we log the error and
2149   * proceed.
2150   *
2151   * If, on the other hand, the calling app implements the
2152   * callout, but the callout throws an exception, it is fatal
2153   * and we must abort the program (this will be caught
2154   * in WHEN OTHERS block).
2155   */
2156  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
2157  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
2158 
2159  BEGIN
2160 
2161      print_debuginfo(l_module_name, 'ENTER');
2162 
2163      /*
2164       * Set the apps context. This is necessary so that
2165       * the calling application can see the org based
2166       * tables associated with this payment.
2167       *
2168       * See bug 4945922.
2169       */
2170      print_debuginfo(l_module_name, 'Setting apps context .. ');
2171 
2172      fnd_global.APPS_INITIALIZE(
2173          user_id      => fnd_global.user_id,
2174          resp_id      => fnd_global.resp_id,
2175          resp_appl_id => fnd_global.resp_appl_id
2176          );
2177 
2178      mo_global.init(fnd_global.application_short_name);
2179 
2180      print_debuginfo(l_module_name, 'Apps context set [user: '
2181          || fnd_global.user_id
2182          || ', responsbility id: '
2183          || fnd_global.resp_id
2184          || ', responsibility application id: '
2185          || fnd_global.resp_appl_id
2186          || ']'
2187          );
2188 
2189      print_debuginfo(l_module_name, 'Apps context [app short name: '
2190          || fnd_global.application_short_name
2191          || ']'
2192          );
2193 
2194     /*--- RYAN TEST CODE ---*/
2195     /*---- start ----*/
2196     /*
2197     begin
2198       print_debuginfo(l_module_name, 'Start RYAN test');
2199       select 'row found in moac synonym'
2200       into l_test
2201       from ap_invoices
2202       where invoice_id = 10045;
2203       print_debuginfo(l_module_name, 'End RYAN test: l_test = ' || l_test);
2204     exception
2205       when no_data_found then
2206       print_debuginfo('RYAN TEST: ap_pmt_callout_pkg',
2207           'in no data found exception');
2208     end;
2209     */
2210     /*---- end ----*/
2211 
2212     /*--- YING TEST CODE ---*/
2213     /*---- start ----*/
2214     /*
2215     begin
2216       print_debuginfo(l_module_name, 'Start YING test');
2217       select organization_id
2218       into l_org
2219       from ce_security_profiles_v
2220       where organization_type='OPERATING_UNIT';
2221       print_debuginfo(l_module_name, 'End YING test: l_org = ' || l_org);
2222     exception
2223       when no_data_found then
2224       print_debuginfo('YING TEST: org id',
2225           'in no data found exception');
2226     end;
2227     */
2228     /*---- end ----*/
2229 
2230      /* Standard call to check for API compatibility */
2231      IF NOT FND_API.Compatible_API_Call(
2232                         l_api_version,
2233                         p_api_version,
2234                         l_api_name,
2235                         G_PKG_NAME) THEN
2236 
2237          RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2238 
2239      END IF;
2240 
2241      /* Initialize message list if p_init_msg_list is set to TRUE */
2242      IF FND_API.to_boolean(p_init_msg_list) THEN
2243          FND_MSG_PUB.initialize;
2244      END IF;
2245 
2246      /* Initialize return status */
2247      x_return_status := FND_API.G_RET_STS_SUCCESS;
2248 
2249      /*
2250       * Fix for bug 5623941:
2251       *
2252       * STEP I:
2253       *
2254       * Before doing anything check if the payment is already
2255       * voided. If it is already voided, we don't need to do anything;
2256       * just exit.
2257       */
2258 
2259      /*
2260       * Get the current status of the
2261       * payment into l_curr_pmt_status
2262       */
2263      SELECT
2264          pmt.payment_status
2265      INTO
2266          l_curr_pmt_status
2267      FROM
2268          IBY_PAYMENTS_ALL pmt
2269      WHERE
2270          payment_id = p_pmt_id
2271      ;
2272 
2273      IF (l_curr_pmt_status = PAY_STATUS_VOID) THEN
2274 
2275          print_debuginfo(l_module_name, 'Payment '
2276              || p_pmt_id
2277              || ' is already voided. Skipping .. '
2278              );
2279 
2280          x_return_status := FND_API.G_RET_STS_SUCCESS;
2281 
2282          print_debuginfo(l_module_name, 'Returning success response ..');
2283          print_debuginfo(l_module_name, 'EXIT');
2284 
2285          RETURN;
2286 
2287      END IF;
2288 
2289      /*
2290       * STEP II:
2291       *
2292       * Check if the external application allows this payment
2293       * to be voided. If not there is no point in proceeding
2294       * further.
2295       */
2296      is_void_allowed (
2297          p_api_version,
2298          FND_API.G_FALSE,
2299          p_pmt_id,
2300          l_ret_flag,
2301          x_return_status,
2302          x_msg_count,
2303          x_msg_data
2304          );
2305 
2306      print_debuginfo(l_module_name, 'Void allowed flag '
2307           || 'after call to is_void_allowed() API: '
2308           || l_ret_flag
2309           );
2310 
2311      /*
2312       * If the void allowed flag is not set to 'Y',
2313       * exit the procedure with an error.
2314       */
2315      IF (UPPER(l_ret_flag) <> 'Y') THEN
2316 
2317          print_debuginfo(l_module_name, 'Void not allowed. '
2318              || 'Returning failure response.'
2319              );
2320 
2321          x_return_status := FND_API.G_RET_STS_ERROR;
2322 
2323          FND_MSG_PUB.Count_And_Get(
2324              p_encoded => FND_API.G_FALSE,
2325              p_count   => x_msg_count,
2326              p_data    => x_msg_data
2327              );
2328 
2329          print_debuginfo(l_module_name, 'EXIT');
2330 
2331          RETURN;
2332 
2333      END IF;
2334 
2335      /*
2336       * STEP III:
2337       *
2338       * Void the specified payment.
2339       */
2340      UPDATE
2341          IBY_PAYMENTS_ALL
2342      SET
2343          payment_status = PAY_STATUS_VOID,
2344          voided_by      = p_voided_by,
2345          void_date      = p_void_date,
2346          void_reason    = p_void_reason
2347      WHERE
2348          payment_id = p_pmt_id
2349      ;
2350 
2351      /*
2352       * STEP IV:
2353       *
2354       * Void the documents linked to this payment.
2355       */
2356      UPDATE
2357          IBY_DOCS_PAYABLE_ALL
2358      SET
2359          document_status = DOC_STATUS_PMT_VOIDED
2360      WHERE
2361          payment_id = p_pmt_id
2362      ;
2363 
2364      /*
2365       * STEP V:
2366       *
2367       * Fix for bug 5017119:
2368       *
2369       * After voiding this payment, check the payment instruction
2370       * to see whether any non-voided / non-removed payments
2371       * exist for this instruction.
2372       *
2373       * If this payment was the last valid payment on the instruction,
2374       * and we just voided it, then set the status of the instruction
2375       * to TERMINATED to signify that this is the final status for
2376       * the instruction.
2377       */
2378      SELECT
2379          instr.payment_instruction_id
2380      INTO
2381          l_instr_id
2382      FROM
2383          IBY_PAY_INSTRUCTIONS_ALL instr,
2384          IBY_PAYMENTS_ALL         pmt
2385      WHERE
2386          instr.payment_instruction_id = pmt.payment_instruction_id AND
2387          pmt.payment_id = p_pmt_id
2388      ;
2389 
2390      print_debuginfo(l_module_name, 'Provided payment '
2391          || p_pmt_id
2392          || ' has payment instruction id '
2393          || l_instr_id
2394          || '. Checking this instruction for any remaining valid payments ..'
2395          );
2396 
2397      SELECT
2398          count(*)
2399      INTO
2400          l_valid_pmts_count
2401      FROM
2402          IBY_PAYMENTS_ALL pmt
2403      WHERE
2404          pmt.payment_instruction_id = l_instr_id AND
2405          pmt.payment_status NOT IN
2406              (
2407               PAY_STATUS_VOID,
2408               PAY_STATUS_REMOVED
2409              )
2410      ;
2411 
2412      print_debuginfo(l_module_name, 'Number of remaining valid payments '
2413          || 'for pmt instruction '
2414          || l_instr_id
2415          || ' is '
2416          || l_valid_pmts_count
2417          );
2418 
2419      IF (l_valid_pmts_count = 0) THEN
2420 
2421          /*
2422           * Set the payment instruction status to TERMINATED
2423           * because no valid payments now exist for this
2424           * payment instruction.
2425           */
2426          UPDATE
2427              IBY_PAY_INSTRUCTIONS_ALL
2428          SET
2429              payment_instruction_status = INS_STATUS_TERMINATED
2430          WHERE
2431              payment_instruction_id = l_instr_id
2432          ;
2433 
2434          print_debuginfo(l_module_name, 'Status of payment instruction '
2435              || l_instr_id
2436              || ' updated to TERMINATED because it has no remaining '
2437              || 'valid payments.'
2438              );
2439 
2440 	/* Also since the Payment Instruction is terminated
2441 	 * we should be unlocking the payment document which this
2442 	 * instruction may be locking to make it available for other
2443 	 * Done per bug 6852606
2444 	 */
2445          print_debuginfo(l_module_name, 'Trying to unlock the payment document as PI termination: ');
2446 	 UPDATE
2447 	     CE_PAYMENT_DOCUMENTS
2448 	 SET
2449 	     payment_instruction_id = NULL,
2450 	     /* Bug 6707369
2451 	      * If some of the documents are skipped, the payment
2452 	      * document's last issued check number must be updated
2453 	      */
2454 	     last_issued_document_number = nvl(
2455 		     (SELECT MAX(pmt.paper_document_number)
2456 		      FROM iby_payments_all pmt
2457 		      WHERE pmt.payment_instruction_id = l_instr_id)
2458 		      ,last_issued_document_number
2459 		      )
2460 	 WHERE
2461 	     payment_instruction_id = l_instr_id;
2462          print_debuginfo(l_module_name, 'Payment document unlocking successful for PI : ' || l_instr_id);
2463 
2464 
2465      END IF;
2466 
2467      /*
2468       * STEP VI:
2469       *
2470       * Call external application hook to inform it of
2471       * the voided payments.
2472       */
2473 
2474      /*
2475       * Get the application name of the calling app. This
2476       * will be used in the callout.
2477       */
2478      SELECT
2479          fnd.application_short_name
2480      INTO
2481          l_app_short_name
2482      FROM
2483          FND_APPLICATION           fnd,
2484          IBY_PAYMENTS_ALL          pmt,
2485          IBY_PAY_SERVICE_REQUESTS  req
2486      WHERE
2487          fnd.application_id             = req.calling_app_id             AND
2488          req.payment_service_request_id = pmt.payment_service_request_id AND
2489          pmt.payment_id                 = p_pmt_id
2490      ;
2491 
2492      /*
2493       * Get the constructed package name to use in the
2494       * call out.
2495       */
2496      l_pkg_name := construct_callout_pkg_name(l_app_short_name);
2497 
2498      print_debuginfo(l_module_name, 'Constructed package name: '
2499          || l_pkg_name);
2500 
2501      IF (l_pkg_name IS NULL) THEN
2502 
2503          print_debuginfo(l_module_name, 'Package name is null. '
2504              || 'Raising exception.');
2505 
2506          APP_EXCEPTION.RAISE_EXCEPTION;
2507 
2508      END IF;
2509 
2510      /*
2511       * Now try to call the external app's implementation of the hook.
2512       * The calling app may or may not have implemented the hook, so
2513       * it's not fatal if the implementation does not exist.
2514       */
2515      l_callout_name := l_pkg_name || '.' || 'payment_voided';
2516 
2517      print_debuginfo(l_module_name, 'Attempting to invoke callout: '
2518          || l_callout_name);
2519 
2520      --l_stmt := 'CALL '|| l_callout_name
2521      --                     || '(:1, :2, :3, :4, :5, :6, :7, :8)';
2522 
2523      l_stmt := 'BEGIN '|| l_callout_name
2524                           || '('
2525                           || 'p_api_version   => :1, '
2526                           || 'p_payment_id    => :2, '
2527                           || 'p_void_date     => :3, '
2528                           || 'p_init_msg_list => :4, '
2529                           || 'p_commit        => :5, '
2530                           || 'x_return_status => :6, '
2531                           || 'x_msg_count     => :7, '
2532                           || 'x_msg_data      => :8  '
2533                           || '); END;'
2534                           ;
2535 
2536      BEGIN
2537 
2538          print_debuginfo(l_module_name, 'Params passed to callout - ');
2539          print_debuginfo(l_module_name, 'p_pmt_id: '    || p_pmt_id);
2540          print_debuginfo(l_module_name, 'p_void_date: ' || p_void_date);
2541 
2542          EXECUTE IMMEDIATE
2543              (l_stmt)
2544          USING
2545              IN  l_api_version,
2546              IN  p_pmt_id,
2547              IN  p_void_date,
2548              IN  FND_API.G_FALSE,
2549              IN  FND_API.G_FALSE,   /* commit flag */
2550              OUT x_return_status,
2551              OUT l_msg_count,
2552              OUT l_msg_data
2553          ;
2554 
2555          print_debuginfo(l_module_name, 'Finished invoking callout ..');
2556          print_debuginfo(l_module_name, 'Status returned by callout: '
2557              || x_return_status);
2558 
2559          /*
2560           * If the called procedure did not return success,
2561           * raise an exception.
2562           */
2563          IF (x_return_status IS NULL OR
2564              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
2565 
2566              print_debuginfo(l_module_name, 'Fatal: External app callout '''
2567                  || l_callout_name
2568                  || ''', returned failure status - '
2569                  || x_return_status
2570                  || '. Raising exception.'
2571                  );
2572 
2573              APP_EXCEPTION.RAISE_EXCEPTION;
2574 
2575          END IF;
2576 
2577      EXCEPTION
2578 
2579          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
2580              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
2581                  || '" not implemented by calling app '
2582                  || l_app_short_name || '.');
2583 
2584              print_debuginfo(l_module_name, 'Skipping hook call.');
2585 
2586          WHEN OTHERS THEN
2587              print_debuginfo(l_module_name, 'Fatal: External app callout '''
2588                  || l_callout_name
2589                  || ''', generated exception.'
2590                  );
2591 
2592              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
2593              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
2594              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
2595 
2596              /*
2597               * Propogate exception to caller.
2598               */
2599              RAISE;
2600      END;
2601 
2602      /*
2603       * Standard call to get message count and if count is 1, get
2604       * message info.
2605       */
2606      FND_MSG_PUB.Count_And_Get(
2607                      p_encoded => FND_API.G_FALSE,
2608                      p_count   => x_msg_count,
2609                      p_data    => x_msg_data
2610                      );
2611 
2612      x_return_status := FND_API.G_RET_STS_SUCCESS;
2613      print_debuginfo(l_module_name, 'Returning success response ..');
2614 
2615      print_debuginfo(l_module_name, 'EXIT');
2616 
2617  EXCEPTION
2618      WHEN OTHERS THEN
2619 
2620          print_debuginfo(l_module_name, 'Exception occured when '
2621              || 'attempting to void payment id '
2622              || p_pmt_id
2623              );
2624 
2625          print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
2626          print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
2627          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
2628 
2629          x_return_status := FND_API.G_RET_STS_ERROR;
2630 
2631          FND_MSG_PUB.Count_And_Get(
2632              p_encoded => FND_API.G_FALSE,
2633              p_count   => x_msg_count,
2634              p_data    => x_msg_data
2635              );
2636 
2637          print_debuginfo(l_module_name, 'Returning error response ..');
2638          print_debuginfo(l_module_name, 'EXIT');
2639 
2640          RETURN;
2641 
2642  END void_pmt_internal;
2643 
2644 /*--------------------------------------------------------------------
2645  | NAME:
2646  |     is_void_allowed
2647  |
2648  |
2649  | PURPOSE:
2650  |
2651  |
2652  | PARAMETERS:
2653  |     IN
2654  |
2655  |
2656  |     OUT
2657  |
2658  |
2659  | RETURNS:
2660  |
2661  | NOTES:
2662  |
2663  *---------------------------------------------------------------------*/
2664  PROCEDURE is_void_allowed (
2665      p_api_version    IN NUMBER,
2666      p_init_msg_list  IN VARCHAR2 DEFAULT FND_API.G_FALSE,
2667      p_pmt_id         IN NUMBER,
2668      x_return_flag    OUT NOCOPY VARCHAR2,   /* 'Y'/'N' flag */
2669      x_return_status  OUT NOCOPY VARCHAR2,
2670      x_msg_count      OUT NOCOPY NUMBER,
2671      x_msg_data       OUT NOCOPY VARCHAR2
2672      )
2673  IS
2674 
2675  l_module_name    CONSTANT VARCHAR2(200) := G_PKG_NAME || '.is_void_allowed';
2676 
2677  /* used in forming callout procedure name */
2678  l_app_short_name VARCHAR2(200);
2679  l_pkg_name       VARCHAR2(200);
2680  l_callout_name   VARCHAR2(500);
2681  l_stmt           VARCHAR2(1000);
2682 
2683  /* used in invocation of callout procedure */
2684  l_api_version    CONSTANT NUMBER := 1.0;
2685  l_msg_count      NUMBER;
2686  l_msg_data       VARCHAR2(2000);
2687 
2688  l_api_name      CONSTANT VARCHAR2(100) := 'is_void_allowed';
2689 
2690  /*
2691   * Implementing the callout is optional for the calling app.
2692   * If the calling app does not implement the hook, then
2693   * the call to the hook will result in ORA-06576 error.
2694   *
2695   * There is no exception name associated with this code, so
2696   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
2697   * exception occurs, it is not fatal: we log the error and
2698   * proceed.
2699   *
2700   * If, on the other hand, the calling app implements the
2701   * callout, but the callout throws an exception, it is fatal
2702   * and we must abort the program (this will be caught
2703   * in WHEN OTHERS block).
2704   */
2705  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
2706  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
2707 
2708  BEGIN
2709 
2710      print_debuginfo(l_module_name, 'ENTER');
2711 
2712      /* Standard call to check for API compatibility */
2713      IF NOT FND_API.Compatible_API_Call(
2714                         l_api_version,
2715                         p_api_version,
2716                         l_api_name,
2717                         G_PKG_NAME) THEN
2718 
2719          RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2720 
2721      END IF;
2722 
2723      /* Initialize message list if p_init_msg_list is set to TRUE */
2724      IF FND_API.to_boolean(p_init_msg_list) THEN
2725          FND_MSG_PUB.initialize;
2726      END IF;
2727 
2728      /* Initialize return status */
2729      x_return_status := FND_API.G_RET_STS_SUCCESS;
2730 
2731      /*
2732       * Get the application name of the calling app. This
2733       * will be used in the callout.
2734       */
2735      SELECT
2736          fnd.application_short_name
2737      INTO
2738          l_app_short_name
2739      FROM
2740          FND_APPLICATION           fnd,
2741          IBY_PAYMENTS_ALL          pmt,
2742          IBY_PAY_SERVICE_REQUESTS  req
2743      WHERE
2744          fnd.application_id             = req.calling_app_id             AND
2745          req.payment_service_request_id = pmt.payment_service_request_id AND
2746          pmt.payment_id                 = p_pmt_id
2747      ;
2748 
2749      /*
2750       * Get the constructed package name to use in the
2751       * call out.
2752       */
2753      l_pkg_name := construct_callout_pkg_name(l_app_short_name);
2754 
2755      print_debuginfo(l_module_name, 'Constructed package name: '
2756          || l_pkg_name);
2757 
2758      IF (l_pkg_name IS NULL) THEN
2759 
2760          print_debuginfo(l_module_name, 'Package name is null. '
2761              || 'Raising exception.');
2762 
2763          APP_EXCEPTION.RAISE_EXCEPTION;
2764 
2765      END IF;
2766 
2767      /*
2768       * Now try to call the external app's implementation of the hook.
2769       * The calling app may or may not have implemented the hook, so
2770       * it's not fatal if the implementation does not exist.
2771       */
2772      l_callout_name := l_pkg_name || '.' || 'void_payment_allowed';
2773 
2774      print_debuginfo(l_module_name, 'Attempting to invoke callout: '
2775          || l_callout_name);
2776 
2777      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7, :8)';
2778 
2779      BEGIN
2780 
2781          EXECUTE IMMEDIATE
2782              (l_stmt)
2783          USING
2784              IN  l_api_version,
2785              IN  FND_API.G_FALSE,
2786              IN  FND_API.G_FALSE,
2787              IN  p_pmt_id,
2788              OUT x_return_flag,
2789              OUT x_return_status,
2790              OUT l_msg_count,
2791              OUT l_msg_data
2792          ;
2793 
2794          /*
2795           * If the called procedure did not return success,
2796           * raise an exception.
2797           */
2798          IF (x_return_status IS NULL OR
2799              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
2800 
2801              print_debuginfo(l_module_name, 'Fatal: External app callout '''
2802                  || l_callout_name
2803                  || ''', returned failure status - '
2804                  || x_return_status
2805                  || '. Raising exception.'
2806                  );
2807 
2808              APP_EXCEPTION.RAISE_EXCEPTION;
2809 
2810          END IF;
2811 
2812      EXCEPTION
2813 
2814          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
2815              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
2816                  || '" not implemented by calling app '
2817                  || l_app_short_name || '.');
2818 
2819              print_debuginfo(l_module_name, 'Skipping hook call.');
2820 
2821              /*
2822               * Fix for bug 5083294:
2823               *
2824               * Default the return flag to 'Y' (meaning
2825               * void is allowed) in case the calling
2826               * application has not implemented this
2827               * callout.
2828               */
2829              x_return_flag := 'Y';
2830 
2831              print_debuginfo(l_module_name, 'Defaulting x_return_flag to '
2832                  || ''''
2833                  || x_return_flag
2834                  || ''''
2835                  || ' [Meaning: void is allowed by default]'
2836                  );
2837 
2838          WHEN OTHERS THEN
2839              print_debuginfo(l_module_name, 'Fatal: External app callout '''
2840                  || l_callout_name
2841                  || ''', generated exception.'
2842                  );
2843 
2844              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
2845              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
2846              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
2847 
2848              /*
2849               * Propogate exception to caller.
2850               */
2851              RAISE;
2852      END;
2853 
2854      x_return_status := FND_API.G_RET_STS_SUCCESS;
2855 
2856      print_debuginfo(l_module_name, 'EXIT');
2857 
2858  EXCEPTION
2859 
2860      WHEN OTHERS THEN
2861 
2862          print_debuginfo(l_module_name, 'Exception occured when '
2863              || 'checking voidability of payment '
2864              || p_pmt_id
2865              );
2866 
2867          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
2868          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
2869          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
2870 
2871          x_return_status := FND_API.G_RET_STS_ERROR;
2872 
2873          print_debuginfo(l_module_name, 'EXIT');
2874 
2875  END is_void_allowed;
2876 
2877 /*--------------------------------------------------------------------
2878  | NAME:
2879  |     void_pmts_internal
2880  |
2881  | PURPOSE:
2882  |     Invokes a series of callouts of the calling app to remove
2883  |     a set of submitted documents payable from the payment processing
2884  |     cycle.
2885  |
2886  |     The calling application can free up the removed documents, and
2887  |     make them available for submission in future payment request(s).
2888  |
2889  | PARAMETERS:
2890  |     IN
2891  |       p_pmt_list        - IDs of the payments to be stopped.
2892  |                           This should be an array of payment ids. All
2893  |                           the child documents payable of each of the
2894  |                           specified payments will be removed.
2895  |
2896  |       p_pmt_status_list - Current statuses of the payments to
2897  |                           be stopped. This should be an array of statuses.
2898  |
2899  |       p_voided_by       - User id of person who issued the void request.
2900  |                           This id will be stored as an attribute of the
2901  |                           payment.
2902  |
2903  |       p_void_date       - Date on which the void request was made.
2904  |
2905  |       p_void_reason     - Reason why this payment needs to be voided.
2906  |
2907  |     OUT
2908  |       x_return_status   - Result of the API call:
2909  |                         FND_API.G_RET_STS_SUCCESS indicates that all
2910  |                           the callouts were invoked successfully.
2911  |                           In this case the caller must COMMIT
2912  |                           the status changes.
2913  |
2914  |                         FND_API.G_RET_STS_ERROR (or other) indicates
2915  |                           that at least one event did not complete
2916  |                           successfully. In this case, the caller must
2917  |                           issue a ROLLBACK to undo all status changes.
2918  |
2919  | RETURNS:
2920  |
2921  | NOTES:
2922  |   Internal API, not for public use.
2923  |
2924  |   This API will not do a COMMIT. It is the the callers responsbility
2925  |   to perform COMMIT / ROLLBACK depending upon the returned status.
2926  |
2927  |   The callouts invoked must be handled synchronously by the
2928  |   calling application. So the COMMIT / ROLLBACK should affect
2929  |   the changes made to the database by the calling application as
2930  |   well. This will ensure that IBY and the calling application are
2931  |   in sync w.r.t. to the specified documents payable.
2932  |
2933  *---------------------------------------------------------------------*/
2934  PROCEDURE void_pmts_internal (
2935      p_instr_id         IN NUMBER,
2936      p_voided_by        IN NUMBER,
2937      p_void_date        IN DATE,
2938      p_void_reason      IN VARCHAR2,
2939      x_return_status    OUT NOCOPY VARCHAR2
2940      )
2941  IS
2942 
2943  l_module_name   CONSTANT VARCHAR2(200) := G_PKG_NAME || '.void_pmts_internal';
2944 
2945  l_api_version   CONSTANT NUMBER        := 1.0;
2946  l_msg_count     NUMBER;
2947  l_msg_data      VARCHAR2(2000);
2948 
2949  l_pmts_list     pmtIDTab;
2950 
2951  CURSOR c_payments (p_instr_id IN NUMBER)
2952  IS
2953  SELECT
2954      payment_id
2955  FROM
2956      IBY_PAYMENTS_ALL
2957  WHERE
2958      payment_instruction_id = p_instr_id  AND
2959      payments_complete_flag = 'Y'
2960  ;
2961 
2962  BEGIN
2963 
2964      print_debuginfo(l_module_name, 'ENTER');
2965 
2966      FND_MSG_PUB.initialize;
2967 
2968      /*
2969       * Pick up all qualifying payments of the payment instruction.
2970       */
2971      OPEN  c_payments(p_instr_id);
2972      FETCH c_payments BULK COLLECT INTO l_pmts_list;
2973      CLOSE c_payments;
2974 
2975      /*
2976       * Return failure if no payments were found.
2977       */
2978      IF (l_pmts_list.COUNT = 0) THEN
2979 
2980          print_debuginfo(l_module_name, 'No completed payments '
2981              || ' were found for payment instruction id '
2982              || p_instr_id
2983              );
2984 
2985          x_return_status := FND_API.G_RET_STS_ERROR;
2986 
2987          print_debuginfo(l_module_name, 'EXIT');
2988 
2989          RETURN;
2990 
2991      END IF;
2992 
2993      /*
2994       * Start processing the payments, one-by-one.
2995       */
2996      FOR i IN l_pmts_list.FIRST .. l_pmts_list.LAST LOOP
2997 
2998          void_pmt_internal (
2999              l_api_version,
3000              FND_API.G_FALSE,
3001              l_pmts_list(i),
3002              p_voided_by,
3003              p_void_date,
3004              p_void_reason,
3005              x_return_status,
3006              l_msg_count,
3007              l_msg_data
3008              );
3009 
3010          /*
3011           * Check if the call to stop the payment succeeded.
3012           */
3013          IF (x_return_status IS NULL OR
3014 	     x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
3015 
3016              /*
3017               * Even if a single call to remove a payment
3018               * failed, return failure for the entire API request.
3019               */
3020              print_debuginfo(l_module_name, 'Voiding of completed payment '
3021                  || l_pmts_list(i)
3022                  || ' failed.'
3023                  );
3024 
3025              print_debuginfo(l_module_name, 'EXIT');
3026 
3027              /*
3028               * It is the callers responsibility to rollback
3029               * all the changes.
3030               */
3031              RETURN;
3032 
3033          END IF;
3034 
3035      END LOOP;
3036 
3037      /*
3038       * If we reached here, it means that all payments
3039       * of the given payment instruction have been
3040       * voided successfully.
3041       */
3042      print_debuginfo(l_module_name, 'All payments of payment '
3043          || 'instruction id '
3044          || p_instr_id
3045          || ' voided successfully.'
3046          );
3047 
3048      /*
3049       * Fix for bug 5017119:
3050       *
3051       * After voiding all the payments of an instruction,
3052       * change the instruction status to TERMINATED
3053       * so that user cannot take any further action on the
3054       * payment instruction.
3055       */
3056      UPDATE
3057          iby_pay_instructions_all
3058      SET
3059          payment_instruction_status = INS_STATUS_TERMINATED
3060      WHERE
3061          payment_instruction_id = p_instr_id
3062      ;
3063 
3064      print_debuginfo(l_module_name, 'Status of payment instruction '
3065          || p_instr_id
3066          || ' set to TERMINATED because all payments have been voided.'
3067          );
3068 
3069      x_return_status := FND_API.G_RET_STS_SUCCESS;
3070 
3071      print_debuginfo(l_module_name, 'Returning success response ..');
3072 
3073      print_debuginfo(l_module_name, 'EXIT');
3074 
3075  END void_pmts_internal;
3076 
3077 /*--------------------------------------------------------------------
3078  | NAME:
3079  |     validate_paper_doc_number
3080  |
3081  | PURPOSE:
3082  |     Validates that the given paper document number is valid for the
3083  |     given payment document (check stock) id.
3084  |
3085  | PARAMETERS:
3086  |     IN
3087  |       p_api_version   -  Version of the API.
3088  |
3089  |       p_init_msg_list - Standard API parameter; default as FND_API.G_FALSE
3090  |
3091  |       p_payment_doc_id
3092  |                       - ID of the payment document (check stock) to use.
3093  |
3094  |     IN/OUT
3095  |       x_paper_doc_num - Paper document number (check number) to use.
3096  |                         If a value is provided, this value will be validated.
3097  |                         If no value (i.e., NULL) is provided, then the
3098  |                         next available paper document number will be
3099  |                         returned as an output parameter.
3100  |
3101  |     OUT
3102  |       x_return_status - Standard return status. Possible values are:
3103  |                         FND_API.G_RET_STS_SUCCESS
3104  |                           The given paper document number is valid
3105  |                           for the given payment document.
3106  |
3107  |                           It is possible that there were warnings.
3108  |                           Please unwind the FND message stack to
3109  |                           check if there were any warnings to display
3110  |                           to the user.
3111  |
3112  |                         FND_API.G_RET_STS_ERROR
3113  |                           The given paper document number is invalid.
3114  |                           Possible reasons are the paper document number
3115  |                           has already been used, or the paper document
3116  |                           number is not in the valid range for the given
3117  |                           payment document.
3118  |
3119  |       x_msg_count     - Standard msg count
3120  |
3121  |       x_msg_data      - Standard msg data
3122  |
3123  | RETURNS:
3124  |
3125  | NOTES:
3126  |  Public API.
3127  |
3128  |   This API will not do a COMMIT/ROLLBACK. There are no database
3129  |   state changes implemented by this API. It is a read only API.
3130  |
3131  *---------------------------------------------------------------------*/
3132  PROCEDURE validate_paper_doc_number (
3133      p_api_version         IN NUMBER,
3134      p_init_msg_list       IN VARCHAR2 DEFAULT FND_API.G_FALSE,
3135      p_payment_doc_id      IN NUMBER,
3136      x_paper_doc_num       IN OUT NOCOPY NUMBER,
3137      x_return_status       OUT NOCOPY VARCHAR2,
3138      x_msg_count           OUT NOCOPY NUMBER,
3139      x_msg_data            OUT NOCOPY VARCHAR2,
3140      show_warn_msgs_flag   IN VARCHAR2 DEFAULT FND_API.G_TRUE
3141      )
3142  IS
3143 
3144  l_module_name   CONSTANT VARCHAR2(200) := G_PKG_NAME
3145                                            || '.validate_paper_doc_number';
3146 
3147  l_api_version   CONSTANT NUMBER        := 1.0;
3148  l_api_name      CONSTANT VARCHAR2(100) := 'validate_paper_doc_number';
3149 
3150  l_error_code    VARCHAR2(3000);
3151 
3152  l_last_used_check_num   NUMBER := 0;
3153  l_next_check_number     NUMBER := 0;
3154 
3155  l_first_avail_check_num NUMBER := 0;
3156  l_last_avail_check_num  NUMBER := 0;
3157  l_pmt_doc_name          VARCHAR2(200) := '';
3158  l_used_paper_doc_number NUMBER := 0;
3159 
3160  l_flag                  BOOLEAN;
3161 
3162  BEGIN
3163 
3164      print_debuginfo(l_module_name, 'ENTER');
3165 
3166      /* Standard call to check for API compatibility */
3167      IF NOT FND_API.Compatible_API_Call(
3168                         l_api_version,
3169                         p_api_version,
3170                         l_api_name,
3171                         G_PKG_NAME) THEN
3172 
3173          RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3174 
3175      END IF;
3176 
3177      /* Initialize message list if p_init_msg_list is set to TRUE */
3178      IF FND_API.to_boolean(p_init_msg_list) THEN
3179          FND_MSG_PUB.initialize;
3180      END IF;
3181 
3182      /* Initialize return status */
3183      x_return_status := FND_API.G_RET_STS_SUCCESS;
3184 
3185 
3186      /*
3187       * Pull up the details of the paper stock, like the
3188       * last used check number and the last available
3189       * check number.
3190       */
3191      BEGIN
3192 
3193          SELECT
3194              NVL(last_issued_document_number,     0),
3195              NVL(first_available_document_num,    0),
3196              NVL(last_available_document_number, -1),
3197              payment_document_name
3198          INTO
3199              l_last_used_check_num,
3200              l_first_avail_check_num,
3201              l_last_avail_check_num,
3202              l_pmt_doc_name
3203          FROM
3204              CE_PAYMENT_DOCUMENTS
3205          WHERE
3206              payment_document_id = p_payment_doc_id
3207          ;
3208 
3209      EXCEPTION
3210 
3211          WHEN NO_DATA_FOUND THEN
3212 
3213              print_debuginfo(l_module_name, 'No payment document '
3214                  || 'with payment document id '
3215                  || p_payment_doc_id
3216                  || ' was found in CE_PAYMENT_DOCUMENTS table.'
3217                  );
3218 
3219              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
3220              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
3221              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
3222 
3223              x_return_status := FND_API.G_RET_STS_ERROR;
3224 
3225              l_error_code := 'IBY_INS_NO_PMT_DOC';
3226              FND_MESSAGE.set_name('IBY', l_error_code);
3227 
3228              FND_MESSAGE.SET_TOKEN('PMT_DOC_ID',
3229                  p_payment_doc_id,
3230                  FALSE);
3231 
3232              FND_MSG_PUB.ADD;
3233 
3234              FND_MSG_PUB.COUNT_AND_GET(
3235                  p_count => x_msg_count,
3236                  p_data  => x_msg_data
3237                  );
3238 
3239              print_debuginfo(l_module_name, 'Returning error response ..');
3240 
3241              print_debuginfo(l_module_name, 'EXIT');
3242 
3243              RETURN;
3244 
3245 
3246          WHEN OTHERS THEN
3247 
3248              print_debuginfo(l_module_name, 'Exception occured when '
3249                  || 'attempting to get details of payment document id '
3250                  || p_payment_doc_id
3251                  );
3252 
3253              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
3254              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
3255 
3256              x_return_status := FND_API.G_RET_STS_ERROR;
3257 
3258              l_error_code := 'IBY_PMT_DOC_EXCEPTION';
3259              FND_MESSAGE.set_name('IBY', l_error_code);
3260 
3261              FND_MESSAGE.SET_TOKEN('PMT_DOC_ID',
3262                  p_payment_doc_id,
3263                  FALSE);
3264 
3265              FND_MSG_PUB.ADD;
3266 
3267              FND_MSG_PUB.COUNT_AND_GET(
3268                  p_count => x_msg_count,
3269                  p_data  => x_msg_data
3270                  );
3271 
3272              print_debuginfo(l_module_name, 'Returning error response ..');
3273 
3274              print_debuginfo(l_module_name, 'EXIT');
3275 
3276              RETURN;
3277 
3278      END;
3279 
3280      /*
3281       * If we reached here, it means that we were able to get
3282       * the details of the provided payment document.
3283       */
3284 
3285      /*
3286       * If a null value is provided for the paper document number,
3287       * we have to return the next available paper document number
3288       * and exit.
3289       */
3290      IF (x_paper_doc_num IS NULL) THEN
3291 
3292          print_debuginfo(l_module_name, 'Paper document number '
3293              || 'has not been provided. Generating ..'
3294              );
3295 
3296          /*
3297           * Loop through the available paper documents until
3298           * we get a paper document number that is -
3299           *
3300           * 1. Not used
3301           * 2. Not greater than the last available document number.
3302           *
3303           * If both these conditions are not satisfied, return an
3304           * error response.
3305           */
3306          x_paper_doc_num := -1;
3307          l_error_code    := NULL;
3308 
3309          l_next_check_number := l_last_used_check_num;
3310 
3311          WHILE (x_paper_doc_num < 0 AND l_error_code IS NULL) LOOP
3312 
3313              /*
3314               * Increment the check number by one and check
3315               * if it unused. If it is unused, we can return
3316               * this check number, else we need to increment
3317               * check number by one more and try again in a
3318               * loop.
3319               */
3320              l_next_check_number := l_next_check_number + 1;
3321 
3322              x_paper_doc_num := l_next_check_number;
3323 
3324              print_debuginfo(l_module_name, 'Generated paper document '
3325                  || 'number is '
3326                  || x_paper_doc_num
3327                  );
3328 
3329              /*
3330               * Fix for bug 5005222:
3331               *
3332               * If last available paper document number is not
3333               * specified by the user (-1), assume that there
3334               * are an infinite number of checks available for
3335               * numbering [no upper bound].
3336               */
3337              /* check that we are not out of paper stock */
3338              IF (x_paper_doc_num         > l_last_avail_check_num AND
3339                  l_last_avail_check_num <> -1)                    THEN
3340 
3341                  print_debuginfo(l_module_name, 'Last available '
3342                      || 'paper document number is '
3343                      || l_last_avail_check_num
3344                      );
3345 
3346                  print_debuginfo(l_module_name, 'Provided payment document '
3347                      || p_payment_doc_id
3348                      || ' is exhausted. No more paper documents are '
3349                      || 'available for issue.'
3350                      );
3351 
3352                  x_return_status := FND_API.G_RET_STS_ERROR;
3353 
3354                  l_error_code := 'IBY_CHECK_STOCK_EXHAUSTED';
3355                  FND_MESSAGE.set_name('IBY', l_error_code);
3356 
3357                  FND_MSG_PUB.ADD;
3358 
3359                  FND_MSG_PUB.COUNT_AND_GET(
3360                      p_count => x_msg_count,
3361                      p_data  => x_msg_data
3362                      );
3363 
3364                  print_debuginfo(l_module_name, 'Returning error response ..');
3365 
3366 
3367              ELSE
3368 
3369                  /*
3370                   * Check if this paper document number has already
3371                   * been used.
3372                   */
3373                  l_flag := checkIfDocUsed(x_paper_doc_num, p_payment_doc_id);
3374 
3375                  IF (l_flag = TRUE) THEN
3376 
3377                      print_debuginfo(l_module_name, 'Generated paper document '
3378                          || 'number '
3379                          || x_paper_doc_num
3380                          || ' has been used. Generating next available '
3381                          || 'paper doc number ..'
3382                          );
3383 
3384                      /* this will cause the while loop to iterate */
3385                      x_paper_doc_num := -1;
3386 
3387                  ELSE
3388 
3389                      x_return_status := FND_API.G_RET_STS_SUCCESS;
3390 
3391                      print_debuginfo(l_module_name, 'Generated paper document '
3392                          || 'number '
3393                          || x_paper_doc_num
3394                          || ' is unused.'
3395                          );
3396 
3397                      print_debuginfo(l_module_name, 'Returning success '
3398                          || 'response ..');
3399 
3400                  END IF; -- if l_flag <> true
3401 
3402              END IF; -- if x_paper_doc_num < l_last_avail_check_num
3403 
3404          END LOOP;
3405 
3406          /* exit at this point as we will not be doing any validations */
3407          print_debuginfo(l_module_name, 'EXIT');
3408 
3409          RETURN;
3410 
3411      END IF; -- if x_paper_doc_num is null
3412 
3413      /*
3414       * Start the paper document number validations.
3415       */
3416 
3417      /*
3418       * Provided paper document number cannot be below
3419       * first available paper doc number.
3420       */
3421      IF (x_paper_doc_num < l_first_avail_check_num) THEN
3422 
3423              print_debuginfo(l_module_name, 'Provided paper doc number '
3424                  || x_paper_doc_num
3425                  || ' is below first available document number '
3426                  || l_first_avail_check_num
3427                  );
3428 
3429              x_return_status := FND_API.G_RET_STS_ERROR;
3430 
3431              l_error_code := 'IBY_DOC_NUM_BELOW_ALLOWED';
3432              FND_MESSAGE.set_name('IBY', l_error_code);
3433 
3434              FND_MESSAGE.SET_TOKEN('FIRST_AVAILABLE_DOC_NUM',
3435                  l_first_avail_check_num,
3436                  FALSE);
3437 
3438              FND_MSG_PUB.ADD;
3439 
3440              FND_MSG_PUB.COUNT_AND_GET(
3441                  p_count => x_msg_count,
3442                  p_data  => x_msg_data
3443                  );
3444 
3445              print_debuginfo(l_module_name, 'Returning error response ..');
3446 
3447              print_debuginfo(l_module_name, 'EXIT');
3448 
3449              RETURN;
3450 
3451      END IF;
3452 
3453      /*
3454       * Fix for bug 5005222:
3455       *
3456       * If last available paper document number is not
3457       * specified by the user (-1), assume that there
3458       * are an infinite number of checks available for
3459       * numbering [no upper bound].
3460       */
3461 
3462      /*
3463       * Provided paper document number cannot be above
3464       * last available paper doc number.
3465       */
3466      IF (x_paper_doc_num         > l_last_avail_check_num AND
3467          l_last_avail_check_num <> -1)                    THEN
3468 
3469              print_debuginfo(l_module_name, 'Last available '
3470                  || 'paper document number is '
3471                  || l_last_avail_check_num
3472                  );
3473 
3474              print_debuginfo(l_module_name, 'Provided paper doc number '
3475                  || x_paper_doc_num
3476                  || ' is above last available document number '
3477                  || l_last_avail_check_num
3478                  );
3479 
3480              x_return_status := FND_API.G_RET_STS_ERROR;
3481 
3482              l_error_code := 'IBY_DOC_NUM_ABOVE_ALLOWED';
3483              FND_MESSAGE.set_name('IBY', l_error_code);
3484 
3485              FND_MESSAGE.SET_TOKEN('LAST_AVAILABLE_DOC_NUM',
3486                  l_last_avail_check_num,
3487                  FALSE);
3488 
3489              FND_MSG_PUB.ADD;
3490 
3491              FND_MSG_PUB.COUNT_AND_GET(
3492                  p_count => x_msg_count,
3493                  p_data  => x_msg_data
3494                  );
3495 
3496              print_debuginfo(l_module_name, 'Returning error response ..');
3497 
3498              print_debuginfo(l_module_name, 'EXIT');
3499 
3500              RETURN;
3501 
3502      END IF;
3503 
3504      /*
3505       * Provided paper document number should not be below
3506       * last issued paper doc number (warning).
3507       */
3508      IF (x_paper_doc_num < l_last_used_check_num) THEN
3509 
3510          /*
3511           * This check will only result in a warning message.
3512           * Ignore this check, if the show warnings flag is
3513           * set to false.
3514           *
3515           * This method can be called multiple times in the
3516           * single payments flow, this could result in a large
3517           * number of error messages being put into the message
3518           * stack and displayed to the user.
3519           *
3520           * By setting the show warnings flag to 'false' for
3521           * the single payments flow, the number of potential
3522           * messages displayed to the user is reduced.
3523           */
3524          IF (show_warn_msgs_flag = FND_API.G_TRUE) THEN
3525 
3526              print_debuginfo(l_module_name, 'Warning: Provided paper '
3527                  || 'doc number '
3528                  || x_paper_doc_num
3529                  || ' is below last issued document number '
3530                  || l_last_used_check_num
3531                  );
3532 
3533              l_error_code := 'IBY_DOC_NUM_BELOW_ISSUED';
3534              FND_MESSAGE.set_name('IBY', l_error_code);
3535 
3536              FND_MSG_PUB.ADD;
3537 
3538              FND_MSG_PUB.COUNT_AND_GET(
3539                  p_count => x_msg_count,
3540                  p_data  => x_msg_data
3541                  );
3542 
3543          END IF;
3544 
3545      END IF;
3546 
3547      /*
3548       * Check if this paper document number has already
3549       * been used.
3550       */
3551      l_flag := checkIfDocUsed(x_paper_doc_num, p_payment_doc_id);
3552 
3553      IF (l_flag = TRUE) THEN
3554 
3555          print_debuginfo(l_module_name, 'Provided paper document '
3556              || 'number '
3557              || x_paper_doc_num
3558              || ' has already been used.'
3559              );
3560 
3561          x_return_status := FND_API.G_RET_STS_ERROR;
3562 
3563          l_error_code := 'IBY_DOC_NUM_USED';
3564          FND_MESSAGE.set_name('IBY', l_error_code);
3565 
3566          FND_MSG_PUB.ADD;
3567 
3568          FND_MSG_PUB.COUNT_AND_GET(
3569              p_count => x_msg_count,
3570              p_data  => x_msg_data
3571              );
3572 
3573          print_debuginfo(l_module_name, 'Returning error response ..');
3574 
3575          print_debuginfo(l_module_name, 'EXIT');
3576 
3577          RETURN;
3578 
3579      ELSE
3580 
3581          print_debuginfo(l_module_name, 'Provided paper document '
3582              || 'number '
3583              || x_paper_doc_num
3584              || ' is unused.'
3585              );
3586 
3587      END IF; -- if l_flag <> true
3588 
3589      /*
3590       * If we reached here, it means that both the paper document
3591       * number and the payment document id are valid.
3592       */
3593      print_debuginfo(l_module_name, 'Returning success response ..');
3594 
3595      x_return_status := FND_API.G_RET_STS_SUCCESS;
3596 
3597      print_debuginfo(l_module_name, 'EXIT');
3598 
3599  END validate_paper_doc_number;
3600 
3601 /*--------------------------------------------------------------------
3602  | NAME:
3603  |     terminate_pmt_instruction
3604  |
3605  |
3606  | PURPOSE:
3607  |
3608  |
3609  | PARAMETERS:
3610  |     IN
3611  |
3612  |
3613  |     OUT
3614  |
3615  |
3616  | RETURNS:
3617  |
3618  | NOTES:
3619  |   Internal API, not for public use.
3620  |
3621  | UPDATE ON MAY-04-2006, rameshsh
3622  | This method was not performing a COMMIT earlier. Due to bug 5206672
3623  | a COMMIT has been added in the code before invoking unlock_pmt_entity(..).
3624  *---------------------------------------------------------------------*/
3625  PROCEDURE terminate_pmt_instruction (
3626      p_instr_id       IN NUMBER,
3627      p_instr_status   IN VARCHAR2,
3628      x_return_status  OUT NOCOPY VARCHAR2
3629      )
3630  IS
3631 
3632  l_module_name    CONSTANT VARCHAR2(200) := G_PKG_NAME
3633                                             || '.terminate_pmt_instruction';
3634 
3635  l_rejection_id   NUMBER(15);
3636 
3637  /* used in forming callout procedure name */
3638  l_calling_app_id NUMBER;
3639  l_pkg_name       VARCHAR2(200);
3640  l_callout_name   VARCHAR2(500);
3641  l_stmt           VARCHAR2(1000);
3642 
3643  /* used in invocation of callout procedure */
3644  l_api_version    CONSTANT NUMBER := 1.0;
3645  l_msg_count      NUMBER;
3646  l_msg_data       VARCHAR2(2000);
3647 
3648  l_appNamesTab    appNamesTab;
3649  l_appIdsTab      appIdsTab;
3650 
3651  l_pmt_doc_id     NUMBER(15);
3652  l_pmt_doc_name   VARCHAR2(2000);
3653 
3654  l_flag           BOOLEAN := FALSE;
3655  l_error_code     VARCHAR2(3000);
3656 
3657  l_ret_status     VARCHAR2(300);
3658 
3659  l_valid_pmts_count NUMBER;
3660 
3661  l_max_paper_document_number NUMBER;
3662  l_min_paper_document_number NUMBER;
3663  l_number_of_payments NUMBER;
3664  l_last_issued NUMBER;
3665  l_document_locked BOOLEAN := TRUE;
3666  l_last_issued_modified NUMBER;
3667  l_irregular_document_numbers EXCEPTION;
3668  /*
3669   * Cursor to pick up names of all calling applications
3670   * associated with a particular payment instruction.
3671   */
3672  CURSOR c_app_names (p_instr_id NUMBER)
3673  IS
3674  SELECT DISTINCT
3675      fnd.application_short_name
3676  FROM
3677      FND_APPLICATION          fnd,
3678      IBY_PAYMENTS_ALL         pmt,
3679      IBY_PAY_SERVICE_REQUESTS req,
3680      IBY_PAY_INSTRUCTIONS_ALL ins
3681  WHERE
3682      pmt.payment_instruction_id     = ins.payment_instruction_id     AND
3683      req.payment_service_request_id = pmt.payment_service_request_id AND
3684      fnd.application_id             = req.calling_app_id             AND
3685      ins.payment_instruction_id     = p_instr_id
3686  ;
3687 
3688  /*
3689   * Cursor to pick up ids all calling applications
3690   * associated with a particular payment instruction.
3691   */
3692  CURSOR c_app_ids (p_instr_id NUMBER)
3693  IS
3694  SELECT
3695      fnd.application_id
3696  FROM
3697      FND_APPLICATION          fnd,
3698      IBY_PAYMENTS_ALL         pmt,
3699      IBY_PAY_SERVICE_REQUESTS req,
3700      IBY_PAY_INSTRUCTIONS_ALL ins
3701  WHERE
3702      pmt.payment_instruction_id     = ins.payment_instruction_id     AND
3703      req.payment_service_request_id = pmt.payment_service_request_id AND
3704      fnd.application_id             = req.calling_app_id             AND
3705      ins.payment_instruction_id     = p_instr_id
3706  ;
3707 
3708  /*
3709   * Implementing the callout is optional for the calling app.
3710   * If the calling app does not implement the hook, then
3711   * the call to the hook will result in ORA-06576 error.
3712   *
3713   * There is no exception name associated with this code, so
3714   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
3715   * exception occurs, it is not fatal: we log the error and
3716   * proceed.
3717   *
3718   * If, on the other hand, the calling app implements the
3719   * callout, but the callout throws an exception, it is fatal
3720   * and we must abort the program (this will be caught
3721   * in WHEN OTHERS block).
3722   */
3723  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
3724  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
3725 
3726  BEGIN
3727 
3728      print_debuginfo(l_module_name, 'ENTER');
3729 
3730      FND_MSG_PUB.initialize;
3731 
3732      /*
3733       * STATUS CHANGE:
3734       *
3735       * API Responsibility:
3736       * instruction status = TERMINATED
3737       * payment_status  = REMOVED_INSTRUCTION_TERMINATED
3738       * document_status = REMOVED_INSTRUCTION_TERMINATED
3739       *
3740       */
3741 
3742      /*
3743       * STEP 1:
3744       *
3745       * If the given payment instruction is locked, it means
3746       * that some concurrent program is acting upon the
3747       * pmt instruction at the moment.
3748       *
3749       * To prevent data corruption do not allow the payment
3750       * instruction to be terminated.
3751       */
3752      l_flag := checkIfPmtEntityLocked(p_instr_id, 'PAYMENT_INSTRUCTION');
3753 
3754     /* for bug 6196551 */
3755         SELECT
3756              count(*)
3757          INTO
3758              l_valid_pmts_count
3759          FROM
3760              IBY_PAYMENTS_ALL pmt
3761          WHERE
3762              pmt.payment_instruction_id = p_instr_id AND
3763              pmt.payment_status NOT IN
3764                  (
3765                   PAY_STATUS_VOID,
3766                   PAY_STATUS_REMOVED,
3767 		  PAY_STATUS_STOPPED
3768                  );
3769 
3770     IF (l_valid_pmts_count=0) THEN
3771     l_flag := FALSE;
3772     END IF;
3773      IF (l_flag = TRUE) THEN
3774 
3775          print_debuginfo(l_module_name, 'Payment instruction '
3776              || p_instr_id
3777              || ' has been locked by a concurrent program.'
3778              || ' It cannot be terminated at present.'
3779              );
3780 
3781          x_return_status := FND_API.G_RET_STS_ERROR;
3782 
3783          l_error_code := 'IBY_INS_LOCKED';
3784          FND_MESSAGE.set_name('IBY', l_error_code);
3785          FND_MSG_PUB.ADD;
3786 
3787          --FND_MSG_PUB.COUNT_AND_GET(
3788          --    p_count => x_msg_count,
3789          --    p_data  => x_msg_data
3790          --    );
3791 
3792          print_debuginfo(l_module_name, 'Returning error response ..');
3793 
3794          print_debuginfo(l_module_name, 'EXIT');
3795 
3796          RETURN;
3797 
3798      ELSE
3799 
3800          print_debuginfo(l_module_name, 'Payment instruction '
3801              || p_instr_id
3802              || ' is not locked.'
3803              );
3804 
3805      END IF;
3806 
3807      /*
3808       * STEP 2:
3809       *
3810       * Update payment instruction, payment and document statuses
3811       * to 'terminated'.
3812       */
3813      UPDATE
3814          iby_pay_instructions_all
3815      SET
3816          payment_instruction_status = INS_STATUS_TERMINATED
3817      WHERE
3818          payment_instruction_id = p_instr_id
3819      ;
3820 
3821      BEGIN
3822 
3823          UPDATE
3824              IBY_PAYMENTS_ALL
3825          SET
3826              payment_status = PAY_STATUS_INS_TERM
3827          WHERE
3828              payment_instruction_id = p_instr_id     AND
3829              (
3830               payment_status <> PAY_STATUS_REMOVED       AND
3831               payment_status <> PAY_STATUS_VOID_SETUP    AND
3832               payment_status <> PAY_STATUS_VOID_OVERFLOW AND
3833               payment_status <> PAY_STATUS_SPOILED       AND
3834               payment_status <> PAY_STATUS_STOPPED       AND
3835               payment_status <> PAY_STATUS_INS_TERM      AND
3836               payment_status <> PAY_STATUS_REQ_TERM      AND
3837               payment_status <> PAY_STATUS_VOID          AND
3838               payment_status <> PAY_STATUS_ACK           AND
3839               payment_status <> PAY_STATUS_BNK_VALID     AND
3840               payment_status <> PAY_STATUS_PAID
3841              )
3842          ;
3843 
3844      EXCEPTION
3845 
3846          WHEN NO_DATA_FOUND THEN
3847              /*
3848               * Handle gracefully the situation where no payments
3849               * exist for the given request.
3850               */
3851              print_debuginfo(l_module_name, 'No payments in valid '
3852                  || 'status exist for payment instruction '
3853                  || p_instr_id
3854                  );
3855 
3856          WHEN OTHERS THEN
3857              print_debuginfo(l_module_name, 'Fatal: Exception occured '
3858                  || 'when attempting to update status of payments '
3859                  || 'for payment instruction '
3860                  || p_instr_id
3861                  || '. Aborting program ..'
3862                  );
3863              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
3864              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
3865              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
3866 
3867              /*
3868               * Propogate exception to caller.
3869               */
3870              RAISE;
3871 
3872      END;
3873 
3874      BEGIN
3875 
3876          UPDATE
3877              IBY_DOCS_PAYABLE_ALL
3878          SET
3879              document_status = DOC_STATUS_INS_TERM,
3880 
3881              /*
3882               * Fix for bug 4405981:
3883               *
3884               * The straight through flag should be set to 'N',
3885               * if the document was rejected / required manual
3886               * intervention.
3887               */
3888              straight_through_flag = 'N'
3889 
3890          WHERE
3891              payment_id IN
3892                  (
3893                   SELECT
3894                       payment_id
3895                   FROM
3896                       IBY_PAYMENTS_ALL
3897                   WHERE
3898                       payment_instruction_id = p_instr_id   AND
3899                       payment_status = PAY_STATUS_INS_TERM
3900                  )
3901                  AND
3902                  (
3903                   document_status <> DOC_STATUS_REJECTED    AND
3904                   document_status <> DOC_STATUS_REMOVED     AND
3905                   document_status <> DOC_STATUS_PMT_REMOVED AND
3906                   document_status <> DOC_STATUS_PMT_STOPPED AND
3907                   document_status <> DOC_STATUS_REQ_TERM    AND
3908                   document_status <> DOC_STATUS_INS_TERM    AND
3909                   document_status <> DOC_STATUS_VOID_SETUP  AND
3910                   document_status <> DOC_STATUS_PMT_VOIDED
3911                  )
3912          ;
3913 
3914     EXCEPTION
3915 
3916          WHEN NO_DATA_FOUND THEN
3917              /*
3918               * Handle gracefully the situation where no documents
3919               * exist for the given payment instruciton.
3920               */
3921              print_debuginfo(l_module_name, 'No payments exist for payment '
3922                  || 'instruction '
3923                  || p_instr_id
3924                  );
3925              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
3926 
3927          WHEN OTHERS THEN
3928              print_debuginfo(l_module_name, 'Fatal: Exception occured '
3929                  || 'when attempting to update status of payments '
3930                  || 'for payment instruction '
3931                  || p_instr_id
3932                  || '. Aborting program ..'
3933                  );
3934              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
3935              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
3936              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
3937 
3938              /*
3939               * Propogate exception to caller.
3940               */
3941              RAISE;
3942 
3943      END;
3944 
3945      /*
3946       * STEP 3:
3947       * Restore the Unused Check numbers and
3948       * Unlock the payment document that has been locked by this payment
3949       * instruction.
3950       */
3951      print_debuginfo(l_module_name, 'Restoring the Unused Check numbers '
3952          || 'by payment instruction '
3953          || p_instr_id
3954          );
3955 
3956 /*Restoring the Unused Check numbers*/
3957 /*Modified for Bug 7325373*/
3958      BEGIN
3959          BEGIN
3960                 SELECT last_issued_document_number INTO l_last_issued
3961                 FROM ce_payment_documents WHERE payment_instruction_id = p_instr_id;
3962              EXCEPTION
3963                 WHEN No_Data_Found THEN
3964                   l_document_locked := FALSE;
3965               print_debuginfo(l_module_name, 'Payment Document is not locked by the instruction '
3966              || p_instr_id
3967              );
3968          END;
3969          IF(l_document_locked = TRUE) THEN
3970         SELECT Max(paper_document_number), Min(paper_document_number), Count(*)
3971         INTO l_max_paper_document_number, l_min_paper_document_number, l_number_of_payments
3972         FROM iby_payments_all WHERE payment_instruction_id = p_instr_id;
3973 
3974           l_last_issued_modified := l_last_issued - l_number_of_payments;
3975          IF ((l_last_issued <> l_max_paper_document_number)
3976             OR ((l_max_paper_document_number - l_min_paper_document_number) <>  (l_number_of_payments - 1)))
3977             THEN
3978                RAISE l_irregular_document_numbers;
3979          END IF;
3980 
3981          UPDATE
3982              CE_PAYMENT_DOCUMENTS
3983          SET
3984              last_issued_document_number = l_last_issued_modified
3985          WHERE
3986              payment_instruction_id = p_instr_id
3987          RETURNING
3988              payment_document_id,
3989              payment_document_name
3990          INTO
3991              l_pmt_doc_id,
3992              l_pmt_doc_name
3993          ;
3994 
3995              print_debuginfo(l_module_name, 'Check number restored for Payment document id '
3996              || l_pmt_doc_id
3997              || ' with name '
3998              || l_pmt_doc_name
3999              );
4000 
4001 
4002         END IF;
4003      EXCEPTION
4004         WHEN l_irregular_document_numbers THEN
4005             print_debuginfo(l_module_name, 'Fatal: Exception occured '
4006              || 'while restoring the used check numbers.'
4007              || p_instr_id
4008              );
4009             RAISE;
4010 
4011         WHEN OTHERS THEN
4012              print_debuginfo(l_module_name, 'Non-Fatal: Exception occured '
4013              || 'while restoring the used check numbers. '
4014              || p_instr_id
4015              );
4016 
4017      END;
4018 
4019      print_debuginfo(l_module_name, 'Unlocking payment document locked '
4020          || 'by payment instruction '
4021          || p_instr_id
4022          );
4023 /* Unlocking the payment document*/
4024      BEGIN
4025 
4026          UPDATE
4027              CE_PAYMENT_DOCUMENTS
4028          SET
4029              payment_instruction_id = NULL
4030          WHERE
4031              payment_instruction_id = p_instr_id
4032          RETURNING
4033              payment_document_id,
4034              payment_document_name
4035          INTO
4036              l_pmt_doc_id,
4037              l_pmt_doc_name
4038          ;
4039 
4040          print_debuginfo(l_module_name, 'Payment document id '
4041              || l_pmt_doc_id
4042              || ' with name '
4043              || l_pmt_doc_name
4044              || ' unlocked successfully.'
4045              );
4046 
4047      EXCEPTION
4048          WHEN OTHERS THEN
4049 
4050          /*
4051           * This is a no-fatal exception. We will log the exception
4052           * and return.
4053           */
4054          print_debuginfo(l_module_name, 'Non-Fatal: Exception occured '
4055              || 'when unlocking pmt document locked by pmt instruction '
4056              || p_instr_id
4057              );
4058 
4059          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
4060          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
4061          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
4062 
4063      END;
4064 
4065      /*
4066       * STEP 4:
4067       *
4068       * Invoke callouts to inform calling applications about the
4069       * terminated documents payable.
4070       */
4071 
4072      /*
4073       * Pick up the names of all the applications which have
4074       * payments in the current payment instruction.
4075       *
4076       * Remember, one payment instruction can contain payments
4077       * across multiple calling applications.
4078       */
4079      OPEN  c_app_names (p_instr_id);
4080      FETCH c_app_names BULK COLLECT INTO l_appNamesTab;
4081      CLOSE c_app_names;
4082 
4083      /*
4084       * Pick up the ids of all the applications which have
4085       * payments in the current payment instruction.
4086       *
4087       * Remember, one payment instruction can contain payments
4088       * across multiple calling applications.
4089       */
4090      OPEN  c_app_ids (p_instr_id);
4091      FETCH c_app_ids BULK COLLECT INTO l_appIdsTab;
4092      CLOSE c_app_ids;
4093 
4094      /*
4095       * This should normally never happen.
4096       */
4097      IF (l_appIdsTab.COUNT = 0) THEN
4098 
4099          print_debuginfo(l_module_name, 'No calling application ids '
4100              || 'were fetched for payment instruction '
4101              || p_instr_id
4102              || ' Possible data corruption. Raising exception ..'
4103              );
4104 
4105          APP_EXCEPTION.RAISE_EXCEPTION;
4106 
4107      END IF;
4108 
4109      /*
4110       * Loop through all the application names, invoking the
4111       * callout of each application.
4112       */
4113      FOR i IN l_appNamesTab.FIRST .. l_appNamesTab.LAST LOOP
4114 
4115          /*
4116           * Get the constructed package name to use in the
4117           * call out.
4118           */
4119          l_pkg_name := construct_callout_pkg_name(l_appNamesTab(i));
4120 
4121          print_debuginfo(l_module_name, 'Constructed package name: '
4122              || l_pkg_name);
4123 
4124          IF (l_pkg_name IS NULL) THEN
4125 
4126              print_debuginfo(l_module_name, 'Package name is null. '
4127                  || 'Raising exception.');
4128 
4129              APP_EXCEPTION.RAISE_EXCEPTION;
4130 
4131          END IF;
4132 
4133          /*
4134           * Get the next available rejected document group id.
4135           */
4136          SELECT
4137              IBY_REJECTED_DOCS_GROUP_S.NEXTVAL
4138          INTO
4139              l_rejection_id
4140          FROM
4141              DUAL
4142          ;
4143 
4144          /*
4145           * Update the terminated documents for this calling app
4146           * with the rejected document group id. The calling
4147           * application will identify rejected documents using
4148           * this id.
4149           */
4150          UPDATE
4151              IBY_DOCS_PAYABLE_ALL
4152          SET
4153              rejected_docs_group_id = l_rejection_id
4154          WHERE
4155              document_status  = DOC_STATUS_INS_TERM AND
4156              calling_app_id   = l_appIdsTab(i)      AND
4157              payment_id IN
4158                  (SELECT
4159                       payment_id
4160                   FROM
4161                       IBY_PAYMENTS_ALL
4162                   WHERE
4163                       payment_instruction_id = p_instr_id    AND
4164                       payment_status = PAY_STATUS_INS_TERM
4165                   )
4166          ;
4167 
4168          /*
4169           * Now try to call the external app's implementation of the hook.
4170           * The calling app may or may not have implemented the hook, so
4171           * it's not fatal if the implementation does not exist.
4172           */
4173          l_callout_name := l_pkg_name || '.' || 'documents_payable_rejected';
4174 
4175          print_debuginfo(l_module_name, 'Attempting to invoke callout: '
4176              || l_callout_name);
4177 
4178          l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7)';
4179 
4180          BEGIN
4181 
4182              print_debuginfo(l_module_name, 'Parameter passed to callout - '
4183                  || 'l_rejection_id: '
4184                  || l_rejection_id
4185                  );
4186 
4187              EXECUTE IMMEDIATE
4188                  (l_stmt)
4189              USING
4190                  IN  l_api_version,
4191                  IN  FND_API.G_FALSE,
4192                  IN  FND_API.G_FALSE,
4193                  OUT x_return_status,
4194                  OUT l_msg_count,
4195                  OUT l_msg_data,
4196                  IN  l_rejection_id
4197              ;
4198 
4199              /*
4200               * If the called procedure did not return success,
4201               * raise an exception.
4202               */
4203              IF (x_return_status IS NULL OR
4204                  x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
4205 
4206                  print_debuginfo(l_module_name, 'Fatal: External app callout '''
4207                      || l_callout_name
4208                      || ''', returned failure status - '
4209                      || x_return_status
4210                      || '. Raising exception.'
4211                      );
4212 
4213                  APP_EXCEPTION.RAISE_EXCEPTION;
4214 
4215              END IF;
4216 
4217          EXCEPTION
4218 
4219              WHEN PROCEDURE_NOT_IMPLEMENTED THEN
4220                  print_debuginfo(l_module_name, 'Callout "' || l_callout_name
4221                      || '" not implemented by calling app '
4222                      || l_appNamesTab(i) || '.');
4223 
4224                  print_debuginfo(l_module_name, 'Skipping hook call.');
4225 
4226 
4227              WHEN OTHERS THEN
4228                  print_debuginfo(l_module_name, 'Fatal: External app callout '''
4229                      || l_callout_name
4230                      || ''', generated exception.'
4231                      );
4232 
4233                  print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
4234                  print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
4235                  FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
4236 
4237                  /*
4238                   * Propogate exception to caller.
4239                   */
4240                  RAISE;
4241 
4242          END;
4243 
4244      END LOOP;
4245 
4246      /*
4247       * STEP 5:
4248       *
4249       * Clean up the pmt instruction by unstamping it. In case the
4250       * concurrent request that was handling this pmt instruction
4251       * had aborted with an exception, this step will clean up the data.
4252       */
4253 
4254      /*
4255       * Fix for bug 5206672:
4256       *
4257       * If we reached here, then the payment instruction has
4258       * been updated to TERMINATED status and the calling app
4259       * has been informed.
4260       *
4261       * Perform a COMMIT here before calling unlock_pmt_entity(..)
4262       * otherwise a deadlock ensues.
4263       */
4264      COMMIT;
4265 
4266      unlock_pmt_entity(
4267          p_instr_id,
4268          'PAYMENT_INSTRUCTION',
4269          l_ret_status
4270          );
4271 
4272      x_return_status := FND_API.G_RET_STS_SUCCESS;
4273 
4274      print_debuginfo(l_module_name, 'EXIT');
4275 
4276  EXCEPTION
4277 
4278      WHEN OTHERS THEN
4279 
4280          print_debuginfo(l_module_name, 'Exception occured when '
4281              || 'terminating payment instruction '
4282              || p_instr_id
4283              || ', with status '
4284              || p_instr_status
4285              );
4286 
4287          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
4288          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
4289          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
4290 
4291          x_return_status := FND_API.G_RET_STS_ERROR;
4292 
4293          print_debuginfo(l_module_name, 'EXIT');
4294 
4295  END terminate_pmt_instruction;
4296 
4297 /*--------------------------------------------------------------------
4298  | NAME:
4299  |     terminate_pmt_request
4300  |
4301  |
4302  | PURPOSE:
4303  |
4304  |
4305  | PARAMETERS:
4306  |     IN
4307  |
4308  |
4309  |     OUT
4310  |
4311  |
4312  | RETURNS:
4313  |
4314  | NOTES:
4315  |   Internal API, not for public use.
4316  |
4317  | UPDATE ON MAY-05-2006, rameshsh
4318  | This method was not performing a COMMIT earlier. Due to bug 5206672
4319  | a COMMIT has been added in the code before invoking unlock_pmt_entity(..).
4320  |
4321  *---------------------------------------------------------------------*/
4322  PROCEDURE terminate_pmt_request (
4323      p_req_id         IN NUMBER,
4324      p_req_status     IN VARCHAR2,
4325      x_return_status  OUT NOCOPY VARCHAR2
4326      )
4327  IS
4328 
4329  l_module_name    CONSTANT VARCHAR2(200) := G_PKG_NAME
4330                                             || '.terminate_pmt_request';
4331 
4332  l_rejection_id   NUMBER(15);
4333 
4334  /* used in forming callout procedure name */
4335  l_calling_app_id NUMBER;
4336  l_app_short_name VARCHAR2(200);
4337  l_pkg_name       VARCHAR2(200);
4338  l_callout_name   VARCHAR2(500);
4339  l_stmt           VARCHAR2(1000);
4340 
4341  /* used in invocation of callout procedure */
4342  l_api_version    CONSTANT NUMBER := 1.0;
4343  l_msg_count      NUMBER;
4344  l_msg_data       VARCHAR2(2000);
4345 
4346  l_flag           BOOLEAN := FALSE;
4347 
4348  l_error_code     VARCHAR2(3000);
4349  l_ret_status     VARCHAR2(300);
4350 
4351  /*
4352   * Implementing the callout is optional for the calling app.
4353   * If the calling app does not implement the hook, then
4354   * the call to the hook will result in ORA-06576 error.
4355   *
4356   * There is no exception name associated with this code, so
4357   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
4358   * exception occurs, it is not fatal: we log the error and
4359   * proceed.
4360   *
4361   * If, on the other hand, the calling app implements the
4362   * callout, but the callout throws an exception, it is fatal
4363   * and we must abort the program (this will be caught
4364   * in WHEN OTHERS block).
4365   */
4366  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
4367  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
4368 
4369  BEGIN
4370 
4371      print_debuginfo(l_module_name, 'ENTER');
4372 
4373      print_debuginfo(l_module_name, 'Parameters passed - '
4374          || 'payment request id: '
4375          || p_req_id
4376          || ', payment request status: '
4377          || p_req_status
4378          );
4379 
4380      FND_MSG_PUB.initialize;
4381 
4382      /*
4383       * STATUS CHANGE:
4384       *
4385       * API Responsibility:
4386       * request status  = TERMINATED
4387       * payment_status  = REMOVED_REQUEST_TERMINATED
4388       * document_status = REMOVED_REQUEST_TERMINATED
4389       *
4390       */
4391 
4392      /*
4393       * STEP 1:
4394       *
4395       * If the given payment request is locked, it means
4396       * that some concurrent program is acting upon the
4397       * ppr at the moment.
4398       *
4399       * To prevent data corruption do not allow the payment
4400       * request to be terminated.
4401       */
4402      l_flag := checkIfPmtEntityLocked(p_req_id, 'PAYMENT_REQUEST');
4403 
4404      IF (l_flag = TRUE) THEN
4405 
4406          print_debuginfo(l_module_name, 'Payment request '
4407              || p_req_id
4408              || ' has been locked by a concurrent program.'
4409              || ' It cannot be terminated at present.'
4410              );
4411 
4412          x_return_status := FND_API.G_RET_STS_ERROR;
4413 
4414          l_error_code := 'IBY_PPR_LOCKED';
4415          FND_MESSAGE.set_name('IBY', l_error_code);
4416          FND_MSG_PUB.ADD;
4417 
4418          --FND_MSG_PUB.COUNT_AND_GET(
4419          --    p_count => x_msg_count,
4420          --    p_data  => x_msg_data
4421          --    );
4422 
4423          print_debuginfo(l_module_name, 'Returning error response ..');
4424 
4425          print_debuginfo(l_module_name, 'EXIT');
4426 
4427          RETURN;
4428 
4429      ELSE
4430 
4431          print_debuginfo(l_module_name, 'Payment request '
4432              || p_req_id
4433              || ' is not locked.'
4434              );
4435 
4436      END IF;
4437 
4438      /*
4439       * Fix for bug  5112559:
4440       *
4441       * Before performing any action, first check if any of
4442       * the payments of this ppr are part of a payment instruction,
4443       * if so, do not allow the ppr to be terminated.
4444       */
4445      l_flag := checkIfPmtInInstExists(p_req_id);
4446 
4447      IF (l_flag = TRUE) THEN
4448 
4449          print_debuginfo(l_module_name, 'The payment request '
4450              || p_req_id
4451              || ' contains at least one payment that is '
4452              || 'part of a payment instruction. Payment '
4453              || 'request cannot be terminated at this stage.'
4454              );
4455 
4456          x_return_status := FND_API.G_RET_STS_ERROR;
4457 
4458          l_error_code := 'IBY_PPR_TERM_NOT_ALLOWED';
4459          FND_MESSAGE.set_name('IBY', l_error_code);
4460          FND_MSG_PUB.ADD;
4461 
4462          --FND_MSG_PUB.COUNT_AND_GET(
4463          --    p_count => x_msg_count,
4464          --    p_data  => x_msg_data
4465          --    );
4466 
4467          print_debuginfo(l_module_name, 'Returning error response ..');
4468 
4469          print_debuginfo(l_module_name, 'EXIT');
4470 
4471          RETURN;
4472 
4473      END IF;
4474 
4475      /*
4476       * STEP 2:
4477       *
4478       * Set the request status to TERMINATED.
4479       */
4480      UPDATE
4481          iby_pay_service_requests
4482      SET
4483          payment_service_request_status = REQ_STATUS_TERMINATED
4484      WHERE
4485          payment_service_request_id = p_req_id
4486      ;
4487 
4488 
4489      BEGIN
4490 
4491          UPDATE
4492              IBY_PAYMENTS_ALL
4493          SET
4494              payment_status = PAY_STATUS_REQ_TERM
4495          WHERE
4496              payment_service_request_id = p_req_id       AND
4497              (
4498               payment_status <> PAY_STATUS_REMOVED       AND
4499               payment_status <> PAY_STATUS_VOID_SETUP    AND
4500               payment_status <> PAY_STATUS_VOID_OVERFLOW AND
4501               payment_status <> PAY_STATUS_SPOILED       AND
4502               payment_status <> PAY_STATUS_STOPPED       AND
4503               payment_status <> PAY_STATUS_INS_TERM      AND
4504               payment_status <> PAY_STATUS_REQ_TERM      AND
4505               payment_status <> PAY_STATUS_VOID          AND
4506               payment_status <> PAY_STATUS_ACK           AND
4507               payment_status <> PAY_STATUS_BNK_VALID     AND
4508               payment_status <> PAY_STATUS_PAID
4509              )
4510          ;
4511 
4512      EXCEPTION
4513 
4514          WHEN NO_DATA_FOUND THEN
4515              /*
4516               * Handle gracefully the situation where no payments
4517               * exist for the given request.
4518               */
4519              print_debuginfo(l_module_name, 'No payments exist for payment '
4520                  || 'request '
4521                  || p_req_id
4522                  );
4523 
4524 
4525          WHEN OTHERS THEN
4526              print_debuginfo(l_module_name, 'Fatal: Exception occured '
4527                  || 'when attempting to update status of payments '
4528                  || 'for payment request '
4529                  || p_req_id
4530                  || '. Aborting program ..'
4531                  );
4532              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
4533              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
4534              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
4535 
4536              /*
4537               * Propogate exception to caller.
4538               */
4539              RAISE;
4540 
4541      END;
4542 
4543      /*
4544       * STEP 3:
4545       *
4546       * Set status of documents to TERMINATED.
4547       */
4548      BEGIN
4549 
4550          UPDATE
4551              IBY_DOCS_PAYABLE_ALL
4552          SET
4553              document_status = DOC_STATUS_REQ_TERM,
4554 
4555              /*
4556               * Fix for bug 4405981:
4557               *
4558               * The straight through flag should be set to 'N',
4559               * if the document was rejected / required manual
4560               * intervention.
4561               */
4562              straight_through_flag = 'N'
4563          WHERE
4564              payment_service_request_id = p_req_id   AND
4565              (
4566               document_status <> DOC_STATUS_REJECTED    AND
4567               document_status <> DOC_STATUS_REMOVED     AND
4568               document_status <> DOC_STATUS_PMT_REMOVED AND
4569               document_status <> DOC_STATUS_PMT_STOPPED AND
4570               document_status <> DOC_STATUS_REQ_TERM    AND
4571               document_status <> DOC_STATUS_INS_TERM    AND
4572               document_status <> DOC_STATUS_VOID_SETUP  AND
4573               document_status <> DOC_STATUS_PMT_VOIDED
4574              )
4575          ;
4576 
4577      EXCEPTION
4578 
4579          WHEN NO_DATA_FOUND THEN
4580 
4581              /*
4582               * Handle gracefully the situation where no documents payable
4583               * exist for the given request.
4584               */
4585              print_debuginfo(l_module_name, 'No docs payable exist for payment '
4586                  || 'request '
4587                  || p_req_id
4588                  || '. Exiting ..'
4589                  );
4590 
4591              /*
4592               * If no documents payable exist for the given request,
4593               * it is not worth proceeding further.
4594               *
4595               * Return success status to the caller.
4596               */
4597              x_return_status := FND_API.G_RET_STS_SUCCESS;
4598 
4599              print_debuginfo(l_module_name, 'EXIT');
4600              RETURN;
4601 
4602          WHEN OTHERS THEN
4603              print_debuginfo(l_module_name, 'Fatal: Exception occured '
4604                  || 'when attempting to update status of documents '
4605                  || 'payable for payment request '
4606                  || p_req_id
4607                  || '. Aborting program ..'
4608                  );
4609              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
4610              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
4611              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
4612 
4613              /*
4614               * Propogate exception to caller.
4615               */
4616              RAISE;
4617 
4618      END;
4619 
4620      /*
4621       * STEP 4:
4622       *
4623       * Inform calling application about rejected documents.
4624       */
4625 
4626      /*
4627       * Get the next available rejected document group id.
4628       */
4629      SELECT
4630          IBY_REJECTED_DOCS_GROUP_S.NEXTVAL
4631      INTO
4632          l_rejection_id
4633      FROM
4634          DUAL
4635      ;
4636 
4637      /*
4638       * Update the terminated documents with the rejected document
4639       * group id. The calling application will identify rejected
4640       * documents using this id.
4641       */
4642      UPDATE
4643          IBY_DOCS_PAYABLE_ALL
4644      SET
4645          rejected_docs_group_id = l_rejection_id
4646      WHERE
4647          document_status            = DOC_STATUS_REQ_TERM AND
4648          payment_service_request_id = p_req_id
4649      ;
4650 
4651      /*
4652       * Get the application name of the calling app. This
4653       * will be used in the callout.
4654       */
4655      SELECT
4656          fnd.application_short_name
4657      INTO
4658          l_app_short_name
4659      FROM
4660          FND_APPLICATION          fnd,
4661          IBY_PAY_SERVICE_REQUESTS req
4662      WHERE
4663          fnd.application_id             = req.calling_app_id AND
4664          req.payment_service_request_id = p_req_id
4665      ;
4666 
4667      /*
4668       * Get the constructed package name to use in the
4669       * call out.
4670       */
4671      l_pkg_name := construct_callout_pkg_name(l_app_short_name);
4672 
4673      print_debuginfo(l_module_name, 'Constructed package name: '
4674          || l_pkg_name);
4675 
4676      IF (l_pkg_name IS NULL) THEN
4677 
4678          print_debuginfo(l_module_name, 'Package name is null. '
4679              || 'Raising exception.');
4680 
4681          APP_EXCEPTION.RAISE_EXCEPTION;
4682 
4683      END IF;
4684 
4685      /*
4686       * Now try to call the external app's implementation of the hook.
4687       * The calling app may or may not have implemented the hook, so
4688       * it's not fatal if the implementation does not exist.
4689       */
4690      l_callout_name := l_pkg_name || '.' || 'documents_payable_rejected';
4691 
4692      print_debuginfo(l_module_name, 'Attempting to invoke callout: '
4693          || l_callout_name);
4694 
4695      print_debuginfo(l_module_name, 'Parameter(s) passed to callout - '
4696          || 'rejection id: '
4697          || l_rejection_id
4698          );
4699 
4700      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7)';
4701 
4702      BEGIN
4703 
4704          EXECUTE IMMEDIATE
4705              (l_stmt)
4706          USING
4707              IN  l_api_version,
4708              IN  FND_API.G_FALSE,
4709              IN  FND_API.G_FALSE,
4710              OUT x_return_status,
4711              OUT l_msg_count,
4712              OUT l_msg_data,
4713              IN  l_rejection_id
4714          ;
4715 
4716          print_debuginfo(l_module_name, 'Parameter(s) returned by callout - '
4717          || 'x_return_status: '
4718          || x_return_status
4719          );
4720 
4721          /*
4722           * If the called procedure did not return success,
4723           * raise an exception.
4724           */
4725          IF (x_return_status IS NULL OR
4726              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
4727 
4728              print_debuginfo(l_module_name, 'Fatal: External app callout '''
4729                  || l_callout_name
4730                  || ''', returned failure status - '
4731                  || x_return_status
4732                  || '. Raising exception.'
4733                  );
4734 
4735              APP_EXCEPTION.RAISE_EXCEPTION;
4736 
4737          END IF;
4738 
4739      EXCEPTION
4740 
4741          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
4742              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
4743                  || '" not implemented by calling app '
4744                  || l_app_short_name || '.');
4745 
4746              print_debuginfo(l_module_name, 'Skipping hook call.');
4747 
4748 
4749          WHEN OTHERS THEN
4750              print_debuginfo(l_module_name, 'Fatal: External app callout '''
4751                  || l_callout_name
4752                  || ''', generated exception.'
4753                  );
4754 
4755              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
4756              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
4757              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
4758 
4759              /*
4760               * Propogate exception to caller.
4761               */
4762              RAISE;
4763      END;
4764 
4765      /*
4766       * STEP 5:
4767       *
4768       * Clean up the ppr by unstamping it. In case the
4769       * concurrent request that was handling this ppr
4770       * had aborted with an exception, this step will
4771       * clean up the data.
4772       */
4773 
4774      /*
4775       * Fix for bug 5206672:
4776       *
4777       * If we reached here, then the payment request has
4778       * been updated to TERMINATED status and the calling app
4779       * has been informed.
4780       *
4781       * Perform a COMMIT here before calling unlock_pmt_entity(..)
4782       * otherwise a deadlock ensues.
4783       */
4784      COMMIT;
4785 
4786      unlock_pmt_entity(
4787          p_req_id,
4788          'PAYMENT_REQUEST',
4789          l_ret_status
4790          );
4791 
4792      x_return_status := FND_API.G_RET_STS_SUCCESS;
4793 
4794      print_debuginfo(l_module_name, 'EXIT');
4795 
4796  EXCEPTION
4797 
4798      WHEN OTHERS THEN
4799 
4800          print_debuginfo(l_module_name, 'Exception occured when '
4801              || 'terminating payment request '
4802              || p_req_id
4803              || ', with status '
4804              || p_req_status
4805              );
4806 
4807          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
4808          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
4809          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
4810 
4811          x_return_status := FND_API.G_RET_STS_ERROR;
4812 
4813          print_debuginfo(l_module_name, 'EXIT');
4814 
4815  END terminate_pmt_request;
4816 
4817 /*--------------------------------------------------------------------
4818  | NAME:
4819  |     resubmit_pmt_request
4820  |
4821  |
4822  | PURPOSE:
4823  |
4824  |
4825  | PARAMETERS:
4826  |     IN
4827  |     p_payreq_id     The id of the payment request that needs to be
4828  |                     re-processed by the Build Program.
4829  |     OUT
4830  |     x_conc_req_id   The id of the concurrent request that was launched
4831  |                     by this API. The user will have to check this
4832  |                     concurrent request status via SRS UI to know the
4833  |                     result of the concurrent request. This concurrent
4834  |                     request will invoke the Build Program for this
4835  |                     payment request.
4836  |     x_error_buf     message buffer that stores the cause of the error.
4837  |     x_return_status '-1' will be returned in the case of an error
4838  |                     '0' will be returned if the request completed
4839  |                     successfully.
4840  |
4841  | RETURNS:
4842  |
4843  | NOTES:
4844  |     This method will perform a COMMIT after each functional
4845  |     flow is complete. The caller should have finished all database
4846  |     operations before making a call this method. The caller should
4847  |     not call commit after invoking this method.
4848  |
4849  *---------------------------------------------------------------------*/
4850  PROCEDURE resubmit_pmt_request (
4851      p_payreq_id     IN NUMBER,
4852      x_conc_req_id   IN OUT NOCOPY NUMBER,
4853      x_error_buf     IN OUT NOCOPY VARCHAR2,
4854      x_return_status IN OUT NOCOPY NUMBER
4855      )
4856  IS
4857 
4858  l_module_name   CONSTANT VARCHAR2(200) := G_PKG_NAME
4859                                            || '.resubmit_pmt_request';
4860 
4861  l_req_attribs   IBY_PAY_SERVICE_REQUESTS%ROWTYPE;
4862  l_ret_status    VARCHAR2(200);
4863 
4864     l_icx_numeric_characters   VARCHAR2(30); -- Bug 6411356
4865     l_bool_val   boolean;  -- Bug 6411356
4866 
4867  BEGIN
4868 
4869      print_debuginfo(l_module_name, 'ENTER');
4870 
4871      FND_MSG_PUB.initialize;
4872 
4873      /*
4874       * STATUS CHANGE:
4875       *
4876       * UI Responsibility:
4877       * request status = RETRY_DOCUMENT_VALIDATION    |
4878       *                  RETRY_PAYMENT_CREATION
4879       * payment_status = MODIFIED                     |
4880       *                  MODIFIED_PAYEE_BANK_ACCOUNT
4881       *
4882       * API Responsibility:
4883       * NONE
4884       */
4885 
4886      /*
4887       * Pick up the attributes of this request; these are
4888       * params like rejection level settings, review
4889       * payments setting etc.
4890       */
4891      SELECT
4892          payment_service_request_id,
4893          calling_app_id,
4894          call_app_pay_service_req_code,
4895          payment_service_request_status,
4896          process_type,
4897          allow_zero_payments_flag,
4898          created_by,
4899          creation_date,
4900          last_updated_by,
4901          last_update_date,
4902          object_version_number,
4903          last_update_login,
4904          internal_bank_account_id,
4905          payment_profile_id,
4906          maximum_payment_amount,
4907          minimum_payment_amount,
4908          document_rejection_level_code,
4909          payment_rejection_level_code,
4910          require_prop_pmts_review_flag,
4911          org_type,
4912          attribute_category,
4913          attribute1,
4914          attribute2,
4915          attribute3,
4916          attribute4,
4917          attribute5,
4918          attribute6,
4919          attribute7,
4920          attribute8,
4921          attribute9,
4922          attribute10,
4923          attribute11,
4924          attribute12,
4925          attribute13,
4926          attribute14,
4927          attribute15,
4928          create_pmt_instructions_flag,
4929          payment_document_id,
4930          request_id
4931      INTO
4932          l_req_attribs
4933      FROM
4934          IBY_PAY_SERVICE_REQUESTS
4935      WHERE
4936          PAYMENT_SERVICE_REQUEST_ID = p_payreq_id
4937      ;
4938 
4939      /*
4940       * Now resubmit the payment request by invoking
4941       * the Build Program functional flows again for
4942       * this request.
4943       *
4944       * This method will begin processing the payment
4945       * request from the last processed point. Therefore,
4946       * we need not bother about the last processed point
4947       * here.
4948       *
4949       * This will launch a concurrent request for processing
4950       * the payment request. We will return the concurrent
4951       * request id back to the user.
4952       */
4953 
4954 
4955     --Bug 6411356
4956     --below code added to set the current nls character setting
4957     --before submitting a child requests.
4958     fnd_profile.get('ICX_NUMERIC_CHARACTERS',l_icx_numeric_characters);
4959     l_bool_val:= FND_REQUEST.SET_OPTIONS( numeric_characters => l_icx_numeric_characters);
4960 
4961      x_conc_req_id := FND_REQUEST.SUBMIT_REQUEST(
4962                      'IBY',
4963                      'IBYBUILD',
4964                      '',
4965                      '',
4966                      FALSE,
4967                      ''||l_req_attribs.calling_app_id||'',
4968                      ''||l_req_attribs.call_app_pay_service_req_code||'',
4969                      ''||l_req_attribs.internal_bank_account_id||'',
4970                      ''||l_req_attribs.payment_profile_id||'',
4971                      ''||l_req_attribs.allow_zero_payments_flag||'',
4972                      ''||l_req_attribs.maximum_payment_amount||'',
4973                      ''||l_req_attribs.minimum_payment_amount||'',
4974                      ''||l_req_attribs.document_rejection_level_code||'',
4975                      ''||l_req_attribs.payment_rejection_level_code||'',
4976                      ''||l_req_attribs.require_prop_pmts_review_flag||'',
4977                      'N',
4978                      '', '', '', '', '', '', '', '', '', '',
4979                      '', '', '', '', '', '', '', '', '', '',
4980                      '', '', '', '', '', '', '', '', '', '',
4981                      '', '', '', '', '', '', '', '', '', '',
4982                      '', '', '', '', '', '', '', '', '', '',
4983                      '', '', '', '', '', '', '', '', '', '',
4984                      '', '', '', '', '', '', '', '', '', '',
4985                      '', '', '', '', '', '', '', '', '', '',
4986                      '', '', '', '', '', '', ''
4987                      );
4988 
4989      IF (x_conc_req_id = 0) THEN
4990 
4991          print_debuginfo(l_module_name, 'Concurrent program request failed.');
4992          APP_EXCEPTION.RAISE_EXCEPTION;
4993 
4994      ELSE
4995 
4996          print_debuginfo(l_module_name, 'The concurrent request was '
4997              || 'launched successfully. '
4998              || 'Check concurrent request id :'
4999              || to_char(x_conc_req_id)
5000              );
5001 
5002          /*
5003           * Lock the payment request so that the user is not
5004           * allowed to take any action upon this payment
5005           * request until the concurrent request just launched
5006           * has completed.
5007           */
5008          lock_pmt_entity(
5009              p_payreq_id,
5010              'PAYMENT_REQUEST',
5011              x_conc_req_id,
5012              l_ret_status
5013              );
5014 
5015          /*
5016           * If we are unable to lock the payment request, abort.
5017           */
5018          IF (l_ret_status <> FND_API.G_RET_STS_SUCCESS) THEN
5019 
5020              print_debuginfo(l_module_name, 'Unable to lock payment '
5021                  || 'process request: '
5022                  || p_payreq_id
5023                  || '.'
5024                  );
5025 
5026              APP_EXCEPTION.RAISE_EXCEPTION;
5027 
5028          END IF;
5029 
5030      END IF;
5031 
5032      x_return_status := 0;
5033      x_error_buf := 'BUILD PROGRAM INVOKED - RESUBMITTING PAYMENT'
5034          || ' REQUEST SUCCEEDED';
5035      print_debuginfo(l_module_name, 'EXIT');
5036 
5037  EXCEPTION
5038 
5039    WHEN OTHERS THEN
5040 
5041      print_debuginfo(l_module_name, 'Exception occured when resubmitting '
5042          || 'payment request id '
5043          || p_payreq_id
5044          );
5045      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
5046      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
5047      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
5048 
5049      x_error_buf := 'BUILD PROGRAM ERROR - RESUBMITTING PAYMENT'
5050          || ' REQUEST FAILED';
5051 
5052      x_return_status := -1;
5053 
5054      print_debuginfo(l_module_name, 'EXIT');
5055 
5056  END resubmit_pmt_request;
5057 
5058 /*--------------------------------------------------------------------
5059  | NAME:
5060  |     resubmit_instruction
5061  |
5062  |
5063  | PURPOSE:
5064  |
5065  |
5066  | PARAMETERS:
5067  |     IN
5068  |
5069  |
5070  |     OUT
5071  |
5072  |
5073  | RETURNS:
5074  |
5075  | NOTES:
5076  |   Internal API, not for public use.
5077  |
5078  *---------------------------------------------------------------------*/
5079  PROCEDURE resubmit_instruction (
5080      p_ins_id        IN NUMBER,
5081      x_conc_req_id   IN OUT NOCOPY NUMBER,
5082      x_error_buf     IN OUT NOCOPY VARCHAR2,
5083      x_return_status IN OUT NOCOPY NUMBER
5084      )
5085  IS
5086 
5087  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME || '.resubmit_instruction';
5088  l_str_ret_status       VARCHAR2(200);
5089  l_icx_numeric_characters   VARCHAR2(30); -- Bug 6411356
5090  l_bool_val   boolean;  -- Bug 6411356
5091 
5092  BEGIN
5093 
5094      print_debuginfo(l_module_name, 'ENTER');
5095 
5096      FND_MSG_PUB.initialize;
5097 
5098      /*
5099       * STATUS CHANGE:
5100       *
5101       * UI Responsibility:
5102       * instruction status = RETRY_CREATION
5103       *
5104       * API Responsibility:
5105       * NONE
5106       */
5107 
5108      /*
5109       * This will launch a concurrent request for processing
5110       * the payment instruction. We will return the concurrent
5111       * request id back to the user.
5112       */
5113 
5114 
5115     --Bug 6411356
5116     --below code added to set the current nls character setting
5117     --before submitting a child requests.
5118     fnd_profile.get('ICX_NUMERIC_CHARACTERS',l_icx_numeric_characters);
5119     l_bool_val:= FND_REQUEST.SET_OPTIONS( numeric_characters => l_icx_numeric_characters);
5120 
5121 
5122      x_conc_req_id := FND_REQUEST.SUBMIT_REQUEST(
5123                      'IBY',
5124                      'IBYREPICP',
5125                      '',
5126                      '',
5127                      FALSE,
5128                      ''||p_ins_id||'',
5129                      '', '', '', '', '', '', '', '', '', '',
5130                      '', '', '', '', '', '', '', '', '', '',
5131                      '', '', '', '', '', '', '', '', '', '',
5132                      '', '', '', '', '', '', '', '', '', '',
5133                      '', '', '', '', '', '', '', '', '', '',
5134                      '', '', '', '', '', '', '', '', '', '',
5135                      '', '', '', '', '', '', '', '', '', '',
5136                      '', '', '', '', '', '', '', '', '', '',
5137                      '', '', '', '', '', '', '', '', '', '',
5138                      '', '', '', '', '', '', ''
5139                      );
5140 
5141      IF (x_conc_req_id = 0) THEN
5142 
5143          print_debuginfo(l_module_name, 'Concurrent program request failed.');
5144          APP_EXCEPTION.RAISE_EXCEPTION;
5145 
5146      ELSE
5147 
5148          print_debuginfo(l_module_name, 'The concurrent request was '
5149              || 'launched successfully. '
5150              || 'Check concurrent request id :'
5151              || to_char(x_conc_req_id)
5152              );
5153 
5154          /*
5155           * Lock the payment instruction so that the user is not
5156           * allowed to take any action upon this payment
5157           * instruction until the concurrent request just launched
5158           * has completed.
5159           */
5160 
5161          /*
5162           * Fix for bug 5206725:
5163           *
5164           * Pass a VARCHAR data type for the return status
5165           * instead of a NUMBER data type.
5166           */
5167          lock_pmt_entity(
5168              p_ins_id,
5169              'PAYMENT_INSTRUCTION',
5170              x_conc_req_id,
5171              l_str_ret_status
5172              );
5173 
5174          IF (l_str_ret_status <> FND_API.G_RET_STS_SUCCESS) THEN
5175 
5176              print_debuginfo(l_module_name, 'Unable to lock payment '
5177                  || 'instruction: '
5178                  || p_ins_id
5179                  || '.'
5180                  );
5181 
5182              APP_EXCEPTION.RAISE_EXCEPTION;
5183 
5184          END IF;
5185 
5186      END IF;
5187 
5188      x_return_status := 0;
5189      x_error_buf := 'PICP INVOKED - RESUBMITTING PAYMENT'
5190          || ' INSTRUCTION SUCCEEDED';
5191 
5192      print_debuginfo(l_module_name, 'EXIT');
5193 
5194  EXCEPTION
5195 
5196    WHEN OTHERS THEN
5197 
5198      print_debuginfo(l_module_name, 'Exception occured when resubmitting '
5199          || 'payment instruction '
5200          || p_ins_id
5201          );
5202      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
5203      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
5204      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
5205 
5206      x_error_buf := 'PICP ERROR - RESUBMITTING PAYMENT'
5207          || ' INSTRUCTION FAILED';
5208 
5209      x_return_status := -1;
5210 
5211      print_debuginfo(l_module_name, 'EXIT');
5212 
5213  END resubmit_instruction;
5214 
5215 /*--------------------------------------------------------------------
5216  | NAME:
5217  |     reprint_prenum_pmt_documents
5218  |
5219  |
5220  | PURPOSE:
5221  |     This API should be called if it is required to re-print some of the
5222  |     paper documents of a payment instruction. This API should only
5223  |     be called with the list of paper documents that were spoilt (not
5224  |     with the list of paper documents that were skipped, issued etc.).
5225  |
5226  |     The list of used paper documents numbers will be used to insert
5227  |     records into the IBY_USED_PAYMENT_DOCS table.
5228  |
5229  |     The list of new paper document numbers will be used to update the
5230  |     IBY_PAYMENTS_ALL table with the new paper document numbers for
5231  |     the corresponding paments. The payment status will then be set to
5232  |     READY_FOR_REPRINT.
5233  |
5234  |     Finally, this API will invoke the paper printing flow.
5235  |
5236  |     This method should only be invoked for reprinting payment documents
5237  |     that are prenumbered (paper stock type is 'prenumbered'). For
5238  |     reprinting payment documents that are on blank stock use the method
5239  |     reprint_blank_pmt_documents().
5240  |
5241  | PARAMETERS:
5242  |     IN
5243  |       p_instr_id      - ID of the payment instruction, for which some
5244  |                         payments need to be re-printed.
5245  |       p_pmt_doc_id    - The payment document id (check stock) which
5246  |                         is to be used for re-printing.
5247  |       p_pmt_list      - List of payments that are affected by the
5248  |                         re-print. These payments will be updated with
5249  |                         new paper document numbers (provided by the user).
5250  |       p_new_ppr_docs_list
5251  |                       - List of new paper document numbers to print
5252  |                         the provided payments on.
5253  |       p_old_ppr_docs_list
5254  |                       - List of previously used paper document numbers.
5255  |                         These will be inserted into IBY_USED_PAYMENT_DOCS
5256  |                         table indicating that they were spoiled.
5257  |       p_printer_name  - Printer to use for re-printing payments.
5258  |
5259  |
5260  |     OUT
5261  |       x_return_status - Result of the API call:
5262  |                         FND_API.G_RET_STS_SUCCESS indicates that the
5263  |                           reprint process was triggered successfully.
5264  |                           In this case the caller must COMMIT
5265  |                           the status change.
5266  |
5267  |                         FND_API.G_RET_STS_ERROR (or other) indicates
5268  |                           that API did not complete successfully.
5269  |                           In this case, the caller must issue a
5270  |                           ROLLBACK to undo all status changes.
5271  |
5272  | RETURNS:
5273  |
5274  | NOTES:
5275  |   Internal API, not for public use.
5276  |
5277  *---------------------------------------------------------------------*/
5278  PROCEDURE reprint_prenum_pmt_documents(
5279      p_instr_id          IN NUMBER,
5280      p_pmt_doc_id        IN NUMBER,
5281      p_pmt_list          IN pmtIDTab,
5282      p_new_ppr_docs_list IN pmtDocsTab,
5283      p_old_ppr_docs_list IN pmtDocsTab,
5284      p_printer_name      IN VARCHAR2,
5285      x_return_status     OUT NOCOPY VARCHAR2
5286      )
5287  IS
5288 
5289  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
5290                                          || '.reprint_prenum_pmt_documents';
5291 
5292  l_pkg_name    CONSTANT VARCHAR2(100) := 'AP_AWT_CALLOUT_PKG';
5293 
5294  l_callout_name     VARCHAR2(500);
5295  l_stmt             VARCHAR2(1000);
5296 
5297  /* used in invocation of callout procedure */
5298  l_api_version      CONSTANT NUMBER := 1.0;
5299  l_msg_count        NUMBER;
5300  l_msg_data         VARCHAR2(2000);
5301 
5302  l_curr_pmt_status  VARCHAR2(200);
5303  l_temp_status      VARCHAR2(200);
5304 
5305  l_last_list_num    NUMBER;
5306  l_last_doc_num     NUMBER;
5307 
5308  /*
5309   * Implementing the hook is optional for the calling app.
5310   * If the calling app does not implement the hook, then
5311   * the call to the hook will result in ORA-06576 error.
5312   *
5313   * There is no exception name associated with this code, so
5314   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
5315   * exception occurs, it is not fatal: we log the error and
5316   * proceed.
5317   *
5318   * If, on the other hand, the calling app implements the
5319   * hook, but the hook throws an exception, it is fatal
5320   * and we must abort the program (this will be caught
5321   * in WHEN OTHERS block).
5322   */
5323  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
5324  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
5325 
5326  BEGIN
5327 
5328      print_debuginfo(l_module_name, 'ENTER');
5329 
5330      FND_MSG_PUB.initialize;
5331 
5332      /*
5333       * STATUS CHANGE:
5334       *
5335       * UI Responsibility:
5336       * NONE
5337       *
5338       * API Responsibility:
5339       * paper document use reason = SPOILED
5340       * payment status = READY_TO_REPRINT
5341       */
5342 
5343      IF (p_pmt_list.COUNT          = 0  OR
5344          p_new_ppr_docs_list.COUNT = 0  OR
5345          p_old_ppr_docs_list.COUNT = 0) THEN
5346 
5347          print_debuginfo(l_module_name, 'Error: List of used paper '
5348              || 'document numbers/new paper document numbers/payment '
5349              || 'ids is empty'
5350              || '. Returning failure response .. '
5351              );
5352 
5353          x_return_status := FND_API.G_RET_STS_ERROR;
5354 
5355          print_debuginfo(l_module_name, 'EXIT');
5356 
5357          RETURN;
5358 
5359      END IF;
5360 
5361      IF (p_pmt_list.COUNT <> p_new_ppr_docs_list.COUNT  OR
5362          p_pmt_list.COUNT <> p_old_ppr_docs_list.COUNT) THEN
5363 
5364          print_debuginfo(l_module_name, 'Error: List of paper '
5365              || 'doc numbers must match list of payment ids. '
5366              || 'Returning failure response .. '
5367              );
5368 
5369          x_return_status := FND_API.G_RET_STS_ERROR;
5370 
5371          print_debuginfo(l_module_name, 'EXIT');
5372 
5373          RETURN;
5374 
5375      END IF;
5376 
5377      /*
5378       * STEP 0 .
5379       *
5380       * Setting the printer name supplied
5381       * while reprinting the payment
5382       * instruction
5383       *
5384       */
5385 
5386 	UPDATE iby_pay_instructions_all ins
5387 	SET ins.printer_name = p_printer_name
5388 	WHERE ins.payment_instruction_id = p_instr_id;
5389 
5390 
5391      print_debuginfo(l_module_name, 'Set printer name as '
5392          || p_printer_name
5393          || ' for payment instruction id  '
5394          || p_instr_id
5395          );
5396 
5397        /*A commit is necessary to avoid deadlock situations*/
5398        COMMIT;
5399 
5400      /*
5401       * STEP 1:
5402       *
5403       * Update the IBY_USED_PAYMENT_DOCS table with the list of
5404       * used paper document numbers. Since the user invokes this API
5405       * to reprint the paper documents, it follows that the earlier
5406       * used paper document was spoilt. Therefore, set the status of
5407       * the earlier used paper document to SPOILED.
5408       */
5409 
5410      FOR i IN p_old_ppr_docs_list.FIRST .. p_old_ppr_docs_list.LAST LOOP
5411 
5412          print_debuginfo(l_module_name, 'Updating paper doc number '
5413              || p_old_ppr_docs_list(i)
5414              || ' of payment document id '
5415              || p_pmt_doc_id
5416              || ' to spoiled status ..'
5417              );
5418 
5419          INSERT INTO IBY_USED_PAYMENT_DOCS (
5420              PAYMENT_DOCUMENT_ID,
5421              USED_DOCUMENT_NUMBER,
5422              DATE_USED,
5423              DOCUMENT_USE,
5424              CREATED_BY,
5425              CREATION_DATE,
5426              LAST_UPDATED_BY,
5427              LAST_UPDATE_DATE,
5428              LAST_UPDATE_LOGIN,
5429              OBJECT_VERSION_NUMBER
5430              )
5431          VALUES (
5432              p_pmt_doc_id,
5433              p_old_ppr_docs_list(i),
5434              sysdate,
5435              DOC_USE_SPOILED,
5436              fnd_global.user_id,
5437              sysdate,
5438              fnd_global.user_id,
5439              sysdate,
5440              fnd_global.login_id,
5441              1
5442              );
5443 
5444      END LOOP;
5445 
5446      /*
5447       * STEP 2:
5448       *
5449       * Update the IBY_PAYMENTS_ALL table with the list of
5450       * new paper document numbers. The payment ids and new
5451       * paper document numbers have been provided in matching
5452       * order. The status of the payment also needs to be
5453       * updated to READY_FOR_REPRINT.
5454       */
5455 
5456      FOR i IN p_new_ppr_docs_list.FIRST .. p_new_ppr_docs_list.LAST LOOP
5457 
5458          /*
5459           * Get the current status of the
5460           * payment into l_curr_pmt_status
5461           */
5462          SELECT
5463              pmt.payment_status
5464          INTO
5465              l_curr_pmt_status
5466          FROM
5467              IBY_PAYMENTS_ALL pmt
5468          WHERE
5469              payment_id = p_pmt_list(i)
5470          ;
5471 
5472          /*
5473           * For debug purposes.
5474           */
5475          IF (l_curr_pmt_status = PAY_STATUS_VOID_SETUP) THEN
5476 
5477              l_temp_status := PAY_STATUS_SETUP_REPRINT;
5478 
5479          ELSIF (l_curr_pmt_status = PAY_STATUS_VOID_OVERFLOW) THEN
5480 
5481              l_temp_status := PAY_STATUS_OVERFLOW_REPRINT;
5482 
5483          ELSE
5484 
5485              l_temp_status := PAY_STATUS_REPRINT;
5486 
5487          END IF;
5488 
5489          print_debuginfo(l_module_name, 'Updating status of payment id '
5490              || p_pmt_list(i)
5491              || ' from '
5492              || l_curr_pmt_status
5493              || ' to '
5494              || l_temp_status
5495              );
5496 
5497          /*
5498           * Set the payment status to READY_TO_REPRINT
5499           *
5500           * Void and overflow payments are identified by
5501           * their statuses, so we do not want to blindly
5502           * overwrite ther statuses. Instead, set their
5503           * status to special statuses that indicate the
5504           * payment is a setup / overflow payment and
5505           * it must be reprinted.
5506           */
5507          UPDATE
5508              IBY_PAYMENTS_ALL
5509          SET
5510              paper_document_number  = p_new_ppr_docs_list(i),
5511              payment_status         = DECODE(
5512                                           l_curr_pmt_status,
5513                                           PAY_STATUS_VOID_SETUP,
5514                                           PAY_STATUS_SETUP_REPRINT,
5515                                           PAY_STATUS_VOID_OVERFLOW,
5516                                           PAY_STATUS_OVERFLOW_REPRINT,
5517                                           PAY_STATUS_REPRINT
5518                                           )
5519          WHERE
5520              payment_id             = p_pmt_list(i) AND
5521              payment_instruction_id = p_instr_id
5522          ;
5523 
5524      END LOOP;
5525 
5526 
5527      /*
5528       * STEP 2A:
5529       *
5530       * Fix for bug 5470041:
5531       *
5532       * Update the last issued document number
5533       * in CE_PAYMENT_DOCUMENTS table using the
5534       * greatest document number from the user
5535       * provided list of new document numbers
5536       * for reprinting.
5537       */
5538 
5539      l_last_list_num := -1;
5540 
5541      FOR i IN p_new_ppr_docs_list.FIRST .. p_new_ppr_docs_list.LAST LOOP
5542 
5543          IF (p_new_ppr_docs_list(i) > l_last_list_num) THEN
5544 
5545              l_last_list_num := p_new_ppr_docs_list(i);
5546 
5547          END IF;
5548 
5549      END LOOP;
5550 
5551      print_debuginfo(l_module_name, 'Greatest paper document number '
5552          || 'derived from provided list: '
5553          || l_last_list_num
5554          );
5555 
5556      /*
5557       * This update uses an extra security check - we
5558       * only update the last issued doc number if the
5559       * provided list contains a doc number greater
5560       * than what is already stored in the database.
5561       */
5562      UPDATE
5563          CE_PAYMENT_DOCUMENTS
5564      SET
5565          last_issued_document_number =
5566              GREATEST(l_last_list_num, last_issued_document_number)
5567      WHERE
5568          payment_document_id         = p_pmt_doc_id
5569      RETURNING
5570          last_issued_document_number
5571      INTO
5572          l_last_doc_num
5573      ;
5574 
5575      print_debuginfo(l_module_name, 'Payment document id '
5576          || p_pmt_doc_id
5577          || ' updated with last issued doc number set to: '
5578          || l_last_doc_num
5579          );
5580 
5581      /*
5582       * STEP 3:
5583       *
5584       * Invoke the hook that handles witholding certificates.
5585       * Every time a paper document is PRINTED | REPRINTED |
5586       * SPOILED, the witholding certificates should be in sync.
5587       */
5588      l_callout_name := l_pkg_name || '.' || 'zx_witholdingCertificatesHook';
5589 
5590      print_debuginfo(l_module_name, 'Attempting to call hook: '
5591          || l_callout_name);
5592 
5593      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7, :8)';
5594 
5595      BEGIN
5596 
5597          EXECUTE IMMEDIATE
5598              (l_stmt)
5599          USING
5600              IN  p_instr_id,
5601              IN  'REPRINT',
5602              IN  l_api_version,
5603              IN  FND_API.G_FALSE,
5604              IN  FND_API.G_FALSE,
5605              OUT x_return_status,
5606              OUT l_msg_count,
5607              OUT l_msg_data
5608          ;
5609 
5610          /*
5611           * If the called procedure did not return success,
5612           * raise an exception.
5613           */
5614          IF (x_return_status IS NULL OR
5615              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
5616 
5617              print_debuginfo(l_module_name, 'Fatal: External app callout '''
5618                  || l_callout_name
5619                  || ''', returned failure status - '
5620                  || x_return_status
5621                  || '. Raising exception.'
5622                  );
5623 
5624              APP_EXCEPTION.RAISE_EXCEPTION;
5625 
5626          END IF;
5627 
5628      EXCEPTION
5629 
5630          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
5631              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
5632                  || '" not implemented by calling app - AP'
5633                  );
5634 
5635              print_debuginfo(l_module_name, 'Skipping hook call.');
5636 
5637 
5638          WHEN OTHERS THEN
5639              print_debuginfo(l_module_name, 'Fatal: External app callout '''
5640                  || l_callout_name
5641                  || ''', generated exception.'
5642                  );
5643 
5644              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
5645              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
5646              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
5647 
5648              /*
5649               * Propogate exception to caller.
5650               */
5651              RAISE;
5652      END;
5653 
5654 
5655 
5656      /*
5657       * STEP 4:
5658       *
5659       * Invoke the print routine to re-print these payments.
5660       */
5661      IBY_FD_POST_PICP_PROGS_PVT.
5662          Run_Post_PI_Programs(
5663              p_instr_id,
5664              'Y'
5665              );
5666 
5667      x_return_status := FND_API.G_RET_STS_SUCCESS;
5668 
5669      print_debuginfo(l_module_name, 'Returning success response ..');
5670 
5671      print_debuginfo(l_module_name, 'EXIT');
5672 
5673  EXCEPTION
5674      WHEN OTHERS THEN
5675 
5676      print_debuginfo(l_module_name, 'Exception occured when '
5677          || 'performing re-print for payment instruction '
5678          || p_instr_id
5679          );
5680 
5681      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
5682      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
5683      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
5684 
5685      x_return_status := FND_API.G_RET_STS_ERROR;
5686 
5687      print_debuginfo(l_module_name, 'EXIT');
5688 
5689  END reprint_prenum_pmt_documents;
5690 
5691 
5692 /*--------------------------------------------------------------------
5693  | NAME:
5694  |     reprint_blank_pmt_documents
5695  |
5696  |
5697  | PURPOSE:
5698  |     This API should be called if it is required to re-print some of the
5699  |     paper documents of a payment instruction. This API should only
5700  |     be called with the list of paper documents that were spoilt (not
5701  |     with the list of paper documents that were skipped, issued etc.).
5702  |
5703  |     The payment status will then be set to READY_FOR_REPRINT. No paper
5704  |     document number adjustment is required because the same paper
5705  |     document can be reused for bank paper stock. Only the status of the
5706  |     payment will be changed, the exiting paper document number on the
5707  |     payment will be untoched.
5708  |
5709  |     Finally, this API will invoke the paper printing flow.
5710  |
5711  |     This method should only be invoked for reprinting payment
5712  |     documents that are printed on blank paper stock (not for
5713  |     paper stock type that is 'prenumbered'). For reprinting
5714  |     payment documents that are on prenumbered stock use the method
5715  |     reprint_prenum_pmt_documents().
5716  |
5717  | PARAMETERS:
5718  |     IN
5719  |       p_instr_id      - ID of the payment instruction, for which some
5720  |                         payments need to be re-printed.
5721  |       p_pmt_list      - List of payments that are affected by the
5722  |                         re-print. The status of these payments will be
5723  |                         updated to indicate they are ready for reprint.
5724  |       p_printer_name  - Printer to use for re-printing payments.
5725  |
5726  |
5727  |     OUT
5728  |       x_return_status - Result of the API call:
5729  |                         FND_API.G_RET_STS_SUCCESS indicates that the
5730  |                           reprint process was triggered successfully.
5731  |                           In this case the caller must COMMIT
5732  |                           the status change.
5733  |
5734  |                         FND_API.G_RET_STS_ERROR (or other) indicates
5735  |                           that API did not complete successfully.
5736  |                           In this case, the caller must issue a
5737  |                           ROLLBACK to undo all status changes.
5738  |
5739  | RETURNS:
5740  |
5741  | NOTES:
5742  |   Internal API, not for public use.
5743  |
5744  *---------------------------------------------------------------------*/
5745  PROCEDURE reprint_blank_pmt_documents(
5746      p_instr_id          IN NUMBER,
5747      p_pmt_list          IN pmtIDTab,
5748      p_printer_name      IN VARCHAR2,
5749      x_return_status     OUT NOCOPY VARCHAR2
5750      )
5751  IS
5752 
5753  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
5754                                          || '.reprint_blank_pmt_documents';
5755 
5756  l_curr_pmt_status  VARCHAR2(200);
5757 
5758  BEGIN
5759 
5760      print_debuginfo(l_module_name, 'ENTER');
5761 
5762      FND_MSG_PUB.initialize;
5763 
5764      /*
5765       * STEP 0 .
5766       *
5767       * Setting the printer name supplied
5768       * while reprinting the payment
5769       * instruction
5770       *
5771       */
5772 
5773 	UPDATE iby_pay_instructions_all ins
5774 	SET ins.printer_name = p_printer_name
5775 	WHERE ins.payment_instruction_id = p_instr_id;
5776 
5777 
5778      print_debuginfo(l_module_name, 'Set printer name as '
5779          || p_printer_name
5780          || ' for payment instruction id  '
5781          || p_instr_id
5782          );
5783 
5784        /*A commit is necessary to avoid deadlock situations*/
5785        COMMIT;
5786 
5787      /*
5788       * STEP 1:
5789       *
5790       * Check whether any payments have been provided.
5791       */
5792      IF (p_pmt_list.COUNT = 0) THEN
5793 
5794          print_debuginfo(l_module_name, 'Error: List of payment ids '
5795              || 'is empty'
5796              || '. Returning failure response .. '
5797              );
5798 
5799          x_return_status := FND_API.G_RET_STS_ERROR;
5800 
5801          print_debuginfo(l_module_name, 'EXIT');
5802 
5803          RETURN;
5804 
5805      END IF;
5806 
5807      /*
5808       * STEP 2:
5809       *
5810       * Update the IBY_PAYMENTS_ALL table with the new status.
5811       * The status of the payment needs to be READY_FOR_REPRINT.
5812       */
5813      FOR i IN p_pmt_list.FIRST .. p_pmt_list.LAST LOOP
5814 
5815          /*
5816           * Get the current status of the
5817           * payment into l_curr_pmt_status
5818           */
5819          SELECT
5820              pmt.payment_status
5821          INTO
5822              l_curr_pmt_status
5823          FROM
5824              IBY_PAYMENTS_ALL pmt
5825          WHERE
5826              payment_id = p_pmt_list(i)
5827          ;
5828 
5829 
5830          /*
5831           * Set the payment status to READY_TO_REPRINT
5832           *
5833           * Void and overflow payments are identified by
5834           * their statuses, so we do not want to blindly
5835           * overwrite ther statuses. Instead, set their
5836           * status to special statuses that indicate the
5837           * payment is a setup / overflow payment and
5838           * it must be reprinted.
5839           */
5840          UPDATE
5841              IBY_PAYMENTS_ALL
5842          SET
5843              payment_status         = DECODE(
5844                                           l_curr_pmt_status,
5845                                           PAY_STATUS_VOID_SETUP,
5846                                           PAY_STATUS_SETUP_REPRINT,
5847                                           PAY_STATUS_VOID_OVERFLOW,
5848                                           PAY_STATUS_OVERFLOW_REPRINT,
5849                                           PAY_STATUS_REPRINT
5850                                           )
5851          WHERE
5852              payment_id             = p_pmt_list(i) AND
5853              payment_instruction_id = p_instr_id
5854          ;
5855 
5856      END LOOP;
5857 
5858 
5859      /*
5860       * STEP 3:
5861       *
5862       * Invoke the print routine to re-print these payments.
5863       */
5864      IBY_FD_POST_PICP_PROGS_PVT.
5865          Run_Post_PI_Programs(
5866              p_instr_id,
5867              'Y'
5868              );
5869 
5870      x_return_status := FND_API.G_RET_STS_SUCCESS;
5871 
5872      print_debuginfo(l_module_name, 'Returning success response ..');
5873 
5874      print_debuginfo(l_module_name, 'EXIT');
5875 
5876  EXCEPTION
5877      WHEN OTHERS THEN
5878 
5879      print_debuginfo(l_module_name, 'Exception occured when '
5880          || 'performing re-print for payment instruction '
5881          || p_instr_id
5882          );
5883 
5884      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
5885      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
5886      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
5887 
5888      x_return_status := FND_API.G_RET_STS_ERROR;
5889 
5890      print_debuginfo(l_module_name, 'EXIT');
5891 
5892  END reprint_blank_pmt_documents;
5893 
5894 /*--------------------------------------------------------------------
5895  | NAME:
5896  |     reprint_payment_instruction
5897  |
5898  | PURPOSE:
5899  |     Reprints all the payment documents associated with a payment
5900  |     instruction.
5901  |
5902  |     Note that in this case, no renumbering of the paper documents
5903  |     is required. This API is equivalent to making a fresh print call
5904  |     for a payment instruction (only requirement is that the payments of
5905  |     the payment instruction be numbered). We simply send the payment
5906  |     instruction for printing with the existing payment document numbers.
5907  |
5908  |     Do not call this API if printing for the payment instruction has
5909  |     already been attempted earlier.
5910  |
5911  | PARAMETERS:
5912  |     IN
5913  |
5914  |
5915  |     OUT
5916  |
5917  |
5918  | RETURNS:
5919  |
5920  | NOTES:
5921  |   Internal API, not for public use.
5922  |
5923  |   This procedure performs a COMMIT.
5924  |
5925  *---------------------------------------------------------------------*/
5926  PROCEDURE reprint_payment_instruction (
5927      p_instr_id          IN NUMBER,
5928      p_printer_name      IN VARCHAR2,
5929      x_return_status     OUT NOCOPY VARCHAR2
5930      )
5931  IS
5932 
5933  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
5934                                          || '.reprint_payment_instruction';
5935 
5936  BEGIN
5937 
5938      print_debuginfo(l_module_name, 'ENTER');
5939 
5940      FND_MSG_PUB.initialize;
5941 
5942      /*
5943       * STEP 1:
5944       *
5945       * Update the status of the payments of the given
5946       * instruction to indicate that they must be reprinted.
5947       */
5948      print_debuginfo(l_module_name, 'Updating statuses of the '
5949          || 'payments of payment instruction '
5950          || p_instr_id
5951          || ' to formatted ..'
5952          );
5953 
5954      UPDATE
5955          IBY_PAYMENTS_ALL
5956      SET
5957          payment_status = PAY_STATUS_FORMATTED
5958      WHERE
5959          payment_instruction_id = p_instr_id
5960      ;
5961 
5962      /*
5963       * STEP 2:
5964       *
5965       * Update the status of the payment instruction
5966       * to indicate that it must be re-printed.
5967       */
5968      print_debuginfo(l_module_name, 'Updating status of '
5969          || 'payment instruction '
5970          || p_instr_id
5971          || ' to formatted - ready for printing ..'
5972          );
5973      UPDATE
5974          IBY_PAY_INSTRUCTIONS_ALL
5975      SET
5976          payment_instruction_status = INS_STATUS_FORMAT_TO_PRINT
5977      WHERE
5978          payment_instruction_id = p_instr_id
5979      ;
5980 
5981      /*
5982       * This commit is necessary. Otherwise a deadlocked
5983       * condition is created when we try to update the same
5984       * payment instruction with the concurrent request id
5985       * (for handling intermediate statuses).
5986       */
5987      COMMIT;
5988 
5989 
5990      /*
5991       * STEP 3:
5992       *
5993       * Invoke the print routine to re-print these payments.
5994       */
5995 
5996      /*
5997       * Note that reprint flag is 'N' in this case;
5998       * this is to treat the re-print as a fresh print.
5999       */
6000      IBY_FD_POST_PICP_PROGS_PVT.
6001          Run_Post_PI_Programs(
6002              p_instr_id,
6003              'N'
6004              );
6005 
6006      x_return_status := FND_API.G_RET_STS_SUCCESS;
6007 
6008      print_debuginfo(l_module_name, 'Returning success response ..');
6009 
6010      print_debuginfo(l_module_name, 'EXIT');
6011 
6012  EXCEPTION
6013      WHEN OTHERS THEN
6014 
6015      print_debuginfo(l_module_name, 'Exception occured when '
6016          || 'performing re-print for payment instruction '
6017          || p_instr_id
6018          );
6019 
6020      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
6021      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
6022      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
6023 
6024      x_return_status := FND_API.G_RET_STS_ERROR;
6025 
6026      print_debuginfo(l_module_name, 'EXIT');
6027 
6028  END reprint_payment_instruction;
6029 
6030 
6031 /*--------------------------------------------------------------------
6032  | NAME:
6033  |     finalize_print_status
6034  |
6035  |
6036  | PURPOSE:
6037  |     Records the final print status for a set of paper documents.
6038  |
6039  |     This is an overloaded method. See the other method signature
6040  |     for complete documentation.
6041  |
6042  | PARAMETERS:
6043  |     IN
6044  |
6045  |
6046  |     OUT
6047  |
6048  |
6049  | RETURNS:
6050  |
6051  | NOTES:
6052  |   Internal API, not for public use.
6053  |
6054  *---------------------------------------------------------------------*/
6055  PROCEDURE finalize_print_status(
6056      p_instr_id         IN NUMBER,
6057      p_pmt_doc_id       IN NUMBER,
6058      p_used_docs_list   IN paperDocNumTab,
6059      x_return_status    OUT NOCOPY VARCHAR2
6060      )
6061  IS
6062  BEGIN
6063 
6064      finalize_print_status(
6065          p_instr_id,
6066          p_pmt_doc_id,
6067          p_used_docs_list,
6068          FALSE,
6069          x_return_status
6070          );
6071 
6072  END finalize_print_status;
6073 
6074 /*--------------------------------------------------------------------
6075  | NAME:
6076  |     finalize_print_status
6077  |
6078  |
6079  | PURPOSE:
6080  |     Records the final print status for a set of paper documents.
6081  |
6082  |     This is an overloaded method. See the other method signature
6083  |     for complete documentation.
6084  |
6085  | PARAMETERS:
6086  |     IN
6087  |
6088  |
6089  |     OUT
6090  |
6091  |
6092  | RETURNS:
6093  |
6094  | NOTES:
6095  |   Internal API, not for public use.
6096  |
6097  *---------------------------------------------------------------------*/
6098  PROCEDURE finalize_print_status(
6099      p_instr_id         IN NUMBER,
6100      p_pmt_doc_id       IN NUMBER,
6101      p_used_docs_list   IN paperDocNumTab,
6102      p_used_pmts_list   IN paperDocNumTab,
6103      x_return_status    OUT NOCOPY VARCHAR2
6104      )
6105  IS
6106  BEGIN
6107 
6108      finalize_print_status(
6109          p_instr_id,
6110          p_pmt_doc_id,
6111          p_used_docs_list,
6112          p_used_pmts_list,
6113          FALSE,
6114          x_return_status
6115          );
6116 
6117  END finalize_print_status;
6118 
6119 /*--------------------------------------------------------------------
6120  | NAME:
6121  |     finalize_print_status
6122  |
6123  | PURPOSE:
6124  |     Records the final print status for a set of paper documents. This
6125  |     API will insert the given set of paper document numbers into the
6126  |     IBY_USED_PAYMENT_DOCS table along with the usage reason indicating
6127  |     whether the paper document was spoiled.
6128  |
6129  |     Note that this API should only be invoked with the list of spoiled
6130  |     paper documents. The UI should directly handle the successfully
6131  |     printed paper documents. For performance reasons, this API is
6132  |     designed only to handle the spoiled paper document case.
6133  |
6134  |     This API will set the usage reason for each provided document
6135  |     to 'SPOILED' in the IBY_USED_PAYMENT_DOCS table, and it will also
6136  |     set the status of the corresponding payment to
6137  |     REMOVED_DOCUMENT_SPOILED.
6138  |
6139  |     Then, this API will set the status of the successfully printed
6140  |     payments to ISSUED status and then invoke the 'mark complete'
6141  |     API to mark the payments of this payment instruction as complete.
6142  |
6143  | PARAMETERS:
6144  |     IN
6145  |       p_pmt_doc_id      - The payment document id (check stock id)
6146  |                           of the given list of paper documents.
6147  |       p_used_docs_list  - The list of paper documents that have been
6148  |                           used for printing
6149  |       p_use_reason_list - The list of paper document usage reasons. This
6150  |                           list will contain a lookup code that specifies
6151  |                           whether the paper document was correctly
6152  |                           printed or not. Possible values include
6153  |                           ISSUED | SPOILED. SKIPPED will never be a
6154  |                           provided reason because skipped documents have
6155  |                           successfully printed (only numbering is wrong).
6156  |       p_submit_postive_pay
6157  |                         - Flag indicating whether positive pay file
6158  |                           report needs to be launched after finalizing
6159  |                           the payments.
6160  |
6161  |     OUT
6162  |       x_return_status   - Result of the API call:
6163  |                           FND_API.G_RET_STS_SUCCESS indicates that the
6164  |                           finalization process completed raised
6165  |                           successfully. In this case the caller must
6166  |                           COMMIT the status change.
6167  |
6168  |                           FND_API.G_RET_STS_ERROR (or other) indicates
6169  |                           that API did not complete successfully.
6170  |                           In this case, the caller must issue a
6171  |                           ROLLBACK to undo all status changes.
6172  |
6173  | RETURNS:
6174  |
6175  | NOTES:
6176  |   Internal API, not for public use.
6177  |
6178  *---------------------------------------------------------------------*/
6179  PROCEDURE finalize_print_status(
6180      p_instr_id           IN NUMBER,
6181      p_pmt_doc_id         IN NUMBER,
6182      p_used_docs_list     IN paperDocNumTab,
6183      p_submit_postive_pay IN BOOLEAN,
6184      x_return_status      OUT NOCOPY VARCHAR2
6185      )
6186  IS
6187 
6188  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
6189                                          || '.finalize_print_status';
6190 
6191  l_paper_doc_num  IBY_PAYMENTS_ALL.paper_document_number%TYPE;
6192 
6193  /* used in invocation of callout procedure */
6194  l_api_version    CONSTANT NUMBER := 1.0;
6195  l_msg_count      NUMBER;
6196  l_msg_data       VARCHAR2(2000);
6197 
6198  l_pkg_name       CONSTANT VARCHAR2(100) := 'AP_AWT_CALLOUT_PKG';
6199 
6200  l_callout_name   VARCHAR2(500);
6201  l_stmt           VARCHAR2(1000);
6202 
6203  /* Bug #6508530 -used for changing status for spoiled payment, document */
6204  l_doc_id_list    docPayIDTab;
6205  l_doc_status_list  docPayStatusTab;
6206 
6207  x_return_status_remove_doc    VARCHAR2(200);
6208 
6209  CURSOR c_docs (p_pmt_id IBY_PAYMENTS_ALL.
6210                                 payment_id%TYPE)
6211  IS
6212  SELECT
6213      doc.document_payable_id,
6214      doc.document_status
6215  FROM
6216      IBY_DOCS_PAYABLE_ALL doc
6217  WHERE
6218      doc.payment_id = p_pmt_id
6219 
6220  ;
6221 
6222 
6223  /*
6224   * Implementing the hook is optional for the calling app.
6225   * If the calling app does not implement the hook, then
6226   * the call to the hook will result in ORA-06576 error.
6227   *
6228   * There is no exception name associated with this code, so
6229   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
6230   * exception occurs, it is not fatal: we log the error and
6231   * proceed.
6232   *
6233   * If, on the other hand, the calling app implements the
6234   * hook, but the hook throws an exception, it is fatal
6235   * and we must abort the program (this will be caught
6236   * in WHEN OTHERS block).
6237   */
6238  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
6239  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
6240 
6241  BEGIN
6242 
6243      print_debuginfo(l_module_name, 'ENTER');
6244 
6245      FND_MSG_PUB.initialize;
6246 
6247      /*
6248       * STATUS CHANGE:
6249       *
6250       * UI Responsibility:
6251       * NONE
6252       *
6253       * API Responsibility:
6254       * payment instruction status = PRINTED
6255       *
6256       * payment status = REMOVED_DOCUMENT_SPOILED (for spoiled payments)
6257       * payment status = ISSUED (for successful payments)
6258       */
6259 
6260      IF (p_used_docs_list.COUNT = 0) THEN
6261 
6262          print_debuginfo(l_module_name, 'Error: List of used paper '
6263              || 'document numbers is empty'
6264              || '. Returning failure response .. '
6265              );
6266 
6267          x_return_status := FND_API.G_RET_STS_ERROR;
6268 
6269          print_debuginfo(l_module_name, 'EXIT');
6270 
6271          RETURN;
6272 
6273      END IF;
6274 
6275      /*
6276       * STEP 1:
6277       *
6278       * Start processing the used paper documents, one-by-one.
6279       *
6280       * This API will only be called with the list of spoiled
6281       * paper documents, so we can set the usage reason for
6282       * each paper document to 'spoiled'.
6283       */
6284      FOR i IN p_used_docs_list.FIRST .. p_used_docs_list.LAST LOOP
6285 
6286          INSERT INTO IBY_USED_PAYMENT_DOCS (
6287              PAYMENT_DOCUMENT_ID,
6288              USED_DOCUMENT_NUMBER,
6289              DATE_USED,
6290              DOCUMENT_USE,
6291              CREATED_BY,
6292              CREATION_DATE,
6293              LAST_UPDATED_BY,
6294              LAST_UPDATE_DATE,
6295              LAST_UPDATE_LOGIN,
6296              OBJECT_VERSION_NUMBER
6297              )
6298          VALUES (
6299              p_pmt_doc_id,
6300              p_used_docs_list(i),
6301              sysdate,
6302              DOC_USE_SPOILED,
6303              fnd_global.user_id,
6304              sysdate,
6305              fnd_global.user_id,
6306              sysdate,
6307              fnd_global.login_id,
6308              1
6309              );
6310 
6311      END LOOP;
6312 
6313      print_debuginfo(l_module_name, 'Finished updating document use table.');
6314 
6315      /*
6316       * STEP 2:
6317       *
6318       * Pick up all payments for this payment instruction
6319       * that have the given paper document number one-by-one.
6320       *
6321       * For each such payment, set the payment status to 'SPOILED'.
6322       */
6323      BEGIN
6324 
6325          FOR i IN p_used_docs_list.FIRST .. p_used_docs_list.LAST LOOP
6326 
6327              l_paper_doc_num := p_used_docs_list(i);
6328 	      print_debuginfo(l_module_name, 'In the loop, p_used_docs_list('||
6329 i||') :'
6330 || p_used_docs_list(i) );
6331 
6332              UPDATE
6333                  IBY_PAYMENTS_ALL
6334              SET
6335                  payment_status = PAY_STATUS_SPOILED
6336              WHERE
6337                  payment_instruction_id = p_instr_id          AND
6338                  payment_id   = p_used_docs_list(i)
6339              ;
6340 
6341 
6342             print_debuginfo(l_module_name, 'Finished updating payments table');
6343              UPDATE
6344 	         IBY_DOCS_PAYABLE_ALL
6345              SET
6346                  document_status = DOC_STATUS_PMT_SPOILED
6347              WHERE
6348                   payment_id = p_used_docs_list(i)
6349              ;
6350 
6351 	      print_debuginfo(l_module_name, 'Finished updating document payable table');
6352 
6353             OPEN  c_docs(p_used_docs_list(i));
6354             FETCH c_docs BULK COLLECT INTO l_doc_id_list, l_doc_status_list;
6355             CLOSE c_docs;
6356 
6357            print_debuginfo(l_module_name, 'The number of doc ids for this '
6358                                           ||'payment' ||l_doc_id_list.COUNT);
6359 
6360 	   remove_documents_payable (
6361                      l_doc_id_list,
6362 		     l_doc_status_list,
6363 		     x_return_status_remove_doc
6364 		     );
6365 print_debuginfo(l_module_name,'Inside loop,after callling'
6366 || 'remove_documents_payable');
6367 
6368 
6369 	    IF (x_return_status_remove_doc <> FND_API.G_RET_STS_SUCCESS) THEN
6370 
6371 		     /*
6372   		      * Even if a single call to remove a document
6373      		      * failed, return failure for the entire
6374      		      * API request.
6375   		      */
6376 		     print_debuginfo(l_module_name, 'Removing of documents '
6377 			 || 'for payment instruction id '
6378 			 || p_instr_id
6379 			 || ' failed.'
6380 			 );
6381 
6382 		     print_debuginfo(l_module_name, 'EXIT');
6383 
6384 		     /*
6385   		      * It is the callers responsibility to rollback
6386        		      * all the changes.
6387        		      */
6388 		     RETURN;
6389 
6390 	    END IF;
6391 
6392         END LOOP;
6393 
6394      EXCEPTION
6395          WHEN OTHERS THEN
6396              print_debuginfo(l_module_name, 'Fatal: Exception occured '
6397                  || 'when attempting to update payment with payment '
6398                  || 'instruction id '
6399                  || p_instr_id
6400                  || ' and paper document number '
6401                  || l_paper_doc_num
6402                  );
6403 
6404              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
6405              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
6406              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
6407 
6408              /*
6409               * Propogate exception to caller.
6410               */
6411              RAISE;
6412 
6413      END;
6414 
6415      print_debuginfo(l_module_name, 'Finished updating payments table.');
6416 
6417      /*
6418       * STEP 3:
6419       *
6420       * Invoke the hook that handles witholding certificates.
6421       * Every time a paper document is PRINTED | REPRINTED |
6422       * SPOILED, the witholding certificates should be in sync.
6423       */
6424      l_callout_name := l_pkg_name || '.' || 'zx_witholdingCertificatesHook';
6425 
6426      print_debuginfo(l_module_name, 'Attempting to call hook: '
6427          || l_callout_name);
6428 
6429      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7, :8)';
6430 
6431      BEGIN
6432 
6433          EXECUTE IMMEDIATE
6434              (l_stmt)
6435          USING
6436              IN  p_instr_id,
6437              IN  'SPOILED',
6438              IN  l_api_version,
6439              IN  FND_API.G_FALSE,
6440              IN  FND_API.G_FALSE,
6441              OUT x_return_status,
6442              OUT l_msg_count,
6443              OUT l_msg_data
6444          ;
6445 
6446          /*
6447           * If the called procedure did not return success,
6448           * raise an exception.
6449           */
6450          IF (x_return_status IS NULL OR
6451              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
6452 
6453              print_debuginfo(l_module_name, 'Fatal: External app callout '''
6454                  || l_callout_name
6455                  || ''', returned failure status - '
6456                  || x_return_status
6457                  || '. Raising exception.'
6458                  );
6459 
6460              APP_EXCEPTION.RAISE_EXCEPTION;
6461 
6462          END IF;
6463 
6464      EXCEPTION
6465 
6466          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
6467              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
6468                  || '" not implemented by calling app - AP'
6469                  );
6470 
6471              print_debuginfo(l_module_name, 'Skipping hook call.');
6472 
6473 
6474          WHEN OTHERS THEN
6475              print_debuginfo(l_module_name, 'Fatal: External app callout '''
6476                  || l_callout_name
6477                  || ''', generated exception.'
6478                  );
6479 
6480              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
6481              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
6482              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
6483 
6484              /*
6485               * Propogate exception to caller.
6486               */
6487              RAISE;
6488      END;
6489 
6490      /*
6491       * STEP 4:
6492       *
6493       * Change the status of the successful payments of this instruction
6494       * to ISSUED status. The ISSUED status is the final status for a
6495       * paper payment; the payment must be in ISSUED status in order to
6496       * be marked complete.
6497       */
6498      UPDATE
6499          IBY_PAYMENTS_ALL
6500      SET
6501          payment_status = PAY_STATUS_ISSUED
6502      WHERE
6503          payment_instruction_id = p_instr_id     AND
6504          (
6505              payment_status IN
6506              (
6507              PAY_STATUS_FORMATTED,
6508              PAY_STATUS_SUB_FOR_PRINT
6509              )
6510              OR
6511              (
6512              process_type = PROCESS_TYPE_IMMEDIATE
6513              )
6514          )
6515      ;
6516 
6517      /*
6518       * STEP 5:
6519       *
6520       * Mark all the payments of the given payment instruction
6521       * as complete.
6522       */
6523      print_debuginfo(l_module_name, 'Attempting to mark payments of '
6524          || 'payment instruction '
6525          || p_instr_id
6526          || ' as complete.'
6527          );
6528 
6529      mark_all_pmts_complete (
6530          p_instr_id,
6531          p_submit_postive_pay,
6532          x_return_status
6533          );
6534 
6535      IF (x_return_status IS NULL OR
6536          x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
6537 
6538          print_debuginfo(l_module_name, 'Error status '
6539              || x_return_status
6540              || ' was received from the mark_all_pmts_complete() '
6541              || 'method. Raising exception.'
6542              );
6543 
6544          APP_EXCEPTION.RAISE_EXCEPTION;
6545 
6546      ELSE
6547 
6548          print_debuginfo(l_module_name, 'Successfully maked payments '
6549              || 'as complete.'
6550              );
6551 
6552      END IF;
6553 
6554      /*
6555       * STEP 6:
6556       *
6557       * Change the status of the payment instruction to PRINTED.
6558       */
6559      UPDATE
6560          IBY_PAY_INSTRUCTIONS_ALL
6561      SET
6562          payment_instruction_status = INS_STATUS_PRINTED
6563      WHERE
6564          payment_instruction_id = p_instr_id
6565      ;
6566 
6567      print_debuginfo(l_module_name, 'Successfully set payment '
6568          || 'instruction status to PRINTED.'
6569          );
6570 
6571      x_return_status := FND_API.G_RET_STS_SUCCESS;
6572 
6573      print_debuginfo(l_module_name, 'Returning success response ..');
6574 
6575      print_debuginfo(l_module_name, 'EXIT');
6576 
6577  EXCEPTION
6578      WHEN OTHERS THEN
6579 
6580      print_debuginfo(l_module_name, 'Exception occured when '
6581          || 'recording final print status for payment instruction '
6582          || p_instr_id
6583          );
6584 
6585      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
6586      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
6587      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
6588 
6589      x_return_status := FND_API.G_RET_STS_ERROR;
6590 
6591      print_debuginfo(l_module_name, 'EXIT');
6592 
6593  END finalize_print_status;
6594 
6595 
6596 /*--------------------------------------------------------------------
6597  | NAME:
6598  |     finalize_print_status
6599  |
6600  | PURPOSE:
6601  |     Records the final print status for a set of paper documents. This
6602  |     API will insert the given set of paper document numbers into the
6603  |     IBY_USED_PAYMENT_DOCS table along with the usage reason indicating
6604  |     whether the paper document was spoiled.
6605  |
6606  |     Note that this API should only be invoked with the list of spoiled
6607  |     paper documents. The UI should directly handle the successfully
6608  |     printed paper documents. For performance reasons, this API is
6609  |     designed only to handle the spoiled paper document case.
6610  |
6611  |     This API will set the usage reason for each provided document
6612  |     to 'SPOILED' in the IBY_USED_PAYMENT_DOCS table, and it will also
6613  |     set the status of the corresponding payment to
6614  |     REMOVED_DOCUMENT_SPOILED.
6615  |
6616  |     Then, this API will set the status of the successfully printed
6617  |     payments to ISSUED status and then invoke the 'mark complete'
6618  |     API to mark the payments of this payment instruction as complete.
6619  |
6620  | PARAMETERS:
6621  |     IN
6622  |       p_pmt_doc_id      - The payment document id (check stock id)
6623  |                           of the given list of paper documents.
6624  |       p_used_docs_list  - The list of paper documents that have been
6625  |                           used for printing
6626  |       p_use_reason_list - The list of paper document usage reasons. This
6627  |                           list will contain a lookup code that specifies
6628  |                           whether the paper document was correctly
6629  |                           printed or not. Possible values include
6630  |                           ISSUED | SPOILED. SKIPPED will never be a
6631  |                           provided reason because skipped documents have
6632  |                           successfully printed (only numbering is wrong).
6633  |       p_submit_postive_pay
6634  |                         - Flag indicating whether positive pay file
6635  |                           report needs to be launched after finalizing
6636  |                           the payments.
6637  |
6638  |     OUT
6639  |       x_return_status   - Result of the API call:
6640  |                           FND_API.G_RET_STS_SUCCESS indicates that the
6641  |                           finalization process completed raised
6642  |                           successfully. In this case the caller must
6643  |                           COMMIT the status change.
6644  |
6645  |                           FND_API.G_RET_STS_ERROR (or other) indicates
6646  |                           that API did not complete successfully.
6647  |                           In this case, the caller must issue a
6648  |                           ROLLBACK to undo all status changes.
6649  |
6650  | RETURNS:
6651  |
6652  | NOTES:
6653  |   Internal API, not for public use.
6654  |
6655  *---------------------------------------------------------------------*/
6656  PROCEDURE finalize_print_status(
6657      p_instr_id           IN NUMBER,
6658      p_pmt_doc_id         IN NUMBER,
6659      p_used_docs_list     IN paperDocNumTab,
6660      p_used_pmts_list     IN paperDocNumTab,
6661      p_submit_postive_pay IN BOOLEAN,
6662      x_return_status      OUT NOCOPY VARCHAR2
6663      )
6664  IS
6665 
6666  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
6667                                          || '.finalize_print_status';
6668 
6669 
6670  l_paper_doc_num IBY_PAYMENTS_ALL.paper_document_number%TYPE;
6671  l_payment_status_list  docPayStatusTab;
6672  l_skipped_document_number IBY_PAYMENTS_ALL.paper_document_number%TYPE;
6673 
6674  /* used in invocation of callout procedure */
6675  l_api_version    CONSTANT NUMBER := 1.0;
6676  l_msg_count      NUMBER;
6677  l_first_doc_number      NUMBER;
6678  l_last_doc_number      NUMBER;
6679  l_msg_data       VARCHAR2(2000);
6680  l_pkg_name       CONSTANT VARCHAR2(100) := 'AP_AWT_CALLOUT_PKG';
6681  l_callout_name   VARCHAR2(500);
6682  l_stmt           VARCHAR2(1000);
6683 
6684  /* Bug #6508530 -used for changing status for spoiled payment, document */
6685  l_doc_id_list    docPayIDTab;
6686  l_doc_status_list  docPayStatusTab;
6687 
6688  x_return_status_remove_doc    VARCHAR2(200);
6689 
6690  CURSOR c_docs (p_pmt_id IBY_PAYMENTS_ALL.
6691                                 payment_id%TYPE)
6692  IS
6693  SELECT
6694      doc.document_payable_id,
6695      doc.document_status
6696  FROM
6697      IBY_DOCS_PAYABLE_ALL doc
6698  WHERE
6699      doc.payment_id = p_pmt_id
6700 
6701  ;
6702 
6703 
6704  /*
6705   * Implementing the hook is optional for the calling app.
6706   * If the calling app does not implement the hook, then
6707   * the call to the hook will result in ORA-06576 error.
6708   *
6709   * There is no exception name associated with this code, so
6710   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
6711   * exception occurs, it is not fatal: we log the error and
6712   * proceed.
6713   *
6714   * If, on the other hand, the calling app implements the
6715   * hook, but the hook throws an exception, it is fatal
6716   * and we must abort the program (this will be caught
6717   * in WHEN OTHERS block).
6718   */
6719  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
6720  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
6721 
6722  BEGIN
6723 
6724      print_debuginfo(l_module_name, 'ENTER');
6725 
6726      FND_MSG_PUB.initialize;
6727 
6728      /*
6729       * STATUS CHANGE:
6730       *
6731       * UI Responsibility:
6732       * NONE
6733       *
6734       * API Responsibility:
6735       * payment instruction status = PRINTED
6736       *
6737       * payment status = REMOVED_DOCUMENT_SPOILED (for spoiled payments)
6738       * payment status = ISSUED (for successful payments)
6739       */
6740 
6741      IF (p_used_docs_list.COUNT = 0) THEN
6742 
6743          print_debuginfo(l_module_name, 'Error: List of used paper '
6744              || 'document numbers is empty'
6745              || '. Returning failure response .. '
6746              );
6747 
6748          x_return_status := FND_API.G_RET_STS_ERROR;
6749 
6750          print_debuginfo(l_module_name, 'EXIT');
6751 
6752          RETURN;
6753 
6754      END IF;
6755 
6756      /*
6757       * STEP 1:
6758       *
6759       * Start processing the used paper documents, one-by-one.
6760       *
6761       * This API will only be called with the list of spoiled
6762       * paper documents, so we can set the usage reason for
6763       * each paper document to 'spoiled'.
6764       */
6765 
6766       -- looping through the complete document list
6767      FOR i IN p_used_docs_list.FIRST .. p_used_docs_list.LAST LOOP
6768 
6769 	 -- fetching the payment status for the documents and storing them in an array
6770 	 SELECT payment_status
6771 	 INTO l_payment_status_list(i)
6772 	 FROM IBY_PAYMENTS_ALL
6773 	 WHERE paper_document_number = p_used_docs_list(i)
6774 	 AND payment_id = p_used_pmts_list(i)
6775 	 AND payment_instruction_id = p_instr_id;
6776 
6777          print_debuginfo(l_module_name, 'Paper Document Number = ' || p_used_docs_list(i));
6778          print_debuginfo(l_module_name, 'Payment ID : Payment Status = ' || p_used_pmts_list(i) || ':' || l_payment_status_list(i));
6779 
6780 	 BEGIN
6781 
6782 		-- checking if the document is already skipped earlier
6783 		SELECT cedocs.used_document_number
6784    	        INTO  l_skipped_document_number
6785 		FROM iby_used_payment_docs cedocs
6786 		WHERE cedocs.payment_document_id = p_pmt_doc_id
6787 		 AND cedocs.used_document_number = p_used_docs_list(i)
6788 		 AND cedocs.document_use = 'SKIPPED';
6789 
6790 	 EXCEPTION
6791 	 WHEN NO_DATA_FOUND THEN
6792 
6793 		 --if the document is not skipped earlier insert new
6794 		 INSERT INTO IBY_USED_PAYMENT_DOCS (
6795 		     PAYMENT_DOCUMENT_ID,
6796 		     USED_DOCUMENT_NUMBER,
6797 		     DATE_USED,
6798 		     DOCUMENT_USE,
6799 		     CREATED_BY,
6800 		     CREATION_DATE,
6801 		     LAST_UPDATED_BY,
6802 		     LAST_UPDATE_DATE,
6803 		     LAST_UPDATE_LOGIN,
6804 		     OBJECT_VERSION_NUMBER
6805 		     )
6806 		 VALUES (
6807 		     p_pmt_doc_id,
6808 		     p_used_docs_list(i),
6809 		     sysdate,
6810 		     decode(l_payment_status_list(i),'REMOVED_DOCUMENT_SPOILED','SPOILED','ISSUED'),
6811 		     fnd_global.user_id,
6812 		     sysdate,
6813 		     fnd_global.user_id,
6814 		     sysdate,
6815 		     fnd_global.login_id,
6816 		     1
6817 		     );
6818 
6819                  print_debuginfo(l_module_name, 'Document number not found, inserting new');
6820 	 END;
6821 
6822          -- updating the document_use in any case
6823 	 UPDATE IBY_USED_PAYMENT_DOCS
6824 	 SET DOCUMENT_USE = decode(l_payment_status_list(i),'REMOVED_DOCUMENT_SPOILED','SPOILED','ISSUED')
6825 	 WHERE payment_document_id = p_pmt_doc_id
6826 	 AND used_document_number = p_used_docs_list(i);
6827 
6828 	 print_debuginfo(l_module_name, 'Found skipped document number, updating document usage');
6829 
6830      END LOOP;
6831 
6832      print_debuginfo(l_module_name, 'Finished updating document use table.');
6833 
6834      /*
6835       * STEP 1.5:
6836       *
6837       * Managing skipped documents
6838       * Finding out which of the documents are skipped
6839       *
6840       */
6841 
6842       l_first_doc_number := p_used_docs_list(p_used_docs_list.FIRST);
6843       l_last_doc_number := p_used_docs_list(p_used_docs_list.LAST);
6844 
6845      print_debuginfo(l_module_name, 'l_first_doc_number : ' || l_first_doc_number);
6846      print_debuginfo(l_module_name, 'l_last_doc_number : ' || l_last_doc_number);
6847 
6848      -- we will loop through the complete document list and find out the missing numbers
6849      FOR i IN l_first_doc_number .. l_last_doc_number LOOP
6850          l_skipped_document_number:=1;
6851 
6852 	    -- finding out the missing number in the sequence
6853             print_debuginfo(l_module_name, 'finding if skipped  ' || i);
6854             FOR j IN p_used_docs_list.FIRST .. p_used_docs_list.LAST LOOP
6855 	     IF (p_used_docs_list(j)=i) THEN
6856 	       l_skipped_document_number:=0;
6857 	     END IF;
6858 	    END LOOP;
6859 
6860        -- if a number is missing in the sequence
6861        IF (l_skipped_document_number=1) THEN
6862          BEGIN
6863 
6864                 -- check if it already exists in the used_documents_table
6865 		SELECT cedocs.used_document_number
6866    	        INTO  l_skipped_document_number
6867 		FROM iby_used_payment_docs cedocs
6868 		WHERE cedocs.payment_document_id = p_pmt_doc_id
6869 		 AND cedocs.used_document_number = i;
6870 
6871 	 EXCEPTION
6872 	 WHEN NO_DATA_FOUND THEN
6873 
6874                  -- inserting the document as skipped
6875                  print_debuginfo(l_module_name, 'inserting as skipped  ' || i);
6876 		 INSERT INTO IBY_USED_PAYMENT_DOCS (
6877 		     PAYMENT_DOCUMENT_ID,
6878 		     USED_DOCUMENT_NUMBER,
6879 		     DATE_USED,
6880 		     DOCUMENT_USE,
6881 		     CREATED_BY,
6882 		     CREATION_DATE,
6883 		     LAST_UPDATED_BY,
6884 		     LAST_UPDATE_DATE,
6885 		     LAST_UPDATE_LOGIN,
6886 		     OBJECT_VERSION_NUMBER
6887 		     )
6888 		 VALUES (
6889 		     p_pmt_doc_id,
6890 		     i,
6891 		     sysdate,
6892 		     'SKIPPED',
6893 		     fnd_global.user_id,
6894 		     sysdate,
6895 		     fnd_global.user_id,
6896 		     sysdate,
6897 		     fnd_global.login_id,
6898 		     1
6899 		     );
6900 	 END;
6901        END IF;
6902 
6903      END LOOP;
6904 
6905 
6906 
6907      /*
6908       * STEP 2:
6909       *
6910       * Pick up all payments for this payment instruction
6911       * that have the given paper document number one-by-one.
6912       *
6913       * For each such payment, set the payment status to 'SPOILED'.
6914       */
6915      BEGIN
6916 
6917 	 -- looping through the entire document list
6918          FOR i IN p_used_docs_list.FIRST .. p_used_docs_list.LAST LOOP
6919 
6920 
6921    	  print_debuginfo(l_module_name, 'Payment ID : Paper Doc Num : Payment Status = ' || p_used_pmts_list(i) || ' : ' || p_used_docs_list(i) || ' : ' || l_payment_status_list(i));
6922 
6923 	  -- only invoices for those paper_documents which are marked as spoiled are unlocked here
6924 	  IF ( l_payment_status_list(i) = 'REMOVED_DOCUMENT_SPOILED') THEN
6925 
6926 	     l_paper_doc_num := p_used_docs_list(i);
6927 	     print_debuginfo(l_module_name, 'In the loop, spoiled document number : ('||i||') :' || p_used_pmts_list(i) );
6928 
6929              UPDATE
6930                  IBY_PAYMENTS_ALL
6931              SET
6932                  payment_status = PAY_STATUS_SPOILED
6933              WHERE
6934                  payment_instruction_id = p_instr_id          AND
6935                  payment_id   = p_used_pmts_list(i)
6936              ;
6937 
6938 
6939             print_debuginfo(l_module_name, 'Finished updating payments table');
6940              UPDATE
6941 	         IBY_DOCS_PAYABLE_ALL
6942              SET
6943                  document_status = DOC_STATUS_PMT_SPOILED
6944              WHERE
6945                   payment_id = p_used_pmts_list(i)
6946              ;
6947 
6948 	      print_debuginfo(l_module_name, 'Finished updating document payable table');
6949 
6950             OPEN  c_docs(p_used_pmts_list(i));
6951             FETCH c_docs BULK COLLECT INTO l_doc_id_list, l_doc_status_list;
6952             CLOSE c_docs;
6953 
6954            print_debuginfo(l_module_name, 'The number of doc ids for this '
6955                                           ||'payment' ||l_doc_id_list.COUNT);
6956 
6957 	   remove_documents_payable (
6958                      l_doc_id_list,
6959 		     l_doc_status_list,
6960 		     x_return_status_remove_doc
6961 		     );
6962 print_debuginfo(l_module_name,'Inside loop,after callling'
6963 || 'remove_documents_payable');
6964 
6965 
6966 	    IF (x_return_status_remove_doc <> FND_API.G_RET_STS_SUCCESS) THEN
6967 
6968 		     /*
6969   		      * Even if a single call to remove a document
6970      		      * failed, return failure for the entire
6971      		      * API request.
6972   		      */
6973 		     print_debuginfo(l_module_name, 'Removing of documents '
6974 			 || 'for payment instruction id '
6975 			 || p_instr_id
6976 			 || ' failed.'
6977 			 );
6978 
6979 		     print_debuginfo(l_module_name, 'EXIT');
6980 
6981 		     /*
6982   		      * It is the callers responsibility to rollback
6983        		      * all the changes.
6984        		      */
6985 		     RETURN;
6986 
6987 	    END IF;
6988 
6989 	 END IF;
6990 
6991         END LOOP;
6992 
6993      EXCEPTION
6994          WHEN OTHERS THEN
6995              print_debuginfo(l_module_name, 'Fatal: Exception occured '
6996                  || 'when attempting to update payment with payment '
6997                  || 'instruction id '
6998                  || p_instr_id
6999                  || ' and paper document number '
7000                  || l_paper_doc_num
7001                  );
7002 
7003              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
7004              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
7005              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
7006 
7007              /*
7008               * Propogate exception to caller.
7009               */
7010              RAISE;
7011 
7012      END;
7013 
7014      print_debuginfo(l_module_name, 'Finished updating payments table.');
7015 
7016      /*
7017       * STEP 3:
7018       *
7019       * Invoke the hook that handles witholding certificates.
7020       * Every time a paper document is PRINTED | REPRINTED |
7021       * SPOILED, the witholding certificates should be in sync.
7022       */
7023      l_callout_name := l_pkg_name || '.' || 'zx_witholdingCertificatesHook';
7024 
7025      print_debuginfo(l_module_name, 'Attempting to call hook: '
7026          || l_callout_name);
7027 
7028      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7, :8)';
7029 
7030      BEGIN
7031 
7032          EXECUTE IMMEDIATE
7033              (l_stmt)
7034          USING
7035              IN  p_instr_id,
7036              IN  'SPOILED',
7037              IN  l_api_version,
7038              IN  FND_API.G_FALSE,
7039              IN  FND_API.G_FALSE,
7040              OUT x_return_status,
7041              OUT l_msg_count,
7042              OUT l_msg_data
7043          ;
7044 
7045          /*
7046           * If the called procedure did not return success,
7047           * raise an exception.
7048           */
7049          IF (x_return_status IS NULL OR
7050              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
7051 
7052              print_debuginfo(l_module_name, 'Fatal: External app callout '''
7053                  || l_callout_name
7054                  || ''', returned failure status - '
7055                  || x_return_status
7056                  || '. Raising exception.'
7057                  );
7058 
7059              APP_EXCEPTION.RAISE_EXCEPTION;
7060 
7061          END IF;
7062 
7063      EXCEPTION
7064 
7065          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
7066              print_debuginfo(l_module_name, 'Callout "' || l_callout_name
7067                  || '" not implemented by calling app - AP'
7068                  );
7069 
7070              print_debuginfo(l_module_name, 'Skipping hook call.');
7071 
7072 
7073          WHEN OTHERS THEN
7074              print_debuginfo(l_module_name, 'Fatal: External app callout '''
7075                  || l_callout_name
7076                  || ''', generated exception.'
7077                  );
7078 
7079              print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
7080              print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
7081              FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
7082 
7083              /*
7084               * Propogate exception to caller.
7085               */
7086              RAISE;
7087      END;
7088 
7089      /*
7090       * STEP 4:
7091       *
7092       * Change the status of the successful payments of this instruction
7093       * to ISSUED status. The ISSUED status is the final status for a
7094       * paper payment; the payment must be in ISSUED status in order to
7095       * be marked complete.
7096       */
7097      UPDATE
7098          IBY_PAYMENTS_ALL
7099      SET
7100          payment_status = PAY_STATUS_ISSUED
7101      WHERE
7102          payment_instruction_id = p_instr_id     AND
7103          (
7104              payment_status IN
7105              (
7106              PAY_STATUS_FORMATTED,
7107              PAY_STATUS_SUB_FOR_PRINT
7108              )
7109              OR
7110              (
7111              process_type = PROCESS_TYPE_IMMEDIATE
7112              )
7113          )
7114      ;
7115 
7116      /*
7117       * STEP 5:
7118       *
7119       * Mark all the payments of the given payment instruction
7120       * as complete.
7121       */
7122      print_debuginfo(l_module_name, 'Attempting to mark payments of '
7123          || 'payment instruction '
7124          || p_instr_id
7125          || ' as complete.'
7126          );
7127 
7128      mark_all_pmts_complete (
7129          p_instr_id,
7130          p_submit_postive_pay,
7131          x_return_status
7132          );
7133 
7134      IF (x_return_status IS NULL OR
7135          x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
7136 
7137          print_debuginfo(l_module_name, 'Error status '
7138              || x_return_status
7139              || ' was received from the mark_all_pmts_complete() '
7140              || 'method. Raising exception.'
7141              );
7142 
7143          APP_EXCEPTION.RAISE_EXCEPTION;
7144 
7145      ELSE
7146 
7147          print_debuginfo(l_module_name, 'Successfully maked payments '
7148              || 'as complete.'
7149              );
7150 
7151      END IF;
7152 
7153      /*
7154       * STEP 6:
7155       *
7156       * Change the status of the payment instruction to PRINTED.
7157       */
7158      UPDATE
7159          IBY_PAY_INSTRUCTIONS_ALL
7160      SET
7161          payment_instruction_status = INS_STATUS_PRINTED
7162      WHERE
7163          payment_instruction_id = p_instr_id
7164      ;
7165 
7166      print_debuginfo(l_module_name, 'Successfully set payment '
7167          || 'instruction status to PRINTED.'
7168          );
7169 
7170      x_return_status := FND_API.G_RET_STS_SUCCESS;
7171 
7172      print_debuginfo(l_module_name, 'Returning success response ..');
7173 
7174      print_debuginfo(l_module_name, 'EXIT');
7175 
7176  EXCEPTION
7177      WHEN OTHERS THEN
7178 
7179      print_debuginfo(l_module_name, 'Exception occured when '
7180          || 'recording final print status for payment instruction '
7181          || p_instr_id
7182          );
7183 
7184      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
7185      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
7186      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
7187 
7188      x_return_status := FND_API.G_RET_STS_ERROR;
7189 
7190      print_debuginfo(l_module_name, 'EXIT');
7191 
7192  END finalize_print_status;
7193 
7194 /*--------------------------------------------------------------------
7195  | NAME:
7196  |     finalize_instr_print_status
7197  |
7198  | PURPOSE:
7199  |     Records the final print status for all the paper documents that
7200  |     are part of a payment instruction.
7201  |
7202  |     This is an overloaded method. See the other method signature for
7203  |     complete documentation.
7204  |
7205  | PARAMETERS:
7206  |     IN
7207  |
7208  |
7209  |     OUT
7210  |
7211  |
7212  | RETURNS:
7213  |
7214  | NOTES:
7215  |   Internal API, not for public use.
7216  |
7217  *---------------------------------------------------------------------*/
7218  PROCEDURE finalize_instr_print_status(
7219      p_instr_id       IN NUMBER,
7220      x_return_status  OUT NOCOPY VARCHAR2
7221      )
7222  IS
7223  BEGIN
7224 
7225      finalize_instr_print_status(
7226          p_instr_id,
7227          FALSE,
7228          x_return_status
7229          );
7230 
7231  END finalize_instr_print_status;
7232 
7233 /*--------------------------------------------------------------------
7234  | NAME:
7235  |     finalize_instr_print_status
7236  |
7237  | PURPOSE:
7238  |     Records the final print status for all the paper documents that
7239  |     are part of a payment instruction. This API will insert the paper
7240  |     document numbers linked to each payment in the instruction into the
7241  |     IBY_USED_PAYMENT_DOCS table along with the usage reason indicating
7242  |     that the paper document was successfully printed.
7243  |
7244  |     This API should only invoked when *all* the payments that are part
7245  |     of a payment instruction have been printed successfully.
7246  |
7247  |     This API is a light weight alternative to the finalize_print_status()
7248  |     API because the caller does not have to provide the list of used
7249  |     payment documents along with the usage reason. This API derives the
7250  |     list of used payment documents from the payments on the instruction
7251  |     and it sets the usage reason for each payment document as 'issued'.
7252  |
7253  | PARAMETERS:
7254  |     IN
7255  |       p_instr_id        - The payment instruction id for which all
7256  |                           checks were successfully printed.
7257  |
7258  |       p_submit_postive_pay
7259  |                         - Flag indicating whether positive pay file
7260  |                           report needs to be launched after finalizing
7261  |                           the payments.
7262  |
7263  |     OUT
7264  |       x_return_status   - Result of the API call:
7265  |                           FND_API.G_RET_STS_SUCCESS indicates that the
7266  |                           finalization process completed raised
7267  |                           successfully. In this case the caller must
7268  |                           COMMIT the status change.
7269  |
7270  |                           FND_API.G_RET_STS_ERROR (or other) indicates
7271  |                           that API did not complete successfully.
7272  |                           In this case, the caller must issue a
7273  |                           ROLLBACK to undo all status changes.
7274  |
7275  | RETURNS:
7276  |
7277  | NOTES:
7278  |   Internal API, not for public use.
7279  |
7280  *---------------------------------------------------------------------*/
7281  PROCEDURE finalize_instr_print_status(
7282      p_instr_id           IN NUMBER,
7283      p_submit_postive_pay IN BOOLEAN,
7284      x_return_status      OUT NOCOPY VARCHAR2
7285      )
7286  IS
7287 
7288  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
7289                                          || '.finalize_instr_print_status';
7290 
7291  l_pmtDocsTab  paperDocNumTab;
7292  l_skipped_document_number IBY_PAYMENTS_ALL.paper_document_number%TYPE;
7293  l_pmt_doc_id     NUMBER(15);
7294 
7295 
7296  /*
7297   * Cursor to pick up all the payment document numbers that
7298   * are linked to payments of a particular payment
7299   * instruction.
7300   */
7301 
7302  /*
7303   * Fix for bug 4887500.
7304   *
7305   * When finalizing the status of a payment instruction, the payment
7306   * status may not be in the right status for single payments.
7307   *
7308   * This is because the Post-PICP program performs the status change
7309   * for the payment and since it runs as a separate conc request, it
7310   * may not have completed by the time the single payments API
7311   * calls this post-PICP program and immediately starts to finalize
7312   * the payment status.
7313   *
7314   * Therefore, the best approach would be to not consider the payment
7315   * status when the payment is a single payment (i.e., process type of
7316   * the payment is 'immediate').
7317   */
7318  CURSOR c_pmt_docs (p_instr_id NUMBER)
7319  IS
7320  SELECT
7321      pmt.paper_document_number
7322  FROM
7323      IBY_PAYMENTS_ALL pmt
7324  WHERE
7325      pmt.payment_instruction_id = p_instr_id    AND
7326          (
7327              (
7328               pmt.payment_status         = PAY_STATUS_FORMATTED      OR
7329               pmt.payment_status         = PAY_STATUS_SUB_FOR_PRINT
7330              )
7331              OR
7332              (
7333               pmt.process_type           = PROCESS_TYPE_IMMEDIATE
7334              )
7335          )
7336  ;
7337 
7338  BEGIN
7339 
7340      print_debuginfo(l_module_name, 'ENTER');
7341 
7342      FND_MSG_PUB.initialize;
7343 
7344      /*
7345       * STATUS CHANGE:
7346       *
7347       * UI Responsibility:
7348       * NONE
7349       *
7350       * API Responsibility:
7351       * payment status = ISSUED
7352       * payment instruction status = PRINTED
7353       */
7354 
7355      /*
7356       * STEP 1:
7357       *
7358       * Derive list of paper documents associated with the payments
7359       * of this instruction.
7360       */
7361      OPEN  c_pmt_docs(p_instr_id);
7362      FETCH c_pmt_docs BULK COLLECT INTO l_pmtDocsTab;
7363      CLOSE c_pmt_docs;
7364 
7365      IF (l_pmtDocsTab.COUNT = 0) THEN
7366 
7367          print_debuginfo(l_module_name, 'Error: Number of '
7368              || 'paper documents associated with payment instruction '
7369              || p_instr_id
7370              || ' is zero. '
7371              || 'Returning failure response .. '
7372              );
7373 
7374          x_return_status := FND_API.G_RET_STS_ERROR;
7375 
7376          print_debuginfo(l_module_name, 'EXIT');
7377 
7378          RETURN;
7379 
7380      END IF;
7381 
7382      /*
7383       * STEP 2:
7384       *
7385       * Derive the payment document id (check stock) that was used to
7386       * print the payments of this instruction. The payment document
7387       * id also needs to be inserted into the IBY_USED_PAYMENT_DOCUMENTS
7388       * table.
7389       */
7390      SELECT
7391          payment_document_id
7392      INTO
7393          l_pmt_doc_id
7394      FROM
7395          IBY_PAY_INSTRUCTIONS_ALL
7396      WHERE
7397          payment_instruction_id = p_instr_id
7398      ;
7399 
7400      IF (l_pmt_doc_id IS NULL) THEN
7401 
7402          print_debuginfo(l_module_name, 'Error: Could not derive '
7403              || 'payment document associated with payment instruction '
7404              || p_instr_id
7405              || '. Returning failure response .. '
7406              );
7407 
7408          x_return_status := FND_API.G_RET_STS_ERROR;
7409 
7410          print_debuginfo(l_module_name, 'EXIT');
7411 
7412          RETURN;
7413 
7414      END IF;
7415 
7416      /*
7417       * STEP 3:
7418       *
7419       * Insert the paper document numbers and the payment
7420       * doc id we picked up in steps (1) and (2) into the
7421       * IBY_USED_PAYMENT_DOCUMENTS table. Set the usage
7422       * reason for each paper document as 'issued'.
7423       */
7424      FOR i IN l_pmtDocsTab.FIRST .. l_pmtDocsTab.LAST LOOP
7425 
7426 
7427 	BEGIN
7428 		-- finding if the document is already skipped earlier
7429 		SELECT cedocs.used_document_number
7430    	        INTO  l_skipped_document_number
7431 		FROM iby_used_payment_docs cedocs
7432 		WHERE cedocs.payment_document_id = l_pmt_doc_id
7433 		 AND cedocs.used_document_number = l_pmtDocsTab(i)
7434 		 AND cedocs.document_use = 'SKIPPED';
7435 
7436 	 EXCEPTION
7437 	 WHEN NO_DATA_FOUND THEN
7438 
7439 		-- if not skipped earlier, inserting new
7440 		 INSERT INTO IBY_USED_PAYMENT_DOCS (
7441 		     PAYMENT_DOCUMENT_ID,
7442 		     USED_DOCUMENT_NUMBER,
7443 		     DATE_USED,
7444 		     DOCUMENT_USE,
7445 		     CREATED_BY,
7446 		     CREATION_DATE,
7447 		     LAST_UPDATED_BY,
7448 		     LAST_UPDATE_DATE,
7449 		     LAST_UPDATE_LOGIN,
7450 		     OBJECT_VERSION_NUMBER
7451 		     )
7452 		 VALUES (
7453 		     l_pmt_doc_id,
7454 		     l_pmtDocsTab(i),
7455 		     sysdate,
7456 		     DOC_USE_ISSUED,
7457 		     fnd_global.user_id,
7458 		     sysdate,
7459 		     fnd_global.user_id,
7460 		     sysdate,
7461 		     fnd_global.login_id,
7462 		     1
7463 		     );
7464 
7465                  print_debuginfo(l_module_name, 'Document number not found, inserting new');
7466 	 END;
7467 
7468 	 -- updating the document_use in any case
7469 	 UPDATE IBY_USED_PAYMENT_DOCS
7470 	 SET DOCUMENT_USE = DOC_USE_ISSUED
7471 	 WHERE payment_document_id = l_pmt_doc_id
7472 	 AND used_document_number = l_pmtDocsTab(i);
7473 
7474 
7475      END LOOP;
7476 
7477 
7478      /*
7479       * STEP 4:
7480       *
7481       * Change the status of the successful payments of this instruction
7482       * to ISSUED status. The ISSUED status is the final status for a
7483       * paper payment; the payment must be in ISSUED status in order to
7484       * be marked complete.
7485       */
7486      UPDATE
7487          IBY_PAYMENTS_ALL
7488      SET
7489          payment_status = PAY_STATUS_ISSUED
7490      WHERE
7491          payment_instruction_id = p_instr_id     AND
7492          (
7493              payment_status IN
7494              (
7495              PAY_STATUS_FORMATTED,
7496              PAY_STATUS_SUB_FOR_PRINT
7497              )
7498              OR
7499              (
7500              process_type = PROCESS_TYPE_IMMEDIATE
7501              )
7502          )
7503      ;
7504 
7505      /*
7506       * STEP 5:
7507       *
7508       * Mark all the payments of the given payment instruction
7509       * as complete.
7510       */
7511      print_debuginfo(l_module_name,
7512          'Invoking mark payments complete API ..');
7513 
7514      mark_all_pmts_complete (
7515          p_instr_id,
7516          p_submit_postive_pay,
7517          x_return_status
7518          );
7519 
7520      print_debuginfo(l_module_name, 'Finished invoking mark payments '
7521          || 'complete API ..'
7522          );
7523 
7524      IF (x_return_status IS NULL OR
7525          x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
7526 
7527          print_debuginfo(l_module_name, 'Error: Could not mark '
7528              || 'the payments associated with payment instruction '
7529              || p_instr_id
7530              || ' as complete. Returning failure response .. '
7531              );
7532 
7533          x_return_status := FND_API.G_RET_STS_ERROR;
7534 
7535          print_debuginfo(l_module_name, 'EXIT');
7536 
7537          RETURN;
7538 
7539      ELSE
7540 
7541          print_debuginfo(l_module_name, 'Payments of '
7542              || 'payment instruction '
7543              || p_instr_id
7544              || ' marked as complete.'
7545              );
7546 
7547      END IF;
7548 
7549      /*
7550       * STEP 6:
7551       *
7552       * Change the status of the payment instruction to PRINTED.
7553       */
7554      UPDATE
7555          IBY_PAY_INSTRUCTIONS_ALL
7556      SET
7557          payment_instruction_status = INS_STATUS_PRINTED
7558      WHERE
7559          payment_instruction_id = p_instr_id
7560      ;
7561 
7562      print_debuginfo(l_module_name, 'Successfully set payment '
7563          || 'instruction status to PRINTED.'
7564          );
7565 
7566 
7567      x_return_status := FND_API.G_RET_STS_SUCCESS;
7568 
7569      print_debuginfo(l_module_name, 'Returning success response ..');
7570 
7571      print_debuginfo(l_module_name, 'EXIT');
7572 
7573  EXCEPTION
7574      WHEN OTHERS THEN
7575 
7576      print_debuginfo(l_module_name, 'Exception occured when '
7577          || 'recording final print status for payments of '
7578          || 'payment instruction '
7579          || p_instr_id
7580          );
7581 
7582      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
7583      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
7584      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
7585 
7586      x_return_status := FND_API.G_RET_STS_ERROR;
7587 
7588      print_debuginfo(l_module_name, 'EXIT');
7589 
7590  END finalize_instr_print_status;
7591 
7592 /*--------------------------------------------------------------------
7593  | NAME:
7594  |     mark_all_pmts_complete
7595  |
7596  | PURPOSE:
7597  |     Marks all payments of the given payment instruction as complete.
7598  |
7599  |     This method overloads the other mark_all_pmts_complete(..)
7600  |     See the other method for complete documentation.
7601  |
7602  | NOTES:
7603  |     Internal API, not for public use.
7604  |
7605  |     This method does not COMMIT/ROLLBACK. It is the callers responsibility
7606  |     to COMMIT/ROLLBACK depending upon the return status.
7607  |
7608  *---------------------------------------------------------------------*/
7609  PROCEDURE mark_all_pmts_complete (
7610      p_instr_id       IN NUMBER,
7611      x_return_status  OUT NOCOPY VARCHAR2
7612      )
7613  IS
7614 
7615  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
7616                                          || '.mark_all_pmts_complete';
7617  BEGIN
7618 
7619      /*
7620       * Call mark_all_pmts_complete(..) with the submit
7621       * positive pay file report flag set to 'no' by
7622       * default.
7623       */
7624      mark_all_pmts_complete(p_instr_id, FALSE, x_return_status);
7625 
7626  END mark_all_pmts_complete;
7627 
7628 /*--------------------------------------------------------------------
7629  | NAME:
7630  |     mark_all_pmts_complete
7631  |
7632  | PURPOSE:
7633  |     Marks all payments of the given payment instruction as complete.
7634  |     Also marks the status of the payment instruction to complete.
7635  |
7636  |     Only payments that are in 'valid' status will be marked complete,
7637  |     others will be left untouched. The 'valid' status for a payment
7638  |     is dependent upon whether it is a printed payment or an electronic
7639  |     payment. Here is list of valid statuses by processing type:
7640  |
7641  |     Processing     Valid statuses for payments
7642  |     Type
7643  |     ----------     ---------------------------
7644  |     PRINTED        ISSUED
7645  |
7646  |     ELECTRONIC     FORMATTED
7647  |                    TRANSMITTED
7648  |                    ACKNOWLEDGED
7649  |                    BANK_VALIDATED
7650  |                    PAID
7651  |
7652  |     Therefore, the caller must ensure that they set the payment
7653  |     status to valid status for all the payments that are to be
7654  |     marked complete *before* calling this API.
7655  |
7656  |     Once payments are marked as complete, the calling application
7657  |     hook 'payments_completed()' is invoked to inform the calling
7658  |     app that their payments have been marked complete.
7659  |
7660  | PARAMETERS:
7661  |     IN
7662  |       p_instr_id        - The payment instruction id for which the
7663  |                           payments need to be marked complete.
7664  |
7665  |       p_submit_postive_pay
7666  |                         - Flag indicating whether positive pay file
7667  |                           report needs to be launched after marking
7668  |                           the payments complete.
7669  |
7670  |     OUT
7671  |       x_return_status   - Result of the API call:
7672  |                           FND_API.G_RET_STS_SUCCESS indicates that
7673  |                           the mark complete process finished
7674  |                           successfully. In this case the caller must
7675  |                           COMMIT the status change.
7676  |
7677  |                           FND_API.G_RET_STS_ERROR (or other) indicates
7678  |                           that API did not complete successfully.
7679  |                           In this case, the caller must issue a
7680  |                           ROLLBACK to undo all status changes.
7681  |
7682  | RETURNS:
7683  |
7684  | NOTES:
7685  |     Internal API, not for public use.
7686  |
7687  |     This method does not COMMIT/ROLLBACK. It is the callers responsibility
7688  |     to COMMIT/ROLLBACK depending upon the return status.
7689  *---------------------------------------------------------------------*/
7690  PROCEDURE mark_all_pmts_complete (
7691      p_instr_id           IN NUMBER,
7692      p_submit_postive_pay IN BOOLEAN,
7693      x_return_status      OUT NOCOPY VARCHAR2
7694      )
7695  IS
7696 
7697  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
7698                                          || '.mark_all_pmts_complete';
7699 
7700  l_completion_id   NUMBER(15);
7701  l_processing_type VARCHAR2(200);
7702  l_process_type    VARCHAR2(200);
7703 
7704  /* used in forming callout procedure name */
7705  l_calling_app_id NUMBER;
7706  l_app_short_name VARCHAR2(200);
7707  l_pkg_name       VARCHAR2(200);
7708  l_callout_name   VARCHAR2(500);
7709  l_stmt           VARCHAR2(1000);
7710 
7711  /* used in invocation of callout procedure */
7712  l_api_version    CONSTANT NUMBER := 1.0;
7713  l_msg_count      NUMBER;
7714  l_msg_data       VARCHAR2(2000);
7715 
7716  l_appNamesTab    appNamesTab;
7717  l_appIdsTab      appIdsTab;
7718 
7719  l_pmts_complete_code   VARCHAR2(1000);
7720 
7721  l_pmt_doc_id     NUMBER(15);
7722  l_pmt_doc_name   VARCHAR2(2000);
7723 
7724  l_doc_count      NUMBER(15);
7725  l_pmt_count      NUMBER(15);
7726 
7727  /*
7728   * These variables are related to kicking off automatic
7729   * reports.
7730   */
7731  l_profile_id     IBY_PAYMENT_PROFILES.
7732                       payment_profile_id%TYPE;
7733  l_auto_pi_reg_submit_flag
7734                   IBY_SYS_PMT_PROFILES_B.
7735                       automatic_pi_reg_submit%TYPE;
7736  l_auto_sra_submit_flag
7737                   IBY_REMIT_ADVICE_SETUP.
7738                       automatic_sra_submit_flag%TYPE;
7739  l_remit_format_code
7740                   IBY_REMIT_ADVICE_SETUP.
7741                       remittance_advice_format_code%TYPE;
7742  l_pos_pay_format IBY_PAYMENT_PROFILES.
7743                       positive_pay_format_code%TYPE;
7744  l_pi_reg_format  IBY_SYS_PMT_PROFILES_B.
7745                       pi_register_format%TYPE;
7746 
7747 
7748  l_conc_req_id    NUMBER(15);
7749 
7750  l_icx_numeric_characters   VARCHAR2(30); -- Bug 6411356
7751  l_bool_val   boolean;  -- Bug 6411356
7752 
7753  l_error_code     IBY_TRANSACTION_ERRORS.error_code%TYPE;
7754 
7755  /*
7756   * Cursor to pick up all calling applications associated
7757   * with a particular payment instruction.
7758   */
7759 
7760  /*
7761   * Fix for bug 4901075.
7762   *
7763   * Added distinct clause to select statement so that duplicate
7764   * calling app ids are eliminated.
7765   *
7766   * Otherwise, the call out could be invoked multiple times
7767   * per calling app.
7768   */
7769  CURSOR c_app_names (p_instr_id NUMBER)
7770  IS
7771  SELECT DISTINCT
7772      fnd.application_short_name
7773  INTO
7774      l_app_short_name
7775  FROM
7776      FND_APPLICATION          fnd,
7777      IBY_PAYMENTS_ALL         pmt,
7778      IBY_PAY_SERVICE_REQUESTS req,
7779      IBY_PAY_INSTRUCTIONS_ALL ins
7780  WHERE
7781      pmt.payment_instruction_id     = ins.payment_instruction_id     AND
7782      req.payment_service_request_id = pmt.payment_service_request_id AND
7783      fnd.application_id             = req.calling_app_id             AND
7784      ins.payment_instruction_id     = p_instr_id
7785  ;
7786 
7787  /*
7788   * Cursor to pick up ids all calling applications
7789   * associated with a particular payment instruction.
7790   */
7791  CURSOR c_app_ids (p_instr_id NUMBER)
7792  IS
7793  SELECT
7794      fnd.application_id
7795  FROM
7796      FND_APPLICATION          fnd,
7797      IBY_PAYMENTS_ALL         pmt,
7798      IBY_PAY_SERVICE_REQUESTS req,
7799      IBY_PAY_INSTRUCTIONS_ALL ins
7800  WHERE
7801      pmt.payment_instruction_id     = ins.payment_instruction_id     AND
7802      req.payment_service_request_id = pmt.payment_service_request_id AND
7803      fnd.application_id             = req.calling_app_id             AND
7804      ins.payment_instruction_id     = p_instr_id
7805  ;
7806 
7807  /*
7808   * Implementing the callout is optional for the calling app.
7809   * If the calling app does not implement the hook, then
7810   * the call to the hook will result in ORA-06576 error.
7811   *
7812   * There is no exception name associated with this code, so
7813   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
7814   * exception occurs, it is not fatal: we log the error and
7815   * proceed.
7816   *
7817   * If, on the other hand, the calling app implements the
7818   * callout, but the callout throws an exception, it is fatal
7819   * and we must abort the program (this will be caught
7820   * in WHEN OTHERS block).
7821   */
7822  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
7823  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
7824 
7825  BEGIN
7826 
7827      print_debuginfo(l_module_name, 'ENTER');
7828 
7829      FND_MSG_PUB.initialize;
7830 
7831      /*
7832       * STEP I:
7833       *
7834       * Get the processing type of this payment instruction.
7835       * The processing type is used as a criterion in selecting
7836       * which payments of this payment instruction are updated
7837       * to completed status.
7838       */
7839      SELECT
7840          prof.processing_type,
7841          inst.payments_complete_code,
7842          inst.process_type
7843      INTO
7844          l_processing_type,
7845          l_pmts_complete_code,
7846          l_process_type
7847      FROM
7848          IBY_PAYMENT_PROFILES     prof,
7849          IBY_PAY_INSTRUCTIONS_ALL inst
7850      WHERE
7851          prof.payment_profile_id     = inst.payment_profile_id  AND
7852          inst.payment_instruction_id = p_instr_id;
7853 
7854      print_debuginfo(l_module_name, 'For payment instruction '
7855          || p_instr_id
7856          || ', payment complete code: '
7857          || l_pmts_complete_code
7858          || ' and process type: '
7859          || l_process_type
7860          );
7861 
7862      /*
7863       * STEP II:
7864       *
7865       * Check whether we need to mark payments complete
7866       * for the payments of this payment instruction.
7867       *
7868       * Payments should be marked complete should be called
7869       * *except* when:
7870       *
7871       * A. The payments of this payment instruction have already
7872       * been marked complete.
7873       */
7874      IF (UPPER(l_pmts_complete_code) = 'YES') THEN
7875 
7876          print_debuginfo(l_module_name, 'Not performing mark pmts '
7877              || 'complete for payment instruction '
7878              || p_instr_id
7879              || ' because payments already marked complete '
7880              || 'for this instruction.'
7881              );
7882 
7883          x_return_status := FND_API.G_RET_STS_SUCCESS;
7884          print_debuginfo(l_module_name, 'Returning success response ..');
7885 
7886          print_debuginfo(l_module_name, 'EXIT');
7887 
7888          RETURN;
7889 
7890      END IF;
7891 
7892      print_debuginfo(l_module_name, 'Processing type of payment instruction '
7893          || p_instr_id
7894          || ' is '
7895          || l_processing_type
7896          );
7897 
7898      /*
7899       * STEP III:
7900       *
7901       * Mark all payments of this payment instruction as
7902       * completed.
7903       */
7904      IF (l_processing_type = P_TYPE_PRINTED) THEN
7905 
7906          UPDATE
7907              IBY_PAYMENTS_ALL
7908          SET
7909              payments_complete_flag = 'Y'
7910          WHERE
7911              payment_instruction_id = p_instr_id        AND
7912              payment_status         = PAY_STATUS_ISSUED
7913          ;
7914 
7915      ELSE
7916 
7917          /* electronic processing type */
7918 
7919          IF (l_process_type <> PROCESS_TYPE_IMMEDIATE) THEN
7920 
7921              /* batch payment(s) */
7922 
7923              UPDATE
7924                  IBY_PAYMENTS_ALL
7925              SET
7926                  payments_complete_flag = 'Y'
7927              WHERE
7928                  payment_instruction_id = p_instr_id AND
7929                  payment_status IN
7930                      (
7931                      PAY_STATUS_FORMATTED,
7932                      PAY_STATUS_TRANSMITTED,
7933                      PAY_STATUS_ACK,
7934                      PAY_STATUS_BNK_VALID,
7935                      PAY_STATUS_PAID
7936                      )
7937              ;
7938 
7939          ELSE
7940 
7941              /* quick/single payment */
7942 
7943              /*
7944               * The Post-PICP program is responsible for
7945               * setting the payment status to FORMATTED /
7946               * TRANSMITTED for electronic payments.
7947               *
7948               * However, when mark_all_payments(..) is called
7949               * for single payments, the Post-PICP would have
7950               * not yet executed (because it runs as a separate
7951               * conc program). Therefore, we set the payment
7952               * complete flag to 'Y' here even through the
7953               * payment is not technically complete.
7954               *
7955               * This special handling is applicable only to
7956               * single payments.
7957               */
7958 
7959              /*
7960               * Fix for bug 5179474:
7961               *
7962               * The PICP will now set the payment status to
7963               * FORMATTED without waiting for the Post-PICP
7964               * to complete.
7965               *
7966               * Reason for this change is so that the payment
7967               * status and the payment complete flag are in
7968               * sync (as in batch payments scenario).
7969               *
7970               * Therefore, mark the payment complete if the
7971               * payment status is FORMATTED.
7972               */
7973 
7974              UPDATE
7975                  IBY_PAYMENTS_ALL
7976              SET
7977                  payments_complete_flag = 'Y'
7978              WHERE
7979                  payment_instruction_id = p_instr_id AND
7980                  payment_status IN
7981                      (
7982                      PAY_STATUS_FORMATTED
7983                      )
7984              ;
7985 
7986          END IF;
7987 
7988      END IF;
7989 
7990      print_debuginfo(l_module_name, 'Finished marking payments of '
7991          || 'payment instruction '
7992          || p_instr_id
7993          || ' as complete.'
7994          );
7995 
7996      /*
7997       * STEP IV:
7998       *
7999       * Get the 'process type' if this payment instruction.
8000       *
8001       * If this payment instruction has been created as part
8002       * of single payments flow, the process type will be
8003       * IMMEDIATE, else it will be STANDARD.
8004       *
8005       * We need to know the process type because we should not be
8006       * invoking the callout for quick payments (as these are
8007       * automatically marked as complete by AP).
8008       */
8009 
8010      /*
8011       * Fix for bug 4923416.
8012       *
8013       * Get the process type from the payment instruction itself
8014       * instead of deriving it from the payments of the instruction.
8015       */
8016      print_debuginfo(l_module_name, 'Process type for pmt instruction '
8017          || p_instr_id
8018          || ' is '
8019          || l_process_type
8020          );
8021 
8022      /*
8023       * STEP V:
8024       *
8025       * Mark the given payment instruction as completed.
8026       */
8027 
8028      UPDATE
8029          IBY_PAY_INSTRUCTIONS_ALL
8030      SET
8031          payments_complete_code = PMT_COMPLETE_YES
8032      WHERE
8033          payment_instruction_id = p_instr_id
8034      ;
8035 
8036      print_debuginfo(l_module_name, 'Finished marking payment instruction '
8037          || p_instr_id
8038          || ' as complete.'
8039          );
8040 
8041      /*
8042       * Pick up the names of all the applications which have
8043       * payments in the current payment instruction.
8044       *
8045       * Remember, one payment instruction can contain payments
8046       * across multiple calling applications.
8047       */
8048      OPEN  c_app_names (p_instr_id);
8049      FETCH c_app_names BULK COLLECT INTO l_appNamesTab;
8050      CLOSE c_app_names;
8051 
8052      /*
8053       * Pick up the ids of all the applications which have
8054       * payments in the current payment instruction.
8055       *
8056       * Remember, one payment instruction can contain payments
8057       * across multiple calling applications.
8058       */
8059      OPEN  c_app_ids (p_instr_id);
8060      FETCH c_app_ids BULK COLLECT INTO l_appIdsTab;
8061      CLOSE c_app_ids;
8062 
8063      /*
8064       * STEP VI:
8065       *
8066       * Loop through all the application names, invoking the
8067       * callout of each application.
8068       */
8069      FOR i IN l_appNamesTab.FIRST .. l_appNamesTab.LAST LOOP
8070 
8071          /*
8072           * Get the constructed package name to use in the
8073           * call out.
8074           */
8075          l_pkg_name := construct_callout_pkg_name(l_appNamesTab(i));
8076 
8077          print_debuginfo(l_module_name, 'Constructed package name: '
8078              || l_pkg_name);
8079 
8080          IF (l_pkg_name IS NULL) THEN
8081 
8082              print_debuginfo(l_module_name, 'Package name is null. '
8083                  || 'Raising exception.');
8084 
8085              APP_EXCEPTION.RAISE_EXCEPTION;
8086 
8087          END IF;
8088 
8089 
8090          /*
8091           * Get the next available completed payments group id.
8092           */
8093          SELECT
8094              IBY_COMPLETED_PMTS_GROUP_S.NEXTVAL
8095          INTO
8096              l_completion_id
8097          FROM
8098              DUAL
8099          ;
8100 
8101          /*
8102           * Update the completed payments for this calling app
8103           * with the completed document group id. The calling
8104           * application will identify completed documents using
8105           * this id.
8106           */
8107          IF (l_processing_type = P_TYPE_PRINTED) THEN
8108 
8109              UPDATE
8110                  IBY_PAYMENTS_ALL     pmt
8111              SET
8112                  pmt.completed_pmts_group_id = l_completion_id
8113              WHERE
8114                  pmt.payment_instruction_id = p_instr_id         AND
8115                  pmt.payments_complete_flag = 'Y'                AND
8116                  payment_status             = PAY_STATUS_ISSUED  AND
8117                  pmt.payment_id IN
8118                      (SELECT
8119                           doc.payment_id
8120                       FROM
8121                           IBY_DOCS_PAYABLE_ALL doc
8122                       WHERE
8123                           doc.payment_id     = pmt.payment_id AND
8124                           doc.calling_app_id = l_appIdsTab(i)
8125                       )
8126              ;
8127 
8128          ELSE
8129 
8130              UPDATE
8131                  IBY_PAYMENTS_ALL     pmt
8132              SET
8133                  pmt.completed_pmts_group_id = l_completion_id
8134              WHERE
8135                  pmt.payment_instruction_id = p_instr_id         AND
8136                  pmt.payments_complete_flag = 'Y'                AND
8137                  payment_status IN
8138                      (
8139                      PAY_STATUS_FORMATTED,
8140                      PAY_STATUS_TRANSMITTED,
8141                      PAY_STATUS_ACK,
8142                      PAY_STATUS_BNK_VALID,
8143                      PAY_STATUS_PAID
8144                      )                                           AND
8145                  pmt.payment_id IN
8146                      (SELECT
8147                           doc.payment_id
8148                       FROM
8149                           IBY_DOCS_PAYABLE_ALL doc
8150                       WHERE
8151                           doc.payment_id     = pmt.payment_id AND
8152                           doc.calling_app_id = l_appIdsTab(i)
8153                       )
8154              ;
8155 
8156          END IF;
8157 
8158          /*
8159           * DEBUG PRINT FOR PAYMENTS
8160           *
8161           * Print list of payments marked complete. This is
8162           * very important for debugging AP-IBY boundry issues.
8163           */
8164          print_completed_pmts(l_completion_id);
8165 
8166          /*
8167           * Update the documents of the completed payments with
8168           * the completed document group id. This will allow the
8169           * calling app to select the completed documents directly
8170           * if they so wish.
8171           */
8172          UPDATE
8173              IBY_DOCS_PAYABLE_ALL doc
8174          SET
8175              doc.completed_pmts_group_id = l_completion_id
8176          WHERE
8177              doc.document_status <> 'REMOVED' AND /* Bug 6388935- removed
8178 document handling */
8179              doc.payment_id IN
8180                  (SELECT
8181                       pmt.payment_id
8182                   FROM
8183                       IBY_PAYMENTS_ALL pmt
8184                   WHERE
8185                       pmt.completed_pmts_group_id = l_completion_id
8186                   )
8187          ;
8188 
8189          /*
8190           * DEBUG PRINT FOR DOCUMENTS
8191           *
8192           * Print list of documents payable marked complete. This is
8193           * very important for debugging AP-IBY boundry issues.
8194           */
8195          print_completed_docs(l_completion_id);
8196 
8197          /*
8198           * For single payments, do not invoke the callout because
8199           * single payments are automatically confirmed by AP.
8200           *
8201           * Only invoke callout where process type is not immediate.
8202           */
8203          IF (l_process_type <> PROCESS_TYPE_IMMEDIATE) THEN
8204 
8205              /*
8206               * Now try to call the external app's implementation of the hook.
8207               * The calling app may or may not have implemented the hook, so
8208               * it's not fatal if the implementation does not exist.
8209               */
8210              l_callout_name := l_pkg_name || '.' || 'payments_completed';
8211 
8212              print_debuginfo(l_module_name, 'Attempting to invoke callout: '
8213                  || l_callout_name, FND_LOG.LEVEL_UNEXPECTED);
8214 
8215              SELECT
8216                  count(*)
8217              INTO
8218                  l_pmt_count
8219              FROM
8220                  IBY_PAYMENTS_ALL pmt
8221              WHERE
8222                  pmt.completed_pmts_group_id = l_completion_id
8223              ;
8224 
8225              SELECT
8226                  count(*)
8227              INTO
8228                  l_doc_count
8229              FROM
8230                  IBY_DOCS_PAYABLE_ALL doc
8231              WHERE
8232                  doc.completed_pmts_group_id = l_completion_id
8233              ;
8234 
8235              print_debuginfo(l_module_name, 'Params passed to callout - '
8236                  || 'completed pmts group id: '
8237                  || l_completion_id,
8238                  FND_LOG.LEVEL_UNEXPECTED
8239                  );
8240 
8241              print_debuginfo(l_module_name, 'Params not passed to callout - '
8242                  || 'completed pmts count: '
8243                  || l_pmt_count
8244                  || ', completed docs count: '
8245                  || l_doc_count
8246                  );
8247 
8248              l_stmt := 'CALL '|| l_callout_name
8249                               || '(:1, :2, :3, :4, :5, :6, :7)';
8250 
8251              BEGIN
8252 
8253                  EXECUTE IMMEDIATE
8254                      (l_stmt)
8255                  USING
8256                      IN  l_api_version,
8257                      IN  FND_API.G_FALSE,
8258                      IN  FND_API.G_FALSE,
8259                      OUT x_return_status,
8260                      OUT l_msg_count,
8261                      OUT l_msg_data,
8262                      IN  l_completion_id
8263                  ;
8264 
8265 
8266                  /*
8267                   * If the called procedure did not return success,
8268                   * raise an exception.
8269                   */
8270                  IF (x_return_status IS NULL OR
8271                      x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
8272 
8273                      print_debuginfo(l_module_name, 'Fatal: External app '
8274                          || 'callout '''
8275                          || l_callout_name
8276                          || ''', returned failure status - '
8277                          || x_return_status
8278                          || '. Raising exception.',
8279                          FND_LOG.LEVEL_UNEXPECTED
8280                          );
8281 
8282                      APP_EXCEPTION.RAISE_EXCEPTION;
8283 
8284                  END IF;
8285 
8286              EXCEPTION
8287 
8288                  WHEN PROCEDURE_NOT_IMPLEMENTED THEN
8289                      print_debuginfo(l_module_name, 'Callout "'
8290                          || l_callout_name
8291                          || '" not implemented by calling app '
8292                          || l_app_short_name || '.');
8293 
8294                      print_debuginfo(l_module_name, 'Skipping hook call.');
8295 
8296                  WHEN OTHERS THEN
8297                      print_debuginfo(l_module_name, 'Fatal: External app '
8298                          || 'callout '''
8299                          || l_callout_name
8300                          || ''', generated exception.',
8301                          FND_LOG.LEVEL_UNEXPECTED
8302                          );
8303 
8304                      print_debuginfo(l_module_name, 'SQL code: '
8305                          || SQLCODE, FND_LOG.LEVEL_UNEXPECTED);
8306                      print_debuginfo(l_module_name, 'SQL err msg: '
8307                          || SQLERRM, FND_LOG.LEVEL_UNEXPECTED);
8308 
8309                      /*
8310                       * Fix for bug 5608142:
8311                       *
8312                       * When mark complete API fails, it is most likely
8313                       * because document sequencing has not been setup
8314                       * correctly.
8315                       *
8316                       * Populate a message on the message stack so that
8317                       * this message can be displayed to the user.
8318                       */
8319                      l_error_code := 'IBY_COMPL_CALLOUT_ERROR';
8320                      FND_MESSAGE.set_name('IBY', l_error_code);
8321 
8322                      FND_MESSAGE.SET_TOKEN('CALLOUT',
8323                          l_callout_name,
8324                          FALSE);
8325 
8326                      /*
8327                       * Set the error message on the concurrent
8328                       * program output file (to warn user that
8329                       * the hook failed).
8330                       */
8331                      FND_FILE.PUT_LINE(FND_FILE.OUTPUT, FND_MESSAGE.GET);
8332 
8333                      /*
8334                       * Set the message on the error stack
8335                       * to display in UI (in case of direct
8336                       * API call from UI).
8337                       */
8338                      FND_MSG_PUB.ADD;
8339 
8340                      --FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
8341 
8342                      /*
8343                       * Propogate exception to caller.
8344                       */
8345                      RAISE;
8346 
8347              END;
8348 
8349          ELSE
8350 
8351              print_debuginfo(l_module_name, 'Not attempting to invoke callout '
8352                  || 'because this is a single payment.');
8353 
8354          END IF;
8355 
8356      END LOOP;
8357 
8358      /*
8359       * Step VII:
8360       *
8361       * Unlock the payment document that has been locked by this payment
8362       * instruction.
8363       */
8364 
8365      /*
8366       * For single payments, the payment document is not locked.
8367       * Consequently, there is no need to unlock it either.
8368       */
8369      IF (l_process_type <> PROCESS_TYPE_IMMEDIATE) THEN
8370 
8371          IF (l_processing_type = P_TYPE_PRINTED) THEN
8372 
8373              print_debuginfo(l_module_name, 'Unlocking payment document '
8374                  || 'locked by payment instruction '
8375                  || p_instr_id
8376              );
8377 
8378              BEGIN
8379 
8380                  UPDATE
8381                      CE_PAYMENT_DOCUMENTS
8382                  SET
8383                      payment_instruction_id = NULL,
8384 		     /* Bug 6707369
8385 		      * If some of the documents are skipped, the payment
8386 		      * document's last issued check number must be updated
8387 		      */
8388 		     last_issued_document_number = nvl(
8389 		     (SELECT MAX(pmt.paper_document_number)
8390 		      FROM iby_payments_all pmt
8391 		      WHERE pmt.payment_instruction_id = p_instr_id)
8392 		      ,last_issued_document_number
8393 		      )
8394                  WHERE
8395                      payment_instruction_id = p_instr_id
8396                  RETURNING
8397                      payment_document_id,
8398                      payment_document_name
8399                  INTO
8400                      l_pmt_doc_id,
8401                      l_pmt_doc_name
8402                  ;
8403 
8404                  print_debuginfo(l_module_name, 'Payment document id '
8405                      || ''''
8406                      || l_pmt_doc_id
8407                      || ''''
8408                      || ' with name '
8409                      || ''''
8410                      || l_pmt_doc_name
8411                      || ''''
8412                      || ' unlocked successfully.'
8413                      );
8414 
8415              EXCEPTION
8416                  WHEN OTHERS THEN
8417 
8418                  /*
8419                   * This is a non-fatal exception. We will log the exception
8420                   * and return.
8421                   */
8422                  print_debuginfo(l_module_name, 'Non-Fatal: Exception occured '
8423                      || 'when unlocking pmt document locked by pmt instruction '
8424                      || p_instr_id
8425                      );
8426 
8427                  print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
8428                  print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
8429 
8430              END;
8431 
8432          ELSE
8433 
8434              print_debuginfo(l_module_name, 'Not attempting to unlock '
8435                  || 'payment document because this is an electronic '
8436                  || 'instruction'
8437                  );
8438 
8439          END IF; -- if processing type = PRINTED
8440 
8441      ELSE
8442 
8443          print_debuginfo(l_module_name, 'Not attempting to unlock '
8444              || 'payment document because this is a single '
8445              || 'payment (payment document was never locked)'
8446              );
8447 
8448      END IF; -- process type <> IMMEDIATE
8449 
8450      /*
8451       * Step VIII:
8452       *
8453       * Invoke payment related reports if necessary.
8454       *
8455       * These reports are:
8456       *   + Final payment instruction register
8457       *   + Separate remittance advice report
8458       */
8459 
8460     --Bug 6411356
8461     --below code added to set the current nls character setting
8462     --before submitting a child requests.
8463     fnd_profile.get('ICX_NUMERIC_CHARACTERS',l_icx_numeric_characters);
8464 
8465      /*
8466       *
8467       * Get the profile id for this payment instruction
8468       * along with the report related settings.
8469       */
8470      SELECT
8471          prof.payment_profile_id,
8472          prof.positive_pay_format_code,
8473          sys_prof.automatic_pi_reg_submit,
8474          sys_prof.pi_register_format,
8475          remit.automatic_sra_submit_flag,
8476          remit.remittance_advice_format_code
8477      INTO
8478          l_profile_id,
8479          l_pos_pay_format,
8480          l_auto_pi_reg_submit_flag,
8481          l_pi_reg_format,
8482          l_auto_sra_submit_flag,
8483          l_remit_format_code
8484      FROM
8485          IBY_PAYMENT_PROFILES     prof,
8486          IBY_SYS_PMT_PROFILES_B   sys_prof,
8487          IBY_PAY_INSTRUCTIONS_ALL inst,
8488          IBY_REMIT_ADVICE_SETUP   remit
8489      WHERE
8490          prof.payment_profile_id      = inst.payment_profile_id   AND
8491          sys_prof.system_profile_code = prof.system_profile_code  AND
8492          remit.system_profile_code    = prof.system_profile_code  AND
8493          inst.payment_instruction_id  = p_instr_id;
8494 
8495      print_debuginfo(l_module_name, 'For payment instruction '
8496          || p_instr_id
8497          || ', profile id: '
8498          || l_profile_id
8499          || ', auto pi register submit flag: '
8500          || l_auto_pi_reg_submit_flag
8501          || ', pi register format: '
8502          || l_pi_reg_format
8503          || ', auto remit advice submit flag: '
8504          || l_auto_sra_submit_flag
8505          || ', remittance advice format: '
8506          || l_remit_format_code
8507          || ', positive pay format: '
8508          || l_pos_pay_format
8509          );
8510 
8511      /*
8512       * Launch the Final Payment Instruction Register report.
8513       */
8514 
8515      /*
8516       * Fix for bug 5732799:
8517       *
8518       * Pass the payment instruction register format as a
8519       * param when launching the payment instruction register
8520       * report.
8521       */
8522      IF (UPPER(l_auto_pi_reg_submit_flag) = 'Y' AND
8523          l_pi_reg_format IS NOT NULL) THEN
8524 
8525          /*
8526           * Fix for bug 5407120:
8527           *
8528           * Before kicking off reports / formats make sure that
8529           * the numeric characters delimiter is correctly set
8530           * by using FND_REQUEST.SET_OPTIONS(..).
8531           *
8532           * The argument provided to this method is based on
8533           * the lookup ICX_NUMERIC_CHARACTERS.
8534           *
8535           * Otherwise, the num delimiter would be picked up
8536           * based on NLS territory and could cause problems.
8537           *
8538           * E.g., $10000.52 would be displayed as $10.000,52 for
8539           * PL territory and this causes problems to XML publisher.
8540           */
8541          l_bool_val := FND_REQUEST.SET_OPTIONS(
8542                            numeric_characters => l_icx_numeric_characters
8543                            );
8544 
8545          l_conc_req_id := FND_REQUEST.SUBMIT_REQUEST(
8546                              'IBY',
8547                              'IBY_FD_FINAL_PMT_REGISTER',
8548                              '',
8549                              '',
8550                              FALSE,
8551                              ''||p_instr_id||'',
8552                              ''||l_pi_reg_format||'',
8553                              '', '', '', '', '', '', '', '', '',
8554                              '', '', '', '', '', '', '', '', '', '',
8555                              '', '', '', '', '', '', '', '', '', '',
8556                              '', '', '', '', '', '', '', '', '', '',
8557                              '', '', '', '', '', '', '', '', '', '',
8558                              '', '', '', '', '', '', '', '', '', '',
8559                              '', '', '', '', '', '', '', '', '', '',
8560                              '', '', '', '', '', '', '', '', '', '',
8561                              '', '', '', '', '', '', '', '', '', '',
8562                              '', '', '', '', '', '', ''
8563                              );
8564 
8565          IF (l_conc_req_id = 0) THEN
8566 
8567              print_debuginfo(l_module_name, 'Request to launch payment '
8568                  || 'instruction register report concurrent program failed.');
8569              APP_EXCEPTION.RAISE_EXCEPTION;
8570 
8571          ELSE
8572 
8573              print_debuginfo(l_module_name, 'Payment instruction register '
8574                  || 'report was launched successfully. '
8575                  || 'Check concurrent request id :'
8576                  || to_char(l_conc_req_id)
8577                  );
8578 
8579          END IF;
8580 
8581      END IF;
8582 
8583      /*
8584       * Launch the Separate Remittance Advice report.
8585       */
8586      IF (UPPER(l_auto_sra_submit_flag) = 'Y') THEN
8587 
8588          l_bool_val := FND_REQUEST.SET_OPTIONS(
8589                            numeric_characters => l_icx_numeric_characters
8590                            );
8591 
8592          l_conc_req_id := FND_REQUEST.SUBMIT_REQUEST(
8593                              'IBY',
8594                              'IBY_FD_SRA_FORMAT',
8595                              '',
8596                              '',
8597                              FALSE,
8598                              ''||p_instr_id||'',
8599                              ''||l_remit_format_code||'',
8600                              '', '', '', '', '', '', '', '', '',
8601                              '', '', '', '', '', '', '', '', '', '',
8602                              '', '', '', '', '', '', '', '', '', '',
8603                              '', '', '', '', '', '', '', '', '', '',
8604                              '', '', '', '', '', '', '', '', '', '',
8605                              '', '', '', '', '', '', '', '', '', '',
8606                              '', '', '', '', '', '', '', '', '', '',
8607                              '', '', '', '', '', '', '', '', '', '',
8608                              '', '', '', '', '', '', '', '', '', '',
8609                              '', '', '', '', '', '', ''
8610                              );
8611 
8612          IF (l_conc_req_id = 0) THEN
8613 
8614              print_debuginfo(l_module_name, 'Request to launch separate '
8615                  || 'remittance advice report concurrent program failed.');
8616              APP_EXCEPTION.RAISE_EXCEPTION;
8617 
8618          ELSE
8619 
8620              print_debuginfo(l_module_name, 'Separate remittance advice '
8621                  || 'report was launched successfully. '
8622                  || 'Check concurrent request id :'
8623                  || to_char(l_conc_req_id)
8624                  );
8625 
8626          END IF;
8627 
8628      END IF;
8629 
8630 
8631      /*
8632       * Launch the Positive Pay program.
8633       */
8634      IF (p_submit_postive_pay = TRUE AND l_pos_pay_format IS NOT NULL) THEN
8635 
8636          l_bool_val := FND_REQUEST.SET_OPTIONS(
8637                            numeric_characters => l_icx_numeric_characters
8638                            );
8639 
8640          l_conc_req_id := FND_REQUEST.SUBMIT_REQUEST(
8641                              'IBY',
8642                              'IBY_FD_POS_PAY_FORMAT',
8643                              '',
8644                              '',
8645                              FALSE,
8646 
8647                              '', -- do not supply profile
8648                              '', -- do not supply from pmt date
8649                              '', -- do not supply to pmt date
8650                              ''||p_instr_id||'',
8651 
8652                              '', '', '', '', '', '', '',
8653                              '', '', '', '', '', '', '', '', '', '',
8654                              '', '', '', '', '', '', '', '', '', '',
8655                              '', '', '', '', '', '', '', '', '', '',
8656                              '', '', '', '', '', '', '', '', '', '',
8657                              '', '', '', '', '', '', '', '', '', '',
8658                              '', '', '', '', '', '', '', '', '', '',
8659                              '', '', '', '', '', '', '', '', '', '',
8660                              '', '', '', '', '', '', '', '', '', '',
8661                              '', '', '', '', '', '', ''
8662                              );
8663 
8664          IF (l_conc_req_id = 0) THEN
8665 
8666              print_debuginfo(l_module_name, 'Request to launch positive '
8667                  || 'pay concurrent program failed.');
8668              APP_EXCEPTION.RAISE_EXCEPTION;
8669 
8670          ELSE
8671 
8672              print_debuginfo(l_module_name, 'Positive pay '
8673                  || 'program was launched successfully. '
8674                  || 'Check concurrent request id :'
8675                  || to_char(l_conc_req_id)
8676                  );
8677 
8678          END IF;
8679 
8680      ELSE
8681 
8682          /*
8683           * In case we did not launch the positive pay
8684           * program, mention why.
8685           */
8686          IF (p_submit_postive_pay = FALSE) THEN
8687 
8688              print_debuginfo(l_module_name, 'Positive pay '
8689                  || 'program not launched because submit '
8690                  || 'positive pay flag was not set.'
8691                  );
8692 
8693          ELSE
8694 
8695              print_debuginfo(l_module_name, 'Positive pay '
8696                  || 'program not launched because positive '
8697                  || 'pay format was not set on profile id '
8698                  || l_profile_id
8699                  );
8700 
8701          END IF;
8702 
8703      END IF;
8704 
8705      x_return_status := FND_API.G_RET_STS_SUCCESS;
8706 
8707      print_debuginfo(l_module_name, 'Returning success response ..');
8708 
8709      print_debuginfo(l_module_name, 'EXIT');
8710 
8711  EXCEPTION
8712 
8713      WHEN OTHERS THEN
8714 
8715      print_debuginfo(l_module_name, 'Exception occured when '
8716          || 'marking payments complete for payment instruction '
8717          || p_instr_id
8718          );
8719 
8720      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
8721      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
8722      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
8723 
8724      x_return_status := FND_API.G_RET_STS_ERROR;
8725 
8726      print_debuginfo(l_module_name, 'EXIT');
8727 
8728  END mark_all_pmts_complete;
8729 
8730 /*--------------------------------------------------------------------
8731  | NAME:
8732  |     transmit_pmt_instruction
8733  |
8734  |
8735  | PURPOSE:
8736  |
8737  |
8738  | PARAMETERS:
8739  |     IN
8740  |
8741  |
8742  |     OUT
8743  |
8744  |
8745  | RETURNS:
8746  |
8747  | NOTES:
8748  |     Internal API, not for public use.
8749  |
8750  *---------------------------------------------------------------------*/
8751  PROCEDURE transmit_pmt_instruction (
8752      p_instr_id         IN NUMBER,
8753      p_trans_status     IN VARCHAR2,
8754      p_error_code       IN VARCHAR2,
8755      p_error_msg        IN VARCHAR2,
8756      x_return_status    OUT NOCOPY VARCHAR2
8757      )
8758  IS
8759 
8760  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
8761                                          || '.transmit_pmt_instruction';
8762 
8763  BEGIN
8764 
8765      print_debuginfo(l_module_name, 'ENTER');
8766      FND_MSG_PUB.initialize;
8767 
8768      x_return_status := FND_API.G_RET_STS_SUCCESS;
8769 
8770      -- Update payment transaction statuses (instruction, payments, etc.)
8771      IBY_FD_POST_PICP_PROGS_PVT.Post_Results(
8772          p_instr_id,
8773          p_trans_status,
8774          'N',
8775          x_return_status
8776          );
8777 
8778      print_debuginfo(l_module_name, 'Return status from Post_Results(..): '
8779          || x_return_status
8780          );
8781 
8782      if p_trans_status = 'TRANSMISSION_FAILED' then
8783         IBY_FD_POST_PICP_PROGS_PVT.Insert_Transmission_Error(p_instr_id,
8784                                                              p_error_code,
8785                                                              p_error_msg);
8786      end if;
8787 
8788      IF (x_return_status IS NULL OR
8789          x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
8790          print_debuginfo(l_module_name, 'Returning error response: '
8791              || x_return_status
8792              );
8793      ELSE
8794          print_debuginfo(l_module_name, 'Returning success response ..');
8795      END IF;
8796 
8797      print_debuginfo(l_module_name, 'EXIT');
8798 
8799  EXCEPTION
8800      WHEN OTHERS THEN
8801 
8802      print_debuginfo(l_module_name, 'Exception occured when '
8803          || 'performing transmit for payment instruction '
8804          || p_instr_id
8805          );
8806 
8807      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
8808      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
8809      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
8810 
8811      x_return_status := FND_API.G_RET_STS_ERROR;
8812 
8813      print_debuginfo(l_module_name, 'EXIT');
8814 
8815  END transmit_pmt_instruction;
8816 
8817 /*--------------------------------------------------------------------
8818  | NAME:
8819  |     construct_callout_pkg_name
8820  |
8821  |
8822  | PURPOSE:
8823  |
8824  |
8825  | PARAMETERS:
8826  |     IN
8827  |
8828  |
8829  |     OUT
8830  |
8831  |
8832  | RETURNS:
8833  |
8834  | NOTES:
8835  |
8836  *---------------------------------------------------------------------*/
8837  FUNCTION construct_callout_pkg_name (
8838      p_app_short_name IN VARCHAR2
8839      ) RETURN VARCHAR2
8840  IS
8841 
8842  l_pkg_prefix    VARCHAR2(100);
8843  l_pkg_suffix    VARCHAR2(100) := '_PMT_CALLOUT_PKG';
8844  l_pkg_name      VARCHAR2(200);
8845 
8846  l_module_name   CONSTANT VARCHAR2(200)  := G_PKG_NAME ||
8847                                             '.construct_callout_pkg_name';
8848 
8849  BEGIN
8850 
8851      print_debuginfo(l_module_name, 'ENTER');
8852      print_debuginfo(l_module_name, 'Provided app short name: '
8853          || p_app_short_name);
8854 
8855      IF (p_app_short_name IS NULL) THEN
8856 
8857          print_debuginfo(l_module_name, 'No app short name provided. '
8858              || 'Returning null ..'
8859          );
8860 
8861          print_debuginfo(l_module_name, 'EXIT');
8862 
8863          RETURN NULL;
8864 
8865      END IF;
8866 
8867      /*
8868       * When we invoke the hook procedure in the external app,
8869       * we must use the hook signature as <package name>.<procedure name>.
8870       *
8871       * For some applications, the application short name cannot
8872       * be directly used in forming the package name.
8873       *
8874       * Example, for AP, the application short name is 'SQLAP',
8875       * but the AP packages begin as 'AP_XXXX'. Therefore,
8876       * we will convert the application short names into package
8877       * prefixes here.
8878       */
8879      CASE p_app_short_name
8880          WHEN 'SQLAP' THEN
8881              l_pkg_prefix := 'AP';
8882          ELSE
8883              l_pkg_prefix := p_app_short_name;
8884      END CASE;
8885 
8886      l_pkg_name := l_pkg_prefix || l_pkg_suffix;
8887 
8888      print_debuginfo(l_module_name, 'Constructed package name: '
8889          || l_pkg_name);
8890 
8891      print_debuginfo(l_module_name, 'EXIT');
8892 
8893      RETURN l_pkg_name;
8894 
8895  END construct_callout_pkg_name;
8896 
8897 /*--------------------------------------------------------------------
8898  | NAME:
8899  |     print_debuginfo
8900  |
8901  | PURPOSE:
8902  |
8903  |
8904  | PARAMETERS:
8905  |     IN
8906  |
8907  |
8908  |     OUT
8909  |
8910  |
8911  | RETURNS:
8912  |
8913  | NOTES:
8914  |
8915  *---------------------------------------------------------------------*/
8916  PROCEDURE print_debuginfo(
8917      p_module      IN VARCHAR2,
8918      p_debug_text  IN VARCHAR2,
8919      p_debug_level IN VARCHAR2  DEFAULT FND_LOG.LEVEL_STATEMENT
8920      )
8921  IS
8922  l_default_debug_level VARCHAR2(200) := FND_LOG.LEVEL_STATEMENT;
8923  BEGIN
8924 
8925      /*
8926       * Set the debug level to the value passed in
8927       * (provided this value is not null).
8928       */
8929      IF (p_debug_level IS NOT NULL) THEN
8930          l_default_debug_level := p_debug_level;
8931      END IF;
8932 
8933      /*
8934       * Write the debug message to the concurrent manager log file.
8935       */
8936      IF (l_default_debug_level >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
8937          iby_build_utils_pkg.print_debuginfo(p_module, p_debug_text,
8938              p_debug_level);
8939      END IF;
8940 
8941  END print_debuginfo;
8942 
8943 /*--------------------------------------------------------------------
8944  | NAME:  get_message_text
8945  |
8946  |
8947  | PURPOSE:  This function will return the transalated message text
8948  |           for validation errors stored in iby_transaction_errors
8949  |           This function should be used from the UI pages.
8950  |
8951  | PARAMETERS:
8952  |     IN  p_transaction_error_id - Transaction error id for the error
8953  |     IN  p_error_code           - Error code.  This paramester is required
8954  |                                  so that the function does not hit the
8955  |                                  iby_transaction_errors table again.
8956  |
8957  | RETURNS: translated message_text
8958  |
8959  | NOTES:
8960  |
8961  *---------------------------------------------------------------------*/
8962  FUNCTION get_message_text (p_transaction_error_id IN NUMBER,
8963                             p_error_code           IN VARCHAR2)
8964  RETURN VARCHAR2 AS
8965   l_error_mes   varchar2(4000);
8966 
8967   TYPE l_token_info_rec IS RECORD(
8968     token_name          iby_trxn_error_tokens.token_name%TYPE,
8969     token_value         iby_trxn_error_tokens.token_value%TYPE,
8970     lookup_type_source  iby_trxn_error_tokens.lookup_type_source%TYPE,
8971     meaning             fnd_lookups.meaning%TYPE);
8972 
8973   TYPE l_token_info_tab IS TABLE OF l_token_info_rec;
8974 
8975   l_token_info  l_token_info_tab;
8976 
8977   CURSOR token_info(c_trxn_error_id IN iby_transaction_errors.transaction_error_id%TYPE) IS
8978   SELECT t.token_name, t.token_value, t.lookup_type_source, l.meaning
8979     FROM iby_trxn_error_tokens t, fnd_lookups l
8980    WHERE t.transaction_error_id = (c_trxn_error_id)
8981      AND t.lookup_type_source = l.lookup_type(+)
8982      AND t.token_value = l.lookup_code(+);
8983 
8984  BEGIN
8985 
8986    IF (p_transaction_error_id IS NOT NULL AND
8987        p_error_code IS NOT NULL) THEN
8988 
8989      FND_MESSAGE.SET_NAME('IBY', p_error_code);
8990 
8991      -- get token info if any.
8992      BEGIN
8993        OPEN token_info(p_transaction_error_id);
8994        FETCH token_info
8995        BULK COLLECT INTO l_token_info;
8996        CLOSE token_info;
8997      EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
8998      END;
8999 
9000      IF (l_token_info.COUNT > 0) THEN
9001        FOR j IN l_token_info.FIRST..l_token_info.LAST LOOP
9002          IF (l_token_info(j).lookup_type_source IS NULL) THEN
9003            FND_MESSAGE.SET_TOKEN(l_token_info(j).token_name, l_token_info(j).token_value);
9004          ELSE
9005            FND_MESSAGE.SET_TOKEN(l_token_info(j).token_name, l_token_info(j).meaning);
9006          END IF;
9007 
9008        END LOOP;
9009      END IF;
9010 
9011    END IF;
9012 
9013    l_error_mes := FND_MESSAGE.GET;
9014    RETURN  l_error_mes;
9015 
9016  END get_message_text;
9017 
9018 /*--------------------------------------------------------------------
9019  | NAME:  get_message_list
9020  |
9021  |
9022  | PURPOSE:  This function will return the transalated message text
9023  |           for validation errors stored in iby_transaction_errors for an
9024  |           specific transaction.  This function will return the list of
9025  |           messages in html format.
9026  |           This function should be used from the UI pages.
9027  |
9028  | PARAMETERS:
9029  |     IN  p_transaction_id   - Transaction id (instruction, payment or document id)
9030  |     IN  p_transaction_type - Transaction type.
9031  |                              (PAYMENT, PAYMENT INSTRUCTION, etc.)
9032  |
9033  | RETURNS: translated list of messages for a transaction in html format
9034  |
9035  | NOTES:
9036  |
9037  *---------------------------------------------------------------------*/
9038  FUNCTION get_message_list (p_transaction_id   IN NUMBER,
9039                             p_transaction_type IN VARCHAR2)
9040  RETURN VARCHAR2 AS
9041 
9042    l_contact_mes   varchar2(4000);
9043    TYPE l_mes_info_rec IS RECORD (
9044      trxn_error_id       iby_transaction_errors.transaction_error_id%TYPE,
9045      error_code          iby_transaction_errors.error_code%TYPE);
9046 
9047    TYPE l_token_info_rec IS RECORD(
9048      token_name          iby_trxn_error_tokens.token_name%TYPE,
9049      token_value         iby_trxn_error_tokens.token_value%TYPE,
9050      lookup_type_source  iby_trxn_error_tokens.lookup_type_source%TYPE,
9051      meaning             fnd_lookups.meaning%TYPE);
9052 
9053    TYPE l_mes_info_tab IS TABLE OF l_mes_info_rec;
9054    TYPE l_token_info_tab IS TABLE OF l_token_info_rec;
9055 
9056    l_mes_info    l_mes_info_tab;
9057    l_token_info  l_token_info_tab;
9058 
9059    CURSOR trxn_errors IS
9060    SELECT transaction_error_id, error_code
9061      FROM iby_transaction_errors
9062     WHERE transaction_id = p_transaction_id
9063       AND transaction_type = p_transaction_type
9064       AND error_status = 'ACTIVE';
9065 
9066    CURSOR token_info(c_trxn_error_id IN iby_transaction_errors.transaction_error_id%TYPE) IS
9067    SELECT t.token_name, t.token_value, t.lookup_type_source, l.meaning
9068      FROM iby_trxn_error_tokens t, fnd_lookups l
9069     WHERE t.transaction_error_id = (c_trxn_error_id)
9070       AND t.lookup_type_source = l.lookup_type(+)
9071       AND t.token_value = l.lookup_code(+);
9072 
9073  BEGIN
9074     BEGIN
9075       OPEN trxn_errors;
9076       FETCH trxn_errors
9077       BULK COLLECT INTO l_mes_info;
9078       CLOSE trxn_errors;
9079     EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
9080     END;
9081 
9082    IF (l_mes_info.COUNT > 0) THEN
9083      l_contact_mes := '<OL>';
9084      FOR i IN l_mes_info.FIRST..l_mes_info.LAST LOOP
9085        FND_MESSAGE.SET_NAME('IBY',l_mes_info(i).error_code);
9086 
9087        -- get token info if any.
9088        BEGIN
9089          OPEN token_info(l_mes_info(i).trxn_error_id);
9090          FETCH token_info
9091          BULK COLLECT INTO l_token_info;
9092          CLOSE token_info;
9093        EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
9094        END;
9095 
9096        IF (l_token_info.COUNT > 0) THEN
9097          FOR j IN l_token_info.FIRST..l_token_info.LAST LOOP
9098            IF (l_token_info(j).lookup_type_source IS NULL) THEN
9099              FND_MESSAGE.SET_TOKEN(l_token_info(j).token_name, l_token_info(j).token_value);
9100            ELSE
9101              FND_MESSAGE.SET_TOKEN(l_token_info(j).token_name, l_token_info(j).meaning);
9102            END IF;
9103 
9104          END LOOP;
9105        END IF;
9106 
9107        l_contact_mes := l_contact_mes||'<LI>'||FND_MESSAGE.GET||'</LI>';
9108 
9109      END LOOP;
9110      l_contact_mes := l_contact_mes||'</OL>';
9111 
9112    END IF;
9113    RETURN l_contact_mes;
9114  END get_message_list;
9115 
9116 /*--------------------------------------------------------------------
9117  | NAME:
9118  |     perform_check_print
9119  |
9120  | PURPOSE: This procedure calls the IBY_CHECKNUMBER_PUB.performCheckNumbering
9121  |          procedure to lock the payment document and number the payments
9122  |
9123  |
9124  | PARAMETERS:
9125  |     IN  p_instruction_id    -  Payment Instruction to print
9126  |     IN  p_pmt_document_id   -  Payment document id used to print
9127  |                                payment instruction
9128  |     IN  p_printer_name      -  Printer defined by the user
9129  |
9130  |     OUT x_return_status     -  Return status (S, E, U)
9131  |     OUT x_return_message    -  This error code will indicate if there
9132  |                                is any error during the numbering of the
9133  |                                payment instruction or if the payment
9134  |                                document cannot be locked.
9135  |
9136  | NOTES:  This procedure is only called from the Print UI since it will
9137  |         number the complete payment instruction.
9138  |
9139  | IMPORTANT NOTE:
9140  |         This procedure originally did not perform a COMMIT. However,
9141  |         after unexpected behaviors started occuring after lock/unlock
9142  |         APIs for handling intermediate statuses were introduced.
9143  |
9144  |         These APIs stamp a conc request id against a pmt entity
9145  |         (such as a pmt request or pmt instruction) and perform a commit.
9146  |
9147  |         If that underlying pmt entity has already been updated, but not
9148  |         committed a deadlock condition ensues and this API exits with
9149  |         error 'ORA-00060: deadlock detected while waiting for resource'.
9150  |
9151  |         Therefore, a COMMIT is performed after the payment instruction
9152  |         is updated in this method. The Post-PICP API will lock the
9153  |         same payment instruction by stamping the conc request id on it.
9154  |         This operation does not fail now because the changes made to the
9155  |         payment instruction have already been committed.
9156  |
9157  |         See bug 5195769 for an example of this deadlock scenario.
9158  |
9159  *---------------------------------------------------------------------*/
9160  PROCEDURE perform_check_print(
9161              p_instruction_id    IN NUMBER,
9162              p_pmt_document_id   IN NUMBER,
9163              p_printer_name      IN VARCHAR2,
9164              x_return_status     IN OUT NOCOPY VARCHAR2,
9165              x_return_message    IN OUT NOCOPY VARCHAR2) IS
9166 
9167  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME|| '.perform_check_print';
9168  l_instr_status IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_status%TYPE;
9169 
9170  l_error_code   VARCHAR2(3000);
9171 
9172  l_msg_count    NUMBER;
9173  l_msg_data     VARCHAR2(4000);
9174 
9175  BEGIN
9176 
9177      print_debuginfo(l_module_name, 'ENTER');
9178 
9179      FND_MSG_PUB.initialize;
9180 
9181      /*
9182       * Get the status of the provided payment instruction.
9183       */
9184      BEGIN
9185 
9186          SELECT
9187              payment_instruction_status
9188          INTO
9189              l_instr_status
9190          FROM
9191              IBY_PAY_INSTRUCTIONS_ALL
9192          WHERE
9193              payment_instruction_id = p_instruction_id
9194          ;
9195 
9196      EXCEPTION
9197          WHEN OTHERS THEN
9198 
9199              print_debuginfo(l_module_name, 'Fatal: Exception occured '
9200                  || 'when attempting to get status of payment '
9201                  || 'instruction '
9202                  || p_instruction_id
9203                  || '. Aborting ..'
9204                  );
9205 
9206              l_error_code := 'IBY_INS_NOT_FOUND';
9207              FND_MESSAGE.set_name('IBY', l_error_code);
9208 
9209              FND_MESSAGE.SET_TOKEN('INS_ID',
9210                  p_instruction_id,
9211                  FALSE);
9212              FND_MSG_PUB.add;
9213              x_return_message := FND_MESSAGE.get;
9214 
9215              /*
9216               * Propogate exception.
9217               */
9218              RAISE;
9219      END;
9220 
9221      print_debuginfo(l_module_name, 'Status of payment instruction '
9222          || p_instruction_id
9223          || ' is '
9224          || l_instr_status
9225          );
9226 
9227      /*
9228       * First check whether the provided payment instruction
9229       * is in the right status.
9230       */
9231      IF (l_instr_status <> INS_STATUS_READY_TO_PRINT  AND
9232          l_instr_status <> INS_STATUS_READY_TO_FORMAT AND
9233          l_instr_status <> INS_STATUS_FORMAT_TO_PRINT) THEN
9234 
9235              print_debuginfo(l_module_name, 'Payment instruction '
9236                  || p_instruction_id
9237                  || ' is in status '
9238                  || l_instr_status
9239                  || '. Cannot print this instruction ..'
9240                  );
9241 
9242              l_error_code := 'IBY_INS_NOT_PRINT_STATUS';
9243              FND_MESSAGE.set_name('IBY', l_error_code);
9244 
9245              FND_MESSAGE.SET_TOKEN('INS_ID',
9246                  p_instruction_id,
9247                  FALSE);
9248 
9249              FND_MESSAGE.SET_TOKEN('BAD_STATUS',
9250                  l_instr_status,
9251                  FALSE);
9252               FND_MSG_PUB.add;
9253              x_return_message := FND_MESSAGE.get;
9254 
9255              APP_EXCEPTION.RAISE_EXCEPTION;
9256 
9257      END IF;
9258 
9259      /*
9260       * If we reached here, the payment instruction is the
9261       * correct status.
9262       *
9263       * Update the printer associated with this payment instruction
9264       * with the provided printer name. The Post-PICP modules
9265       * will use this printer for printing the checks.
9266       */
9267      UPDATE
9268          IBY_PAY_INSTRUCTIONS_ALL
9269      SET
9270          printer_name = p_printer_name
9271      WHERE
9272          payment_instruction_id = p_instruction_id
9273      ;
9274 
9275      /*
9276       * Fix for bug 5195769:
9277       *
9278       * This commit is necessary. Otherwise a deadlocked
9279       * condition is created when we try to update the same
9280       * payment instruction with the concurrent request id
9281       * (for handling intermediate statuses).
9282       */
9283      COMMIT;
9284 
9285      /*
9286       * Lastly invoke numbering and/or printing depending
9287       * upon the status of the payment instruction.
9288       */
9289      IF (l_instr_status = INS_STATUS_FORMAT_TO_PRINT) THEN
9290 
9291          /*
9292           * This means that this payment instruction is
9293           * already formatted. Only printing is required.
9294           */
9295          BEGIN
9296 
9297              print_debuginfo(l_module_name, 'Going to invoke '
9298                  || 'extract and format operation for payment instruction '
9299                  || p_instruction_id
9300                  );
9301 
9302              IBY_FD_POST_PICP_PROGS_PVT.
9303                  Run_Post_PI_Programs(
9304                      p_instruction_id,
9305                      'N'
9306                      );
9307 
9308              print_debuginfo(l_module_name, 'Extract and format '
9309                  || 'operation completed successfully.'
9310                  );
9311 
9312          EXCEPTION
9313              WHEN OTHERS THEN
9314 
9315              print_debuginfo(l_module_name, 'Extract and '
9316                  || 'format operation generated '
9317                  || 'exception for payment instruction '
9318                  || p_instruction_id
9319                  );
9320 
9321              l_error_code := 'IBY_INS_BACKEND_ERROR';
9322              FND_MESSAGE.set_name('IBY', l_error_code);
9323 
9324              FND_MESSAGE.SET_TOKEN('INS_ID',
9325                  p_instruction_id,
9326                  FALSE);
9327               FND_MSG_PUB.add;
9328              x_return_message := FND_MESSAGE.get;
9329 
9330              /*
9331               * Propagate exception.
9332               */
9333              RAISE;
9334 
9335          END;
9336 
9337      ELSE
9338 
9339          /*
9340           * This means that this payment instruction is not
9341           * yet numbered. Invoke the numbering flow.
9342           */
9343          IBY_CHECKNUMBER_PUB.performCheckNumbering(
9344              p_instruction_id,
9345              p_pmt_document_id,
9346              NULL,
9347              x_return_status,
9348              x_return_message,
9349              l_msg_count,
9350              l_msg_data
9351              );
9352 
9353          IF (x_return_status IS NULL OR
9354 	     x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9355 
9356              print_debuginfo(l_module_name, 'Check numbering '
9357                  || 'operation failed for payment instruction '
9358                  || p_instruction_id
9359                  || ' with error message: '
9360                  || x_return_message
9361                  );
9362 
9363              APP_EXCEPTION.RAISE_EXCEPTION;
9364 
9365          END IF;
9366 
9367          /*
9368           * After numbering, invoke the printing flow.
9369           */
9370          BEGIN
9371 
9372              print_debuginfo(l_module_name, 'Invoking extract and '
9373                  || 'format operation for payment instruction '
9374                  || p_instruction_id
9375                  );
9376 
9377              IBY_FD_POST_PICP_PROGS_PVT.
9378                  Run_Post_PI_Programs(
9379                      p_instruction_id,
9380                      'N'
9381                      );
9382 
9383              print_debuginfo(l_module_name, 'Extract and format '
9384                  || 'operation completed successfully'
9385                  );
9386 
9387          EXCEPTION
9388              WHEN OTHERS THEN
9389 
9390              l_error_code := 'IBY_INS_BACKEND_ERROR';
9391              FND_MESSAGE.set_name('IBY', l_error_code);
9392 
9393              FND_MESSAGE.SET_TOKEN('INS_ID',
9394                  p_instruction_id,
9395                  FALSE);
9396              FND_MSG_PUB.add;
9397              x_return_message := FND_MESSAGE.get;
9398 
9399              print_debuginfo(l_module_name, 'Extract and '
9400                  || 'format operation generated '
9401                  || 'exception for payment instruction '
9402                  || p_instruction_id
9403                  );
9404 
9405              /*
9406               * Propagate exception.
9407               */
9408              RAISE;
9409 
9410          END;
9411 
9412      END IF;
9413 
9414      /*
9415       * Return success.
9416       */
9417      print_debuginfo(l_module_name, 'Returning success response ..');
9418      x_return_status := FND_API.G_RET_STS_SUCCESS;
9419 
9420      print_debuginfo(l_module_name, 'EXIT');
9421 
9422  EXCEPTION
9423      WHEN OTHERS THEN
9424 
9425      print_debuginfo(l_module_name, 'Exception occured when '
9426          || 'performing check print'
9427          );
9428 
9429      print_debuginfo(l_module_name, 'SQL code: '
9430          || SQLCODE);
9431      print_debuginfo(l_module_name, 'SQL err msg: '
9432          || SQLERRM);
9433      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
9434 
9435      print_debuginfo(l_module_name, 'Returning failure response .. '
9436          );
9437 
9438      /*
9439       * The error message would have already been set.
9440       * Just set the error status here.
9441       */
9442      x_return_status := FND_API.G_RET_STS_ERROR;
9443 
9444      print_debuginfo(l_module_name, 'EXIT');
9445 
9446  END perform_check_print;
9447 
9448 /*--------------------------------------------------------------------
9449  | NAME:
9450  |     checkIfDocUsed
9451  |
9452  | PURPOSE:
9453  |     Checks if a given paper document number has already been used.
9454  |     A used paper document implies that a check has already been
9455  |     printed for the given paper document number.
9456  |
9457  |
9458  | PARAMETERS:
9459  |     IN
9460  |       p_paper_doc_num   - Paper document number (check number) to verify.
9461  |
9462  |       p_pmt_document_id - Payment document id (check stock) that this
9463  |                           paper document number belongs to.
9464  |     OUT
9465  |       NONE
9466  |
9467  | RETURNS:
9468  |       TRUE  - if the paper document number has already been used.
9469  |       FALSE - if the paper document number has not been used.
9470  |
9471  | NOTES:
9472  |
9473  *---------------------------------------------------------------------*/
9474  FUNCTION checkIfDocUsed(
9475      p_paper_doc_num     IN NUMBER,
9476      p_pmt_document_id   IN NUMBER
9477      ) RETURN BOOLEAN
9478  IS
9479 
9480  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
9481                                          || '.checkIfDocUsed';
9482 
9483  l_flag BOOLEAN;
9484  l_used_paper_doc_number NUMBER := 0;
9485 
9486  BEGIN
9487 
9488      /*
9489       * Check if this paper document number has already
9490       * been used by searching the the IBY_USED_PAYMENT_DOCS
9491       * table.
9492       */
9493      SELECT
9494          used_document_number
9495      INTO
9496          l_used_paper_doc_number
9497      FROM
9498          IBY_USED_PAYMENT_DOCS
9499      WHERE
9500          payment_document_id  = p_pmt_document_id     AND
9501          used_document_number = p_paper_doc_num AND
9502 	 document_use <> 'SKIPPED'
9503      ;
9504 
9505      /*
9506       * If we reached here, it means that a row has been
9507       * found in the IBY_USED_PAYMENT_DOCS table for the
9508       * given (paper doc number, payment document id)
9509       * combination. This means that the paper document
9510       * is used.
9511       *
9512       * Set the return flag to true.
9513       */
9514      l_flag := TRUE;
9515 
9516      print_debuginfo(l_module_name, 'Returning TRUE.');
9517      RETURN l_flag;
9518 
9519  EXCEPTION
9520 
9521      WHEN NO_DATA_FOUND THEN
9522 
9523          /* now rows means success */
9524          print_debuginfo(l_module_name, 'Paper document '
9525              || 'number '
9526              || p_paper_doc_num
9527              || ' is unused.'
9528              );
9529 
9530          /* set the return flag to false */
9531          l_flag := FALSE;
9532 
9533          print_debuginfo(l_module_name, 'Returning FALSE.');
9534          RETURN l_flag;
9535 
9536      WHEN OTHERS THEN
9537 
9538          print_debuginfo(l_module_name, 'Exception occured when '
9539              || 'attempting to get details of paper document '
9540              || p_paper_doc_num
9541              || ' from IBY_USED_PAYMENT_DOCS table.'
9542              );
9543 
9544          print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
9545          print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
9546 
9547          print_debuginfo(l_module_name, 'Unexpected error. '
9548              || 'Raising exception ..');
9549 
9550          APP_EXCEPTION.RAISE_EXCEPTION;
9551 
9552  END checkIfDocUsed;
9553 
9554 /*--------------------------------------------------------------------
9555  | NAME:
9556  |     insert_conc_request
9557  |
9558  | PURPOSE:
9559  |     Inserts a given concurrent request id into the
9560  |     IBY_PROCESS_CONC_REQUESTS table for audit purposes.
9561  |
9562  | PARAMETERS:
9563  |     IN
9564  |     p_object_id         The id of the payment entity. This can be
9565  |                         a payment id, a payment request id or a payment
9566  |                         instruction id.
9567  |
9568  |     p_object_type       The type of the payment entity. This can be
9569  |                         one of the following
9570  |                             PAYMENT
9571  |                             PAYMENT_REQUEST
9572  |                             PAYMENT_INSTRUCTION
9573  |
9574  |     p_conc_request_id   The concurrent request id.
9575  |
9576  |     p_completed_flag    Flag indicating whether the concurrent request
9577  |                         has completed.
9578  |
9579  |     OUT
9580  |     x_return_status     Return status (S, E, U)
9581  |
9582  | RETURNS:
9583  |
9584  | NOTES:
9585  |
9586  *---------------------------------------------------------------------*/
9587  PROCEDURE insert_conc_request(
9588              p_object_id         IN NUMBER,
9589              p_object_type       IN VARCHAR2,
9590              p_conc_request_id   IN NUMBER,
9591              p_completed_flag    IN VARCHAR2 DEFAULT 'N',
9592              x_return_status     IN OUT NOCOPY VARCHAR2
9593              )
9594  IS
9595 
9596  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME|| '.insert_conc_request';
9597 
9598  BEGIN
9599 
9600      print_debuginfo(l_module_name, 'ENTER');
9601 
9602      print_debuginfo(l_module_name, 'Inserting conc request id '
9603          || p_conc_request_id
9604          || ' into IBY_PROCESS_CONC_REQUESTS for object id '
9605          || p_object_id
9606          || ' with object type '
9607          || p_object_type
9608          );
9609 
9610      INSERT INTO IBY_PROCESS_CONC_REQUESTS
9611          (
9612          OBJECT_ID,             /* 1 */
9613          OBJECT_TYPE,
9614          REQUEST_ID,
9615          COMPLETED_FLAG,
9616          CREATED_BY,            /* 5 */
9617          CREATION_DATE,
9618          LAST_UPDATED_BY,
9619          LAST_UPDATE_DATE,
9620          LAST_UPDATE_LOGIN,
9621          OBJECT_VERSION_NUMBER  /* 10 */
9622          )
9623          VALUES
9624          (
9625          p_object_id,           /* 1 */
9626          p_object_type,
9627          p_conc_request_id,
9628          p_completed_flag,
9629          fnd_global.user_id,    /* 5 */
9630          sysdate,
9631          fnd_global.user_id,
9632          sysdate,
9633          fnd_global.login_id,
9634          1                      /* 10 */
9635          )
9636          ;
9637 
9638      x_return_status := FND_API.G_RET_STS_SUCCESS;
9639      print_debuginfo(l_module_name, 'EXIT');
9640 
9641  EXCEPTION
9642      WHEN OTHERS THEN
9643 
9644          print_debuginfo(l_module_name, 'Exception occured when '
9645              || 'inserting conc request id '
9646              || p_conc_request_id
9647              || ' into IBY_PROCESS_CONC_REQUESTS for object id '
9648              || p_object_id
9649              || ' with object type '
9650              || p_object_type
9651              || '.'
9652              );
9653 
9654          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
9655          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
9656 
9657          FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
9658          x_return_status := FND_API.G_RET_STS_ERROR;
9659 
9660          print_debuginfo(l_module_name, 'EXIT');
9661 
9662  END insert_conc_request;
9663 
9664 /*--------------------------------------------------------------------
9665  | NAME:
9666  |     lock_pmt_entity
9667  |
9668  | PURPOSE:
9669  |     Stamps the given payment entity with the given concurrent
9670  |     request id to lock the entity.
9671  |
9672  |     The IBY UI will not allow any follow on operation on a payment
9673  |     entity that is locked.
9674  |
9675  |     Locking/unlocking is the mechanism by which to preserve
9676  |     data integrity of payment entities which are in transient
9677  |     statuses.
9678  |
9679  |     This method also inserts the provided concurrent request into
9680  |     IBY_PROCESS_CONC_REQUESTS table for audit purposes.
9681  |
9682  | PARAMETERS:
9683  |     IN
9684  |     p_object_id         The id of the payment entity. This can be
9685  |                         a payment id, a payment request id or a payment
9686  |                         instruction id.
9687  |
9688  |     p_object_type       The type of the payment entity. This can be
9689  |                         one of the following
9690  |                             PAYMENT
9691  |                             PAYMENT_REQUEST
9692  |                             PAYMENT_INSTRUCTION
9693  |
9694  |     p_conc_request_id   The concurrent request id to stamp the payment
9695  |                         entity with. If NULL is provided, the value of
9696  |                         FND_GLOBAL.CONC_REQUEST_ID will be used.
9697  |
9698  |     OUT
9699  |     x_return_status     Return status (S, E, U)
9700  |
9701  | RETURNS:
9702  |
9703  | NOTES:
9704  |     This method is implemented as an autonomous transaction
9705  |     so that a COMMIT can be performed on the payment entity
9706  |     without side effects on the main transaction.
9707  |
9708  *---------------------------------------------------------------------*/
9709  PROCEDURE lock_pmt_entity(
9710              p_object_id         IN NUMBER,
9711              p_object_type       IN VARCHAR2,
9712              p_conc_request_id   IN NUMBER DEFAULT NULL,
9713              x_return_status     IN OUT NOCOPY VARCHAR2
9714              )
9715  IS
9716  PRAGMA AUTONOMOUS_TRANSACTION;
9717 
9718  l_module_name     CONSTANT VARCHAR2(200) := G_PKG_NAME|| '.lock_pmt_entity';
9719  l_conc_request_id NUMBER;
9720 
9721  BEGIN
9722 
9723      print_debuginfo(l_module_name, 'ENTER');
9724 
9725      FND_MSG_PUB.initialize;
9726 
9727      print_debuginfo(l_module_name, 'Input params - '
9728          || 'object id: '
9729          || p_object_id
9730          || ', object type: '
9731          || p_object_type
9732          );
9733 
9734      /*
9735       * STEP 1:
9736       *
9737       * If the concurrent request id has not been provided,
9738       * derive it from the current context.
9739       */
9740      IF (p_conc_request_id IS NULL) THEN
9741 
9742          print_debuginfo(l_module_name, 'Concurrent request id not '
9743              || 'provided. Deriving from context ..'
9744              );
9745 
9746          l_conc_request_id := FND_GLOBAL.conc_request_id;
9747 
9748      ELSE
9749 
9750          print_debuginfo(l_module_name, 'Concurrent request id '
9751              || 'provided as input param: '
9752              || p_conc_request_id
9753              );
9754 
9755          l_conc_request_id := p_conc_request_id;
9756 
9757      END IF;
9758 
9759      /*
9760       * STEP 2:
9761       *
9762       * Stamp the given entity with the provided concurrent request id.
9763       */
9764      IF (p_object_type = 'PAYMENT_REQUEST') THEN
9765 
9766          UPDATE
9767              IBY_PAY_SERVICE_REQUESTS req
9768          SET
9769              req.request_id = l_conc_request_id
9770          WHERE
9771              req.payment_service_request_id = p_object_id
9772          ;
9773 
9774      ELSIF (p_object_type = 'PAYMENT_INSTRUCTION') THEN
9775 
9776          UPDATE
9777              IBY_PAY_INSTRUCTIONS_ALL inst
9778          SET
9779              inst.request_id = l_conc_request_id
9780          WHERE
9781              inst.payment_instruction_id = p_object_id
9782          ;
9783 
9784      ELSIF (p_object_type = 'PAYMENT') THEN
9785 
9786          UPDATE
9787              IBY_PAYMENTS_ALL pmt
9788          SET
9789              pmt.request_id = l_conc_request_id
9790          WHERE
9791              pmt.payment_id = p_object_id
9792          ;
9793 
9794      ELSE
9795 
9796          print_debuginfo(l_module_name, 'Unknown payment entity type '
9797              || p_object_type
9798              || ' provided. Raising exception .. '
9799              );
9800 
9801          APP_EXCEPTION.RAISE_EXCEPTION;
9802 
9803      END IF;
9804 
9805      /*
9806       * STEP 3:
9807       *
9808       * Insert concurrent request into audit table.
9809       */
9810 
9811      print_debuginfo(l_module_name, 'Inserting cp into audit table');
9812 
9813      insert_conc_request(
9814              p_object_id,
9815              p_object_type,
9816              l_conc_request_id,
9817              'N',
9818              x_return_status
9819              );
9820 
9821      print_debuginfo(l_module_name, 'Return status from '
9822          || 'insert_conc_request(..) call = '
9823          || x_return_status
9824          );
9825 
9826 
9827      IF (x_return_status IS NULL OR
9828          x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9829 
9830          print_debuginfo(l_module_name, 'Audit of conc request '
9831              || l_conc_request_id
9832              || ' failed. Returning error response .. '
9833              );
9834 
9835          /*
9836           * Undo any database changes made in this method.
9837           */
9838          ROLLBACK;
9839 
9840          print_debuginfo(l_module_name, 'EXIT');
9841          RETURN;
9842 
9843      END IF;
9844 
9845      /*
9846       * STEP 4:
9847       *
9848       * Finally, perform a COMMIT to lock the payment entity
9849       * with a concurrent request id.
9850       */
9851      COMMIT;
9852 
9853      x_return_status := FND_API.G_RET_STS_SUCCESS;
9854      print_debuginfo(l_module_name, 'Returning success response ..');
9855 
9856      print_debuginfo(l_module_name, 'EXIT');
9857 
9858  EXCEPTION
9859      WHEN OTHERS THEN
9860 
9861      print_debuginfo(l_module_name, 'Exception occured when locking '
9862          || 'pmt entity.');
9863 
9864      print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
9865      print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
9866 
9867      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
9868 
9869      ROLLBACK;
9870 
9871      x_return_status := FND_API.G_RET_STS_ERROR;
9872 
9873      print_debuginfo(l_module_name, 'EXIT');
9874 
9875  END lock_pmt_entity;
9876 
9877 /*--------------------------------------------------------------------
9878  | NAME:
9879  |     unlock_pmt_entity
9880  |
9881  | PURPOSE:
9882  |     Nulls out the concurrent request id on given payment entity
9883  |     to unlock the entity.
9884  |
9885  |     The IBY UI will not allow any follow on operation on a payment
9886  |     entity that is locked.
9887  |
9888  |     Locking/unlocking is the mechanism by which to preserve
9889  |     data integrity of payment entities which are in transient
9890  |     statuses.
9891  |
9892  | PARAMETERS:
9893  |     IN
9894  |     p_object_id         The id of the payment entity. This can be
9895  |                         a payment id, a payment request id or a payment
9896  |                         instruction id.
9897  |
9898  |     p_object_type       The type of the payment entity. This can be
9899  |                         one of the following
9900  |                             PAYMENT
9901  |                             PAYMENT_REQUEST
9902  |                             PAYMENT_INSTRUCTION
9903  |
9904  |     OUT
9905  |     x_return_status     Return status (S, E, U)
9906  |
9907  | RETURNS:
9908  |
9909  | NOTES:
9910  |     This method is implemented as an autonomous transaction
9911  |     so that a COMMIT can be performed on the payment entity
9912  |     without side effects on the main transaction.
9913  |
9914  *---------------------------------------------------------------------*/
9915  PROCEDURE unlock_pmt_entity(
9916              p_object_id         IN NUMBER,
9917              p_object_type       IN VARCHAR2,
9918              x_return_status     IN OUT NOCOPY VARCHAR2
9919              )
9920  IS
9921  PRAGMA AUTONOMOUS_TRANSACTION;
9922 
9923  l_module_name     CONSTANT VARCHAR2(200) := G_PKG_NAME|| '.unlock_pmt_entity';
9924 
9925  BEGIN
9926 
9927      print_debuginfo(l_module_name, 'ENTER');
9928 
9929      print_debuginfo(l_module_name, 'Input params - '
9930          || 'object id: '
9931          || p_object_id
9932          || ', object type: '
9933          || p_object_type
9934          );
9935 
9936      /*
9937       * STEP 1:
9938       *
9939       * Unstamp the given entity with the provided concurrent request id.
9940       */
9941      IF (p_object_type = 'PAYMENT_REQUEST') THEN
9942 
9943          UPDATE
9944              IBY_PAY_SERVICE_REQUESTS req
9945          SET
9946              req.request_id = NULL
9947          WHERE
9948              req.payment_service_request_id = p_object_id
9949          ;
9950 
9951      ELSIF (p_object_type = 'PAYMENT_INSTRUCTION') THEN
9952 
9953          UPDATE
9954              IBY_PAY_INSTRUCTIONS_ALL inst
9955          SET
9956              inst.request_id = NULL
9957          WHERE
9958              inst.payment_instruction_id = p_object_id
9959          ;
9960 
9961      ELSIF (p_object_type = 'PAYMENT') THEN
9962 
9963          UPDATE
9964              IBY_PAYMENTS_ALL pmt
9965          SET
9966              pmt.request_id = NULL
9967          WHERE
9968              pmt.payment_id = p_object_id
9969          ;
9970 
9971      ELSE
9972 
9973          print_debuginfo(l_module_name, 'Unknown payment entity type '
9974              || p_object_type
9975              || ' provided. Raising exception .. '
9976              );
9977 
9978          APP_EXCEPTION.RAISE_EXCEPTION;
9979 
9980      END IF;
9981 
9982      /*
9983       * STEP 3:
9984       *
9985       * Finally, perform a COMMIT to unlock the payment entity
9986       * with a concurrent request id.
9987       */
9988      COMMIT;
9989 
9990      x_return_status := FND_API.G_RET_STS_SUCCESS;
9991      print_debuginfo(l_module_name, 'Returning success response ..');
9992 
9993      print_debuginfo(l_module_name, 'EXIT');
9994 
9995  EXCEPTION
9996      WHEN OTHERS THEN
9997 
9998      print_debuginfo(l_module_name, 'Exception occured when unlocking '
9999          || 'pmt entity.');
10000 
10001      print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
10002      print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
10003 
10004      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
10005 
10006      ROLLBACK;
10007 
10008      x_return_status := FND_API.G_RET_STS_ERROR;
10009 
10010      print_debuginfo(l_module_name, 'EXIT');
10011 
10012  END unlock_pmt_entity;
10013 
10014 /*--------------------------------------------------------------------
10015  | NAME:
10016  |     populatePaymentFunctions
10017  |
10018  |
10019  | PURPOSE:
10020  |     Populate the payment functions that user has access to
10021  |
10022  | PARAMETERS:
10023  |     IN
10024  |
10025  |
10026  |     OUT
10027  |
10028  |
10029  | RETURNS:
10030  |
10031  | NOTES:
10032  |
10033  *---------------------------------------------------------------------*/
10034  PROCEDURE populatePaymentFunctions(
10035              x_return_status     IN OUT NOCOPY VARCHAR2,
10036              x_return_message    IN OUT NOCOPY VARCHAR2) IS
10037 
10038  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
10039                                          || '.populatePaymentFunctions';
10040 l_func varchar2(30);
10041 l_bool boolean;
10042 l_count number;
10043 cursor c_pay_function is
10044 select lookup_code
10045 from fnd_lookups
10046 where lookup_type='IBY_PAYMENT_FUNCTIONS';
10047 
10048 begin
10049 
10050 FND_MSG_PUB.initialize;
10051 
10052 -- first check whether the payment function is populated or not
10053   begin
10054    select count(1)
10055     into l_count
10056    from IBY_USER_PAY_FUNS_GT;
10057    exception
10058       WHEN OTHERS THEN
10059 
10060          /* now rows means success */
10061          print_debuginfo(l_module_name, 'Exception in select ');
10062           null;
10063      end;
10064 
10065    if(l_count<>0) then
10066         x_return_status := FND_API.G_RET_STS_SUCCESS;
10067         return;
10068    end if;
10069 
10070     OPEN  c_pay_function;
10071     loop
10072      FETCH c_pay_function INTO l_func;
10073      exit when c_pay_function%NOTFOUND;
10074       -- check security
10075     l_bool := fnd_function.test_instance(
10076    'IBY_' || l_func,
10077    null,
10078    null,
10079    null,
10080    null,
10081    null,
10082    null,
10083    fnd_global.user_name);
10084 
10085    if(l_bool) then
10086    --print_debuginfo(l_module_name, 'User has access to:' || l_func);
10087     insert into IBY_USER_PAY_FUNS_GT(payment_function)
10088     values(l_func);
10089 	end if;
10090       end loop;
10091       close c_pay_function;
10092 
10093    x_return_status := FND_API.G_RET_STS_SUCCESS;
10094         return;
10095    EXCEPTION
10096 
10097     WHEN OTHERS THEN
10098      print_debuginfo(l_module_name, 'SQL err msg: '
10099        || SQLERRM);
10100      print_debuginfo(l_module_name, 'Returning failure response .. '
10101        );
10102      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
10103      /*
10104       * The error message would have already been set.
10105       * Just set the error status here.
10106       */
10107      x_return_status := FND_API.G_RET_STS_ERROR;
10108 
10109      print_debuginfo(l_module_name, 'EXIT');
10110 
10111 end populatePaymentFunctions;
10112 
10113 /*--------------------------------------------------------------------
10114  | NAME:
10115  |     checkUserAccess
10116  |
10117  |
10118  | PURPOSE:
10119  |     Check whether the user has access to all the org. or payment function
10120  |      of a particular object.
10121  |
10122  | PARAMETERS:
10123  |     IN
10124  |
10125  |
10126  |     OUT
10127  |
10128  |
10129  | RETURNS:
10130  |
10131  | NOTES:
10132  |
10133  *---------------------------------------------------------------------*/
10134 PROCEDURE checkUserAccess(
10135              p_object_id         IN NUMBER,
10136              p_object_type       IN VARCHAR2,
10137              x_access_flag       IN OUT NOCOPY VARCHAR2,
10138              x_return_status     IN OUT NOCOPY VARCHAR2,
10139              x_return_message    IN OUT NOCOPY VARCHAR2)
10140 IS
10141  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
10142                                          || '.checkUserAccess';
10143 
10144  l_function_count NUMBER:=0;
10145  l_org_count NUMBER:=0;
10146  l_msg_count NUMBER:=0;
10147  l_message_code VARCHAR2(30);
10148 begin
10149 
10150 -- initiate the return parameter
10151 print_debuginfo(l_module_name, 'ENTER');
10152 
10153 FND_MSG_PUB.initialize;
10154 populatePaymentFunctions(x_return_status, x_return_message);
10155 x_access_flag:='N';
10156 
10157  /* Initialize return status */
10158 x_return_status := FND_API.G_RET_STS_SUCCESS;
10159 
10160 select count(1)
10161 into l_function_count
10162 from iby_process_functions pfun
10163 where object_id=p_object_id
10164 and   object_type=p_object_type
10165 and pfun.payment_function not in
10166        (select payment_function
10167         from IBY_USER_PAY_FUNS_GT
10168         );
10169 print_debuginfo(l_module_name, 'Number of Missing Payment Function:' ||l_function_count);
10170 
10171 select count(1)
10172 into l_org_count
10173 from iby_process_orgs porg
10174 where object_id=p_object_id
10175 and   object_type=p_object_type
10176 and porg.org_id not in
10177        (select  organization_id
10178         from ce_security_profiles_v cep
10179         where cep.organization_type=porg.org_type
10180         );
10181 print_debuginfo(l_module_name, 'Number of Missing Org:' ||l_org_count);
10182 
10183 -- check the user access
10184 if(l_function_count<>0 OR l_org_count <>0) THEN
10185 
10186 print_debuginfo(l_module_name, 'User doesnt have full access to the payment request or payment instruction');
10187 
10188   -- return error message for different object type
10189 
10190    if(p_object_type='PAYMENT_REQUEST') then
10191      l_message_code :='IBY_FD_ACCESS_REQUEST_ERROR';
10192    else
10193      l_message_code :='IBY_FD_ACCESS_INSTR_ERROR';
10194 
10195    end if;
10196 
10197 
10198     FND_MESSAGE.set_name('IBY', l_message_code);
10199     FND_MSG_PUB.add;
10200 
10201 x_return_status := FND_API.G_RET_STS_ERROR;
10202 
10203 FND_MSG_PUB.Count_And_Get(
10204                           p_encoded => FND_API.G_FALSE,
10205                           p_count   => l_msg_count,
10206                           p_data    => x_return_message
10207                           );
10208 
10209              print_debuginfo(l_module_name, 'Returning error response ..');
10210              print_debuginfo(l_module_name, 'Error count:' || l_msg_count);
10211              print_debuginfo(l_module_name, 'Error Text:' || x_return_message);
10212              print_debuginfo(l_module_name, 'EXIT');
10213 end if;
10214 
10215 EXCEPTION
10216 WHEN OTHERS THEN
10217    print_debuginfo(l_module_name, 'SQL err msg: '
10218        || SQLERRM);
10219      print_debuginfo(l_module_name, 'Returning failure response .. '
10220        );
10221      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
10222      /*
10223       * The error message would have already been set.
10224       * Just set the error status here.
10225       */
10226      x_return_status := FND_API.G_RET_STS_ERROR;
10227 
10228      print_debuginfo(l_module_name, 'EXIT');
10229 end checkUserAccess;
10230 
10231 /*--------------------------------------------------------------------
10232  | NAME:
10233  |     checkIfAllPmtsTerminated
10234  |
10235  | PURPOSE:
10236  |     Checks if all payments of a given payment instruction
10237  |     have been terminated.
10238  |
10239  | PARAMETERS:
10240  |     IN
10241  |       p_instr_id   - Payment instruction id to verify.
10242  |
10243  |     OUT
10244  |       NONE
10245  |
10246  | RETURNS:
10247  |       TRUE  - if all payments have been terminated.
10248  |       FALSE - if at least one non-terminated payment exists.
10249  |
10250  | NOTES:
10251  |
10252  *---------------------------------------------------------------------*/
10253  FUNCTION checkIfAllPmtsTerminated(
10254      p_instr_id          IN NUMBER
10255      ) RETURN BOOLEAN
10256  IS
10257 
10258  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
10259                                          || '.checkIfAllPmtsTerminated';
10260 
10261  l_flag             BOOLEAN := FALSE;
10262 
10263  l_all_pmts_count   NUMBER;
10264  l_term_pmts_count  NUMBER;
10265 
10266  BEGIN
10267 
10268      print_debuginfo(l_module_name, 'ENTER');
10269 
10270      SELECT
10271          COUNT(*)
10272      INTO
10273          l_all_pmts_count
10274      FROM
10275          IBY_PAYMENTS_ALL pmt
10276      WHERE
10277          pmt.payment_instruction_id = p_instr_id
10278      ;
10279 
10280 
10281      print_debuginfo(l_module_name, 'Count of all payments in pmt instr '
10282          || p_instr_id
10283          || ' = '
10284          || l_all_pmts_count
10285          );
10286 
10287      SELECT
10288          COUNT(*)
10289      INTO
10290          l_term_pmts_count
10291      FROM
10292          IBY_PAYMENTS_ALL pmt
10293      WHERE
10294          pmt.payment_instruction_id = p_instr_id
10295      AND
10296          pmt.payment_status = PAY_STATUS_REQ_TERM
10297      ;
10298 
10299      print_debuginfo(l_module_name, 'Count of terminated payments in '
10300          || 'pmt instr '
10301          || p_instr_id
10302          || ' = '
10303          || l_all_pmts_count
10304          );
10305 
10306      /*
10307       * If all payments have been terminated return TRUE.
10308       */
10309      IF (l_all_pmts_count = l_term_pmts_count) THEN
10310 
10311          print_debuginfo(l_module_name, 'All payments in pmt instr '
10312              || p_instr_id
10313              || ' have been terminated. Returning TRUE.'
10314              );
10315 
10316          l_flag := TRUE;
10317 
10318      ELSE
10319 
10320          print_debuginfo(l_module_name, 'At least one payment in pmt instr '
10321              || p_instr_id
10322              || ' has not been terminated. Returning FALSE.'
10323              );
10324 
10325          l_flag := FALSE;
10326 
10327      END IF;
10328 
10329      print_debuginfo(l_module_name, 'EXIT');
10330 
10331      RETURN l_flag;
10332 
10333  EXCEPTION
10334 
10335      WHEN OTHERS THEN
10336 
10337          print_debuginfo(l_module_name, 'Exception occured when '
10338              || 'checking if all pmts of pmt instruction '
10339              || p_instr_id
10340              || ' were terminated.'
10341              );
10342 
10343          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
10344          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
10345 
10346          l_flag := FALSE;
10347          print_debuginfo(l_module_name, 'Returning FALSE.');
10348          print_debuginfo(l_module_name, 'EXIT');
10349 
10350          RETURN l_flag;
10351 
10352  END checkIfAllPmtsTerminated;
10353 
10354 /*--------------------------------------------------------------------
10355  | NAME:
10356  |     checkIfPmtInInstExists
10357  |
10358  | PURPOSE:
10359  |     Checks if all payments of a given payment instruction
10360  |     have been terminated.
10361  |
10362  | PARAMETERS:
10363  |     IN
10364  |       p_payreq_id - Payment request to verify.
10365  |
10366  |     OUT
10367  |       NONE
10368  |
10369  | RETURNS:
10370  |       TRUE  - if at least one payment of the ppr is part of
10371  |                   an instruction.
10372  |       FALSE - if none of the payments of the ppr are part of
10373  |                   an instruction.
10374  |
10375  | NOTES:
10376  |       This method is meant exclusively to be used by the
10377  |       terminate_pmt_request(..) API. Do not use call this
10378  |       method for other general purposes.
10379  |
10380  |
10381  |       -- IMPORTANT --
10382  |       This method locks rows in the IBY_PAYMENTS_ALL table and
10383  |       expects that the caller will commit/rollback to release lock.
10384  |
10385  *---------------------------------------------------------------------*/
10386  FUNCTION checkIfPmtInInstExists(
10387      p_payreq_id          IN NUMBER
10388      ) RETURN BOOLEAN
10389  IS
10390 
10391  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
10392                                          || '.checkIfPmtInInstExists';
10393 
10394  l_flag             BOOLEAN := FALSE;
10395  l_test             VARCHAR2(200);
10396 
10397  l_all_pmts_count   NUMBER;
10398  l_term_pmts_count  NUMBER;
10399 
10400  BEGIN
10401 
10402      print_debuginfo(l_module_name, 'ENTER');
10403 
10404      /*
10405       * This method is called by terminate_pmt_request(..)
10406       * to check if any of the payments are part of a payment
10407       * instruction.
10408       *
10409       * TIME T1: This method returns FALSE
10410       *          implying that none of the
10411       *          payments of the ppr are part
10412       *          of any payment instruction.
10413       *
10414       * TIME T2: PICP runs and picks up payments
10415       *          of which some payments are from this
10416       *          ppr.
10417       *
10418       * TIME T3: terminate_pmt_request(..) terminates
10419       *          a ppr based on the return value of
10420       *          this method. Now, we have an payment
10421       *          instruction that contains a payment
10422       *          from this ppr that has been terminated.
10423       *          This situation is wrong and should never
10424       *          occur.
10425       *
10426       * To prevent this situation, we lock the payments
10427       * table first, before attempting to terminate
10428       * a ppr.
10429       *
10430       * This lock will get released when the UI peforms a
10431       * COMMIT / ROLLBACK action based on the return value
10432       * of the terminate_pmt_request(..) API.
10433       */
10434 
10435      /*
10436       * Instead of locking the entire table only lock the
10437       * rows that we are interested in (explicit locking).
10438       */
10439      -- LOCK TABLE IBY_PAYMENTS_ALL IN EXCLUSIVE MODE;
10440 
10441      SELECT
10442          pmt.payment_id
10443      INTO
10444          l_test
10445      FROM
10446          IBY_PAYMENTS_ALL pmt
10447      WHERE
10448          pmt.payment_instruction_id IS NOT NULL
10449      AND
10450          pmt.payment_service_request_id = p_payreq_id
10451      FOR UPDATE
10452      ;
10453 
10454      /*
10455       * Now check whether the payments of this request
10456       * are linked to any payment instructions.
10457       */
10458      SELECT
10459          'TRUE'
10460      INTO
10461          l_test
10462      FROM
10463          DUAL
10464      WHERE
10465          EXISTS
10466          (
10467           SELECT
10468               pmt.payment_id
10469           FROM
10470               IBY_PAYMENTS_ALL pmt
10471           WHERE
10472               pmt.payment_instruction_id IS NOT NULL
10473           AND
10474               pmt.payment_service_request_id = p_payreq_id
10475           )
10476      ;
10477 
10478      IF (l_test = 'TRUE') THEN
10479          l_flag := TRUE;
10480          print_debuginfo(l_module_name, 'Returning flag as TRUE.');
10481      ELSE
10482          l_flag := FALSE;
10483          print_debuginfo(l_module_name, 'Returning flag as FALSE.');
10484      END IF;
10485 
10486      print_debuginfo(l_module_name, 'EXIT');
10487 
10488      RETURN l_flag;
10489 
10490  EXCEPTION
10491 
10492      WHEN NO_DATA_FOUND THEN
10493 
10494          print_debuginfo(l_module_name, 'Payment request id '
10495              || p_payreq_id
10496              || ' does not contain any payments.'
10497              );
10498 
10499          /*
10500           * This ppr only contains documents and no payments.
10501           *
10502           * Therefore, allow this ppr to be terminated by
10503           * returning FALSE.
10504           */
10505          l_flag := FALSE;
10506          print_debuginfo(l_module_name, 'Returning FALSE.');
10507          print_debuginfo(l_module_name, 'EXIT');
10508 
10509          RETURN l_flag;
10510 
10511      WHEN OTHERS THEN
10512 
10513          print_debuginfo(l_module_name, 'Exception occured when '
10514              || 'checking if any pmts of pmt request '
10515              || p_payreq_id
10516              || ' were part of a pmt instruction.'
10517              );
10518 
10519          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
10520          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
10521 
10522          /*
10523           * In case of an exception, play safe and return TRUE.
10524           *
10525           * The terminate_pmt_request(..) API will not allow the
10526           * request to be terminated.
10527           */
10528          l_flag := TRUE;
10529          print_debuginfo(l_module_name, 'Returning TRUE.');
10530          print_debuginfo(l_module_name, 'EXIT');
10531 
10532          RETURN l_flag;
10533 
10534  END checkIfPmtInInstExists;
10535 
10536 /*--------------------------------------------------------------------
10537  | NAME:
10538  |     finalize_electronic_instr
10539  |
10540  |
10541  | PURPOSE:
10542  |
10543  |
10544  | PARAMETERS:
10545  |     IN
10546  |
10547  |
10548  |     OUT
10549  |
10550  |
10551  | RETURNS:
10552  |
10553  | NOTES:
10554  |     Internal API, not for public use.
10555  |
10556  *---------------------------------------------------------------------*/
10557  PROCEDURE finalize_electronic_instr(
10558              p_instr_id          IN NUMBER,
10559              x_return_status     IN OUT NOCOPY VARCHAR2
10560              )
10561  IS
10562 
10563  l_module_name     CONSTANT VARCHAR2(200)
10564                                 := G_PKG_NAME ||
10565                                        '.finalize_electronic_instr';
10566 
10567  l_flag            BOOLEAN := FALSE;
10568 
10569  BEGIN
10570 
10571      print_debuginfo(l_module_name, 'ENTER');
10572      FND_MSG_PUB.initialize;
10573 
10574      /*
10575       * STEP 1:
10576       *
10577       * Check if payment instruction transmission is outside
10578       * the system.
10579       *
10580       * Update the payment instruction and payment statuses
10581       * to final statuses accordingly.
10582       */
10583      l_flag := checkIfInstrXmitOutsideSystem(p_instr_id);
10584 
10585      IF (l_flag = TRUE) THEN
10586 
10587          UPDATE
10588              IBY_PAY_INSTRUCTIONS_ALL inst
10589          SET
10590              inst.payment_instruction_status = INS_STATUS_FORMATTED_ELEC
10591          WHERE
10592              inst.payment_instruction_id = p_instr_id
10593          ;
10594 
10595          UPDATE
10596              IBY_PAYMENTS_ALL pmt
10597          SET
10598              pmt.payment_status = PAY_STATUS_FORMATTED
10599          WHERE
10600              pmt.payment_instruction_id = p_instr_id
10601          ;
10602 
10603      ELSE
10604 
10605          UPDATE
10606              IBY_PAY_INSTRUCTIONS_ALL inst
10607          SET
10608              inst.payment_instruction_status = INS_STATUS_TRANSMITTED
10609          WHERE
10610              inst.payment_instruction_id = p_instr_id
10611          ;
10612 
10613          UPDATE
10614              IBY_PAYMENTS_ALL pmt
10615          SET
10616              pmt.payment_status = PAY_STATUS_TRANSMITTED
10617          WHERE
10618              pmt.payment_instruction_id = p_instr_id
10619          ;
10620 
10621      END IF;
10622 
10623      /*
10624       * STEP 2:
10625       *
10626       * Mark the payment instruction and payments complete.
10627       */
10628      print_debuginfo(l_module_name,
10629          'Invoking mark payments complete API ..');
10630 
10631      mark_all_pmts_complete(p_instr_id, x_return_status);
10632 
10633      print_debuginfo(l_module_name, 'Returning status: '
10634          || x_return_status
10635          );
10636 
10637      print_debuginfo(l_module_name, 'EXIT');
10638 
10639  EXCEPTION
10640      WHEN OTHERS THEN
10641 
10642          print_debuginfo(l_module_name, 'Exception occured when '
10643              || 'finalizing electronic payment instruction '
10644              || p_instr_id
10645              || '.'
10646              );
10647 
10648          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
10649          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
10650 
10651          x_return_status := FND_API.G_RET_STS_ERROR;
10652 
10653          print_debuginfo(l_module_name, 'Returning error status: '
10654              || x_return_status
10655              );
10656          print_debuginfo(l_module_name, 'EXIT');
10657 
10658  END finalize_electronic_instr;
10659 
10660 /*--------------------------------------------------------------------
10661  | NAME:
10662  |     checkIfInstrXmitOutsideSystem
10663  |
10664  |
10665  | PURPOSE:
10666  |
10667  |
10668  | PARAMETERS:
10669  |     IN
10670  |
10671  |
10672  |     OUT
10673  |
10674  |
10675  | RETURNS:
10676  |
10677  | NOTES:
10678  |     Internal API, not for public use.
10679  |
10680  *---------------------------------------------------------------------*/
10681  FUNCTION checkIfInstrXmitOutsideSystem(
10682      p_instr_id          IN NUMBER
10683      ) RETURN BOOLEAN
10684  IS
10685 
10686  l_module_name CONSTANT VARCHAR2(200)
10687                             := G_PKG_NAME
10688                                    || '.checkIfInstrXmitOutsideSystem';
10689 
10690  l_flag             BOOLEAN := FALSE;
10691  l_test             VARCHAR2(200);
10692 
10693  BEGIN
10694 
10695      print_debuginfo(l_module_name, 'ENTER');
10696 
10697      /*
10698       * If the transmit configuration id linked to the profile
10699       * on a payment instruction is null, it means that transmit
10700       * configuration has not been set up for that profile.
10701       *
10702       * This implies that the payment instruction needs to be
10703       * transmitted outside the system (i.e., using an external
10704       * application).
10705       */
10706      SELECT
10707          'TRUE'
10708      INTO
10709          l_test
10710      FROM
10711          DUAL
10712      WHERE
10713          EXISTS
10714          (
10715           SELECT
10716               instr.payment_instruction_id
10717           FROM
10718               IBY_PAY_INSTRUCTIONS_ALL instr,
10719               IBY_PAYMENT_PROFILES     prof
10720           WHERE
10721               instr.payment_instruction_id = p_instr_id
10722           AND
10723               prof.payment_profile_id = instr.payment_profile_id
10724           AND
10725               prof.transmit_configuration_id IS NULL
10726           )
10727      ;
10728 
10729      IF (l_test = 'TRUE') THEN
10730          l_flag := TRUE;
10731          print_debuginfo(l_module_name, 'Transmission is outside the system.');
10732          print_debuginfo(l_module_name, 'Returning flag as TRUE.');
10733      ELSE
10734          l_flag := FALSE;
10735          print_debuginfo(l_module_name, 'Transmission is inside the system.');
10736          print_debuginfo(l_module_name, 'Returning flag as FALSE.');
10737      END IF;
10738 
10739      print_debuginfo(l_module_name, 'EXIT');
10740 
10741      RETURN l_flag;
10742 
10743  EXCEPTION
10744 
10745      WHEN OTHERS THEN
10746 
10747          print_debuginfo(l_module_name, 'Exception occured when '
10748              || 'checking if instruction '
10749              || p_instr_id
10750              || ' needs to be transmitted using external system(s).'
10751              );
10752 
10753          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
10754          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
10755 
10756          /*
10757           * In case of an exception, play safe and return TRUE.
10758           *
10759           * The user will have to transmit the payment instruction
10760           * outside of IBY using some external application.
10761           */
10762          l_flag := TRUE;
10763          print_debuginfo(l_module_name, 'Transmission will have to be '
10764              || 'outside the system (irrespective of setting).');
10765          print_debuginfo(l_module_name, 'Returning TRUE.');
10766          print_debuginfo(l_module_name, 'EXIT');
10767 
10768          RETURN l_flag;
10769 
10770  END checkIfInstrXmitOutsideSystem;
10771 
10772 /*--------------------------------------------------------------------
10773  | NAME:
10774  |     checkIfPmtEntityLocked
10775  |
10776  |
10777  | PURPOSE:
10778  |     Checks if a given payment entity is locked (i.e., stamped
10779  |     with a concurrent request id).
10780  |
10781  | PARAMETERS:
10782  |     IN
10783  |
10784  |
10785  |     OUT
10786  |
10787  |
10788  | RETURNS:
10789  |
10790  | NOTES:
10791  |     Internal API, not for public use.
10792  |
10793  *---------------------------------------------------------------------*/
10794  FUNCTION checkIfPmtEntityLocked(
10795      p_object_id         IN NUMBER,
10796      p_object_type       IN VARCHAR2
10797      ) RETURN BOOLEAN
10798  IS
10799  l_module_name CONSTANT VARCHAR2(200)
10800                             := G_PKG_NAME || '.checkIfPmtEntityLocked';
10801 
10802  l_flag             BOOLEAN := FALSE;
10803  l_test             VARCHAR2(200);
10804 
10805  BEGIN
10806 
10807      print_debuginfo(l_module_name, 'ENTER');
10808 
10809      IF (p_object_type = 'PAYMENT_REQUEST') THEN
10810 
10811          SELECT
10812              'TRUE'
10813          INTO
10814              l_test
10815          FROM
10816              DUAL
10817          WHERE
10818              EXISTS
10819              (
10820              SELECT
10821                  req.payment_service_request_id
10822              FROM
10823                  IBY_PAY_SERVICE_REQUESTS req
10824              WHERE
10825                  req.payment_service_request_id = p_object_id
10826              AND
10827                  req.request_id IS NOT NULL
10828              )
10829          ;
10830 
10831      ELSIF (p_object_type = 'PAYMENT_INSTRUCTION') THEN
10832 
10833          SELECT
10834              'TRUE'
10835          INTO
10836              l_test
10837          FROM
10838              DUAL
10839          WHERE
10840              EXISTS
10841              (
10842              SELECT
10843                  inst.payment_instruction_id
10844              FROM
10845                  IBY_PAY_INSTRUCTIONS_ALL inst
10846              WHERE
10847                  inst.payment_instruction_id = p_object_id
10848              AND
10849                  inst.request_id IS NOT NULL
10850              )
10851          ;
10852 
10853      ELSIF (p_object_type = 'PAYMENT') THEN
10854 
10855          SELECT
10856              'TRUE'
10857          INTO
10858              l_test
10859          FROM
10860              DUAL
10861          WHERE
10862              EXISTS
10863              (
10864              SELECT
10865                  pmt.payment_id
10866              FROM
10867                  IBY_PAYMENTS_ALL pmt
10868              WHERE
10869                  pmt.payment_id = p_object_id
10870              AND
10871                  pmt.request_id IS NOT NULL
10872              )
10873          ;
10874 
10875      ELSE
10876 
10877          print_debuginfo(l_module_name, 'Unknown payment entity type '
10878              || p_object_type
10879              || ' provided. Raising exception .. '
10880              );
10881 
10882          APP_EXCEPTION.RAISE_EXCEPTION;
10883 
10884      END IF;
10885 
10886      IF (l_test = 'TRUE') THEN
10887          l_flag := TRUE;
10888          print_debuginfo(l_module_name, 'Returning flag as TRUE.');
10889      ELSE
10890          l_flag := FALSE;
10891          print_debuginfo(l_module_name, 'Returning flag as FALSE.');
10892      END IF;
10893 
10894      print_debuginfo(l_module_name, 'EXIT');
10895 
10896      RETURN l_flag;
10897 
10898  EXCEPTION
10899 
10900      /*
10901       * Fix for bug 5195694:
10902       *
10903       * If no row was found, it means that the
10904       * payment entity is not locked.
10905       */
10906      WHEN NO_DATA_FOUND THEN
10907 
10908          print_debuginfo(l_module_name, 'Pmt entity id '
10909              || p_object_id
10910              || ' of type '
10911              || p_object_type
10912              || ' is not locked.'
10913              );
10914 
10915          l_flag := FALSE;
10916          print_debuginfo(l_module_name, 'Returning FALSE.');
10917          print_debuginfo(l_module_name, 'EXIT');
10918 
10919          RETURN l_flag;
10920 
10921      WHEN OTHERS THEN
10922 
10923          print_debuginfo(l_module_name, 'Exception occured when '
10924              || 'checking if pmt entity id '
10925              || p_object_id
10926              || ' of type '
10927              || p_object_type
10928              || ' is locked.'
10929              );
10930 
10931          print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
10932          print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
10933 
10934          /*
10935           * In case of an exception, play safe and return TRUE.
10936           *
10937           * The user will assume that the pmt entity is locked.
10938           */
10939          l_flag := TRUE;
10940          print_debuginfo(l_module_name, 'Treating payment entity as locked.');
10941          print_debuginfo(l_module_name, 'Returning TRUE.');
10942          print_debuginfo(l_module_name, 'EXIT');
10943 
10944          RETURN l_flag;
10945 
10946  END checkIfPmtEntityLocked;
10947 
10948  -- The procedure to submit a request set
10949  /*--------------------------------------------------------------------
10950  | NAME:
10951  |     submit_masking_req_set
10952  |
10953  |
10954  | PURPOSE:
10955  |
10956  | PARAMETERS:
10957  |     IN
10958  |
10959  |
10960  |     OUT
10961  |
10962  |
10963  | RETURNS:
10964  |
10965  | NOTES:
10966  |
10967  *---------------------------------------------------------------------*/
10968  PROCEDURE submit_masking_req_set (
10969      x_request_id      OUT NOCOPY NUMBER,
10970      x_return_status   OUT NOCOPY VARCHAR2,
10971      x_msg_count       OUT NOCOPY NUMBER,
10972      x_msg_data        OUT NOCOPY VARCHAR2
10973  ) IS
10974  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME || '.submit_masking_req_set';
10975 
10976  l_api_version    CONSTANT NUMBER := 1.0;
10977  l_msg_count      NUMBER;
10978  l_msg_data       VARCHAR2(2000);
10979 
10980  l_phase          VARCHAR2(200);
10981  l_success BOOLEAN;
10982  submit_failed EXCEPTION;
10983 
10984  BEGIN
10985     print_debuginfo(l_module_name, 'ENTER');
10986 
10987     x_return_status := FND_API.G_RET_STS_SUCCESS;
10988     FND_MSG_PUB.initialize;
10989 
10990     /* set the context for the request set IBY_SECURITY_MASKING_REQ_SET */
10991     l_success := fnd_submit.set_request_set('IBY', 'IBY_SECURITY_MASKING_REQ_SET');
10992     l_phase := 'After set request set.';
10993 
10994         if ( l_success ) then
10995 
10996            /* submit program IBY_CREDITCARD_MASKING which is in stage STAGE1 */
10997            l_success := fnd_submit.submit_program('IBY','IBY_CREDITCARD_MASKING', 'STAGE1',
10998                           '','','','','','','','','','','','','','','','','','','','',
10999                           '','','','','','','','','','','','','','','','','','','','',
11000                           '','','','','','','','','','','','','','','','','','','','',
11001                           '','','','','','','','','','','','','','','','','','','','',
11002                           '','','','','','','','','','','','','','','','','','','','');
11003            l_phase := 'After submit program 1.';
11004            if ( not l_success ) then
11005               raise submit_failed;
11006            end if;
11007 
11008            /* submit program IBY_EXT_BANKACCT_MASKING which is in stage STAGE1 */
11009            l_success := fnd_submit.submit_program('IBY','IBY_EXT_BANKACCT_MASKING', 'STAGE1',
11010                           '','','','','','','','','','','','','','','','','','','','',
11011                           '','','','','','','','','','','','','','','','','','','','',
11012                           '','','','','','','','','','','','','','','','','','','','',
11013                           '','','','','','','','','','','','','','','','','','','','',
11014                           '','','','','','','','','','','','','','','','','','','','');
11015            l_phase := 'After submit program 2.';
11016            if ( not l_success ) then
11017               raise submit_failed;
11018            end if;
11019 
11020            /*  Submit the Request set  */
11021            x_request_id := fnd_submit.submit_set(null,FALSE);
11022            l_phase := 'After submit request set.';
11023 
11024        else
11025            l_phase := 'Failed after set request set.';
11026            raise submit_failed;
11027        end if;
11028  EXCEPTION
11029    WHEN submit_failed THEN
11030      x_return_status := FND_API.G_RET_STS_ERROR;
11031      print_debuginfo(l_module_name, 'Exception submit_failed - ' || l_phase);
11032      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
11033 
11034    WHEN others THEN
11035      x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
11036      print_debuginfo(l_module_name, 'Exception others.');
11037      print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
11038      print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
11039      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
11040 
11041  END submit_masking_req_set;
11042 
11043  -- The procedure to submit a request set
11044  /*--------------------------------------------------------------------
11045  | NAME:
11046  |     submit_decrypt_req_set
11047  |
11048  |
11049  | PURPOSE:
11050  |
11051  | PARAMETERS:
11052  |     IN
11053  |
11054  |
11055  |     OUT
11056  |
11057  |
11058  | RETURNS:
11059  |
11060  | NOTES:
11061  |
11062  *---------------------------------------------------------------------*/
11063  PROCEDURE submit_decrypt_req_set (
11064      x_request_id      OUT NOCOPY NUMBER,
11065      x_return_status   OUT NOCOPY VARCHAR2,
11066      x_msg_count       OUT NOCOPY NUMBER,
11067      x_msg_data        OUT NOCOPY VARCHAR2
11068  ) IS
11069  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME || '.submit_decrypt_req_set';
11070 
11071  l_api_version    CONSTANT NUMBER := 1.0;
11072  l_msg_count      NUMBER;
11073  l_msg_data       VARCHAR2(2000);
11074 
11075  l_phase          VARCHAR2(200);
11076  l_success BOOLEAN;
11077  submit_failed EXCEPTION;
11078 
11079  BEGIN
11080     print_debuginfo(l_module_name, 'ENTER');
11081 
11082     x_return_status := FND_API.G_RET_STS_SUCCESS;
11083     FND_MSG_PUB.initialize;
11084 
11085     /* set the context for the request set IBY_SECURITY_DECRYPT_REQ_SET */
11086     l_success := fnd_submit.set_request_set('IBY', 'IBY_SECURITY_DECRYPT_REQ_SET');
11087     l_phase := 'After set request set.';
11088 
11089         if ( l_success ) then
11090 
11091            /* submit program IBY_CREDITCARD_DECRYPTION which is in stage STAGE1 */
11092            l_success := fnd_submit.submit_program('IBY','IBY_CREDITCARD_DECRYPTION', 'STAGE1',
11093                           '','','','','','','','','','','','','','','','','','','','',
11094                           '','','','','','','','','','','','','','','','','','','','',
11095                           '','','','','','','','','','','','','','','','','','','','',
11096                           '','','','','','','','','','','','','','','','','','','','',
11097                           '','','','','','','','','','','','','','','','','','','','');
11098            l_phase := 'After submit program 1.';
11099            if ( not l_success ) then
11100               raise submit_failed;
11101            end if;
11102 
11103            /* submit program IBY_EXT_BANKACCT_DECRYPTION which is in stage STAGE1 */
11104            l_success := fnd_submit.submit_program('IBY','IBY_EXT_BANKACCT_DECRYPTION', 'STAGE1',
11105                           '','','','','','','','','','','','','','','','','','','','',
11106                           '','','','','','','','','','','','','','','','','','','','',
11107                           '','','','','','','','','','','','','','','','','','','','',
11108                           '','','','','','','','','','','','','','','','','','','','',
11109                           '','','','','','','','','','','','','','','','','','','','');
11110            l_phase := 'After submit program 2.';
11111            if ( not l_success ) then
11112               raise submit_failed;
11113            end if;
11114 
11115            /* submit program IBY_TRXN_EXTENSION_DECRYPTION which is in stage STAGE1 */
11116            l_success := fnd_submit.submit_program('IBY','IBY_TRXN_EXTENSION_DECRYPTION', 'STAGE1',
11117                           '','','','','','','','','','','','','','','','','','','','',
11118                           '','','','','','','','','','','','','','','','','','','','',
11119                           '','','','','','','','','','','','','','','','','','','','',
11120                           '','','','','','','','','','','','','','','','','','','','',
11121                           '','','','','','','','','','','','','','','','','','','','');
11122            l_phase := 'After submit program 3.';
11123            if ( not l_success ) then
11124               raise submit_failed;
11125            end if;
11126 
11127            /* submit program IBY_TX_CREDITCARD_DECRYPTION which is in stage STAGE1 */
11128            l_success := fnd_submit.submit_program('IBY','IBY_TX_CREDITCARD_DECRYPTION', 'STAGE1',
11129                           '','','','','','','','','','','','','','','','','','','','',
11130                           '','','','','','','','','','','','','','','','','','','','',
11131                           '','','','','','','','','','','','','','','','','','','','',
11132                           '','','','','','','','','','','','','','','','','','','','',
11133                           '','','','','','','','','','','','','','','','','','','','');
11134            l_phase := 'After submit program 4.';
11135            if ( not l_success ) then
11136               raise submit_failed;
11137            end if;
11138 
11139            /*  Submit the Request set  */
11140            x_request_id := fnd_submit.submit_set(null,FALSE);
11141            l_phase := 'After submit request set.';
11142 
11143        else
11144            l_phase := 'Failed after set request set.';
11145            raise submit_failed;
11146        end if;
11147  EXCEPTION
11148    WHEN submit_failed THEN
11149      x_return_status := FND_API.G_RET_STS_ERROR;
11150      print_debuginfo(l_module_name, 'Exception submit_failed - ' || l_phase);
11151      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
11152 
11153    WHEN others THEN
11154      x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
11155      print_debuginfo(l_module_name, 'Exception others.');
11156      print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
11157      print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
11158      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
11159 
11160  END submit_decrypt_req_set;
11161 
11162 /*--------------------------------------------------------------------
11163  | NAME:
11164  |     get_conc_request_status
11165  |
11166  | PURPOSE:
11167  |     Get the concurrent request id status using the FND API.
11168  |
11169  | PARAMETERS:
11170  |     IN     x_request_id
11171  |
11172  | RETURNS: x_request_status (SUCCESS, ERROR, PENDING)
11173  |
11174  | NOTES:
11175  |     Internal API, not for public use.
11176  |     This API is used by the FD Dashboard to determine if a request
11177  |     has terminated with error.
11178  |
11179  *---------------------------------------------------------------------*/
11180  FUNCTION get_conc_request_status (
11181      x_request_id     IN NUMBER)
11182  RETURN VARCHAR2 AS
11183 
11184    v_call_status   BOOLEAN;
11185    v_req_phase_t   VARCHAR2(80);
11186    v_req_status_t  VARCHAR2(80);
11187    v_req_phase_c   VARCHAR2(30);
11188    v_req_status_c  VARCHAR2(30);
11189    v_message       VARCHAR2(240);
11190    v_request_id    iby_payments_all.request_id%TYPE;
11191 
11192    x_return_status VARCHAR2(30) := 'PENDING';
11193 
11194  BEGIN
11195    IF (x_request_id IS NOT NULL) THEN
11196      v_request_id := x_request_id;
11197      -- call FND API to get request status
11198      v_call_status := FND_CONCURRENT.get_request_status(
11199                       v_request_id,
11200                       null, null,
11201                       v_req_phase_t, v_req_status_t,
11202                       v_req_phase_c, v_req_status_c,
11203                       v_message);
11204 
11205      IF (v_call_status) THEN
11206        IF (v_req_phase_c = 'COMPLETE') THEN
11207          IF (v_req_status_c IN ('ERROR', 'CANCELLED', 'TERMINATED')) THEN
11208            x_return_status := 'ERROR';
11209          END IF;
11210        END IF;
11211      ELSE
11212        x_return_status := 'ERROR';
11213      END IF;
11214    ELSE
11215      x_return_status := 'SUCCESS';
11216    END IF;
11217 
11218    RETURN x_return_status;
11219  END get_conc_request_status;
11220 
11221 /*--------------------------------------------------------------------
11222  | NAME:
11223  |     print_completed_pmts
11224  |
11225  |
11226  | PURPOSE:
11227  |     Prints list of payments marked complete using the provided
11228  |     completion group id.
11229  |
11230  |     This function is used for debugging purposes.
11231  |
11232  | PARAMETERS:
11233  |     IN
11234  |
11235  |
11236  |     OUT
11237  |
11238  |
11239  | RETURNS:
11240  |
11241  | NOTES:
11242  |     Internal API, not for public use.
11243  |
11244  *---------------------------------------------------------------------*/
11245  PROCEDURE print_completed_pmts(
11246              p_completion_id          IN NUMBER
11247              )
11248  IS
11249  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
11250                                          || '.print_completed_pmts';
11251 
11252  l_pmts_list     pmtIDTab;
11253 
11254  /*
11255   * Cursor to pick up all payment ids associated with the
11256   * provided completion id.
11257   */
11258  CURSOR c_pmt_ids (p_complete_id NUMBER)
11259  IS
11260  SELECT
11261      pmt.payment_id
11262  FROM
11263      IBY_PAYMENTS_ALL         pmt
11264  WHERE
11265      pmt.completed_pmts_group_id = p_complete_id
11266  ;
11267 
11268  BEGIN
11269 
11270      print_debuginfo(l_module_name, 'ENTER');
11271      print_debuginfo(l_module_name, 'completion id: ' || p_completion_id);
11272 
11273      FND_MSG_PUB.initialize;
11274 
11275      OPEN  c_pmt_ids (p_completion_id);
11276      FETCH c_pmt_ids BULK COLLECT INTO l_pmts_list;
11277      CLOSE c_pmt_ids;
11278 
11279      IF (l_pmts_list.COUNT > 0) THEN
11280 
11281          print_debuginfo(l_module_name, 'List of completed payments - ');
11282 
11283          FOR i IN l_pmts_list.FIRST .. l_pmts_list.LAST LOOP
11284 
11285              print_debuginfo(l_module_name, 'pmt id: ' || l_pmts_list(i));
11286 
11287          END LOOP;
11288 
11289      ELSE
11290 
11291          print_debuginfo(l_module_name, 'No completed payments '
11292              || 'were retrieved using completion id '
11293              || p_completion_id
11294              );
11295 
11296      END IF;
11297 
11298      print_debuginfo(l_module_name, 'EXIT');
11299 
11300  EXCEPTION
11301      WHEN OTHERS THEN
11302 
11303      /*
11304       * This is a non-fatal exception. We will log the exception
11305       * and return.
11306       */
11307      print_debuginfo(l_module_name, 'Non-Fatal: Exception occured '
11308          || 'when trying to print completed payments using '
11309          || 'completion id: '
11310          || p_completion_id
11311          );
11312 
11313      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
11314      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
11315      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
11316 
11317  END print_completed_pmts;
11318 
11319 
11320 /*--------------------------------------------------------------------
11321  | NAME:
11322  |     print_completed_docs
11323  |
11324  |
11325  | PURPOSE:
11326  |     Prints list of documents payable marked complete using the
11327  |     provided completion group id.
11328  |
11329  |     This function is used for debugging purposes.
11330  |
11331  | PARAMETERS:
11332  |     IN
11333  |
11334  |
11335  |     OUT
11336  |
11337  |
11338  | RETURNS:
11339  |
11340  | NOTES:
11341  |     Internal API, not for public use.
11342  |
11343  *---------------------------------------------------------------------*/
11344  PROCEDURE print_completed_docs(
11345              p_completion_id          IN NUMBER
11346              )
11347  IS
11348  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
11349                                          || '.print_completed_docs';
11350 
11351  l_docs_list     docPayIDTab;
11352 
11353  /*
11354   * Cursor to pick up all document ids associated with the
11355   * provided completion id.
11356   */
11357  CURSOR c_doc_ids (p_complete_id NUMBER)
11358  IS
11359  SELECT
11360      doc.document_payable_id
11361  FROM
11362      IBY_DOCS_PAYABLE_ALL        doc
11363  WHERE
11364      doc.completed_pmts_group_id = p_complete_id
11365  ;
11366 
11367  BEGIN
11368 
11369      print_debuginfo(l_module_name, 'ENTER');
11370      print_debuginfo(l_module_name, 'completion id: ' || p_completion_id);
11371 
11372      FND_MSG_PUB.initialize;
11373 
11374      OPEN  c_doc_ids (p_completion_id);
11375      FETCH c_doc_ids BULK COLLECT INTO l_docs_list;
11376      CLOSE c_doc_ids;
11377 
11378      IF (l_docs_list.COUNT > 0) THEN
11379 
11380          print_debuginfo(l_module_name, 'List of completed documents - ');
11381 
11382          FOR i IN l_docs_list.FIRST .. l_docs_list.LAST LOOP
11383 
11384              print_debuginfo(l_module_name, 'doc id: ' || l_docs_list(i));
11385 
11386          END LOOP;
11387 
11388      ELSE
11389 
11390          print_debuginfo(l_module_name, 'No completed documents '
11391              || 'were retrieved using completion id '
11392              || p_completion_id
11393              );
11394 
11395      END IF;
11396 
11397      print_debuginfo(l_module_name, 'EXIT');
11398 
11399  EXCEPTION
11400      WHEN OTHERS THEN
11401 
11402      /*
11403       * This is a non-fatal exception. We will log the exception
11404       * and return.
11405       */
11406      print_debuginfo(l_module_name, 'Non-Fatal: Exception occured '
11407          || 'when trying to print completed documents using '
11408          || 'completion id: '
11409          || p_completion_id
11410          );
11411 
11412      print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
11413      print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
11414      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
11415 
11416  END print_completed_docs;
11417 
11418 
11419 /*--------------------------------------------------------------------
11420  | NAME:
11421  |     is_security_function_valid
11422  |
11423  | PURPOSE:
11424  |     This API will return Y or N is the security function passed
11425  |     is assigned to the user.  This function wraps the
11426  |     FND_FUNCTION.TEST API.
11427  |
11428  | PARAMETERS:
11429  |     IN     x_security_function_name
11430  |
11431  | RETURNS: x_function_valid (Y, N)
11432  |
11433  | NOTES:
11434  |     Internal API, not for public use.
11435  |     This API is used by the taks list page to determine if a user is
11436  |     available to do the setup for the Shared, FD or FC tasks.
11437  |
11438  *---------------------------------------------------------------------*/
11439  FUNCTION is_security_function_valid (
11440      x_security_function_name     IN VARCHAR2)
11441  RETURN VARCHAR2 AS
11442 
11443    x_return_status VARCHAR2(30) := 'N';
11444 
11445  BEGIN
11446 
11447    IF fnd_function.test(x_security_function_name) THEN
11448      x_return_status := 'Y';
11449    END IF;
11450 
11451    RETURN x_return_status;
11452  END is_security_function_valid;
11453 
11454 
11455 
11456   /*--------------------------------------------------------------------
11457  | NAME:
11458  |    Rejected_user_acc
11459  |
11460  |
11461  | PURPOSE:
11462  |     Checks whether the user has access to all the org. or payment function
11463  |      of rejected or removed entities ( documents or payments) for a
11464  |      given payment service request.
11465  |
11466  | PARAMETERS:
11467  |     IN
11468  |
11469  |
11470  |     OUT
11471  |
11472  |
11473  | RETURNS:
11474  |
11475  | NOTES:
11476  |     Internal API, not for public use.
11477  |
11478  *---------------------------------------------------------------------*/
11479  PROCEDURE Rejected_user_acc(
11480              p_pay_service_request_id  IN NUMBER,
11481              x_inaccessible_entities OUT NOCOPY VARCHAR2,
11482              x_return_status     IN OUT NOCOPY VARCHAR2,
11483              x_return_message    IN OUT NOCOPY VARCHAR2)
11484   IS
11485  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME
11486                                          || '.Rejected_user_acc';
11487 
11488  l_doc_function_count NUMBER:=0;
11489  l_doc_org_count NUMBER:=0;
11490  l_pmt_org_count NUMBER:=0;
11491 BEGIN
11492 
11493 
11494 print_debuginfo(l_module_name, 'ENTER');
11495 --Initializing the out parameter
11496  x_inaccessible_entities :='N';
11497 
11498 FND_MSG_PUB.initialize;
11499 
11500 /*Initializing security through CE for populating the
11501    ce related global tables*/
11502 CEP_STANDARD.init_security();
11503 
11504 populatePaymentFunctions(x_return_status, x_return_message);
11505 
11506  /* Initialize return status */
11507 x_return_status := FND_API.G_RET_STS_SUCCESS;
11508 
11509 select count(1)
11510 into l_doc_function_count
11511 FROM  IBY_DOCS_PAYABLE_ALL docs
11512 where  docs.document_status IN
11513         ( 'REJECTED',
11514           'FAILED_BY_RELATED_DOCUMENT',
11515           'FAILED_BY_REJECTION_LEVEL',
11516           'FAILED_BY_CALLING_APP',
11517           'REMOVED',
11518           'REMOVED_PAYMENT_REMOVED',
11519           'REMOVED_REQUEST_TERMINATED',
11520           'REMOVED_INSTRUCTION_TERMINATED',
11521           'REMOVED_PAYMENT_STOPPED',
11522           'REMOVED_PAYMENT_VOIDED')
11523 AND docs.payment_service_request_id = p_pay_service_request_id
11524 and docs.payment_function not in
11525        (select payment_function
11526         from IBY_USER_PAY_FUNS_GT
11527         );
11528 print_debuginfo(l_module_name, 'Number of Missing Payment Function for rejected documents:' ||l_doc_function_count);
11529 
11530 select count(1)
11531 into l_doc_org_count
11532 FROM  IBY_DOCS_PAYABLE_ALL docs
11533 where  docs.document_status IN
11534         ( 'REJECTED',
11535           'FAILED_BY_RELATED_DOCUMENT',
11536           'FAILED_BY_REJECTION_LEVEL',
11537           'FAILED_BY_CALLING_APP',
11538           'REMOVED',
11539           'REMOVED_PAYMENT_REMOVED',
11540           'REMOVED_REQUEST_TERMINATED',
11541           'REMOVED_INSTRUCTION_TERMINATED',
11542           'REMOVED_PAYMENT_STOPPED',
11543           'REMOVED_PAYMENT_VOIDED')
11544 AND docs.payment_service_request_id = p_pay_service_request_id
11545 and docs.org_id not in
11546        (select  organization_id
11547         from ce_security_profiles_v cep
11548         where cep.organization_type=docs.org_type
11549         );
11550 
11551 print_debuginfo(l_module_name, 'Number of Missing Orgs for rejected documents:' ||l_doc_org_count);
11552 
11553 
11554 select count(1)
11555 into  l_pmt_org_count
11556 FROM  iby_payments_all payments
11557 where  payments.payment_status IN
11558                         ('FAILED_BY_REJECTION_LEVEL',
11559                         'FAILED_BY_CALLING_APP',
11560                         'REMOVED',
11561                         'REMOVED_REQUEST_TERMINATED',
11562                         'REMOVED_INSTRUCTION_TERMINATED',
11563                         'REMOVED_DOCUMENT_SPOILED',
11564                         'REMOVED_PAYMENT_STOPPED',
11565                         'VOID')
11566 and payments.org_id not in
11567        (select  organization_id
11568         from ce_security_profiles_v cep
11569         where cep.organization_type=payments.org_type
11570         );
11571     print_debuginfo(l_module_name, 'Number of Missing Org for rejected payments:' ||l_pmt_org_count);
11572 
11573 -- check the user access
11574 if(l_doc_function_count<>0 OR l_doc_org_count <>0 OR l_pmt_org_count <>0) THEN
11575 
11576    print_debuginfo(l_module_name, 'User doesnt have full access to the Rejected documents or Rejected Payments for a given payment process Request');
11577 
11578    x_inaccessible_entities:='Y';
11579    print_debuginfo(l_module_name, 'Returning Y for x_inaccessible_entities');
11580 
11581 end if;
11582    print_debuginfo(l_module_name, 'EXIT');
11583 
11584 EXCEPTION
11585 WHEN OTHERS THEN
11586    print_debuginfo(l_module_name, 'SQL err msg: '
11587        || SQLERRM);
11588      print_debuginfo(l_module_name, 'Returning failure response .. '
11589        );
11590      FND_MSG_PUB.add_exc_msg(G_PKG_NAME, l_module_name, null);
11591      /*
11592       * The error message would have already been set.
11593       * Just set the error status here.
11594       */
11595      x_return_status := FND_API.G_RET_STS_ERROR;
11596 
11597      print_debuginfo(l_module_name, 'EXIT');
11598 
11599 
11600  END Rejected_user_acc;
11601 
11602 
11603 
11604 END IBY_DISBURSE_UI_API_PUB_PKG;
11605