DBA Data[Home] [Help]

PACKAGE BODY: APPS.IBY_SINGPAY_PUB

Source


1 PACKAGE BODY IBY_SINGPAY_PUB AS
2 /*$Header: ibypsinb.pls 120.31.12010000.2 2008/08/22 15:26:42 vkarlapu ship $*/
3 
4  --
5  -- Declare global variables
6  --
7  G_PKG_NAME CONSTANT VARCHAR2(30) := 'IBY_SINGPAY_PUB';
8 
9  --
10  -- List of document statuses that are used / set in this
11  -- module (payment creation flow).
12  --
13  DOC_STATUS_VALIDATED    CONSTANT VARCHAR2(100) := 'VALIDATED';
14  DOC_STATUS_PAY_CREATED  CONSTANT VARCHAR2(100) := 'PAYMENTS_CREATED';
15  DOC_STATUS_CA_FAILED    CONSTANT VARCHAR2(100) := 'FAILED_BY_CALLING_APP';
16  DOC_STATUS_RELN_FAIL    CONSTANT VARCHAR2(100) := 'FAILED_BY_RELATED_DOCUMENT';
17  DOC_STATUS_PAY_VAL_FAIL CONSTANT VARCHAR2(100) := 'PAYMENT_FAILED_VALIDATION';
18  DOC_STATUS_FAIL_BY_REJLVL CONSTANT VARCHAR2(100)
19                                                 := 'FAILED_BY_REJECTION_LEVEL';
20 
21  --
22  -- List of payment statuses that are used / set in this
23  -- module (payment creation flow).
24  --
25  PAY_STATUS_REJECTED       CONSTANT VARCHAR2(100) := 'REJECTED';
26  PAY_STATUS_FAIL_VALID     CONSTANT VARCHAR2(100) := 'FAILED_VALIDATION';
27  PAY_STATUS_CREATED        CONSTANT VARCHAR2(100) := 'CREATED';
28  PAY_STATUS_CA_FAILED      CONSTANT VARCHAR2(100) := 'FAILED_BY_CALLING_APP';
29  PAY_STATUS_FAIL_BY_REJLVL CONSTANT VARCHAR2(100)
30                                         := 'FAILED_BY_REJECTION_LEVEL';
31 
32  --
33  -- List of payment request statuses that are set in this
34  -- module (payment creation flow).
35  --
36  REQ_STATUS_PAY_CRTD      CONSTANT VARCHAR2(100) := 'PAYMENTS_CREATED';
37  REQ_STATUS_FAIL_PAY_CR   CONSTANT VARCHAR2(100) := 'FAILED_PAYMENT_VALIDATION';
38  REQ_STATUS_USER_REVW     CONSTANT VARCHAR2(100) := 'PENDING_REVIEW';
39  REQ_STATUS_USER_REVW_ERR CONSTANT VARCHAR2(100)
40                                        := 'PENDING_REVIEW_PMT_VAL_ERRORS';
41 
42  --
43  -- List of rejection level system options  that are possible for
44  -- this module (payment creation flow).
45  --
46  REJ_LVL_REQUEST  CONSTANT VARCHAR2(100) := 'REQUEST';
47  REJ_LVL_PAYMENT  CONSTANT VARCHAR2(100) := 'PAYMENT';
48  REJ_LVL_NONE     CONSTANT VARCHAR2(100) := 'NONE';
49 
50  -- Transaction types (for inserting into IBY_TRANSACTION_ERRORS table)
51  TRXN_TYPE_DOC   CONSTANT VARCHAR2(100) := 'DOCUMENT_PAYABLE';
52  TRXN_TYPE_PMT   CONSTANT VARCHAR2(100) := 'PAYMENT';
53 
54 /*--------------------------------------------------------------------
55  | NAME:
56  |     createPayments
57  |
58  | PURPOSE:
59  |     Entry point for payment creation flow. All payment grouping
60  |     rules are handled within this method.
61  |
62  |     This method is very similar to createPayments(..) in the
63  |     IBY_PAYGROUP_PUB package. That package is meant for normal
64  |     build program flow, whereas this package is meant for single
65  |     payments flow.
66  |
67  | PARAMETERS:
68  |     IN
69  |
70  |
71  |     OUT
72  |
73  |
74  | RETURNS:
75  |
76  | NOTES:
77  |
78  *---------------------------------------------------------------------*/
79  PROCEDURE createPayments(
80      p_payment_request_id         IN IBY_PAY_SERVICE_REQUESTS.
81                                          payment_service_request_id%TYPE,
82      p_pmt_rejection_level        IN IBY_INTERNAL_PAYERS_ALL.
83                                          payment_rejection_level_code%TYPE,
84      p_review_proposed_pmts_flag  IN IBY_INTERNAL_PAYERS_ALL.
85                                          require_prop_pmts_review_flag%TYPE,
86      p_override_complete_point    IN VARCHAR2,
87      p_bill_payable_flag          IN         VARCHAR2,
88      p_maturity_date              IN         DATE,
89      x_return_status      IN OUT NOCOPY VARCHAR2)
90  IS
91 
92  l_module_name           VARCHAR2(200) := G_PKG_NAME || '.createPayments';
93 
94  /* these are related to central bank reporting */
95  l_decl_option             VARCHAR2(100) := '';
96  l_decl_only_fx_flag       VARCHAR2(1)   := '';
97  l_decl_curr_fx_rate_type  VARCHAR2(255) := '';
98  l_decl_curr_code          VARCHAR2(10)  := '';
99  l_decl_threshold_amount   NUMBER(15)    := 0;
100 
101 /* Bug 5709596 */
102 -- l_cbrTab                  IBY_PAYGROUP_PUB.centralBankReportTabType;
103 
104  l_ca_payreq_cd            VARCHAR2(255) := '';
105  l_ca_id                   NUMBER(15)    := 0;
106  l_all_pmts_success_flag   BOOLEAN       := FALSE;
107  l_all_pmts_failed_flag    BOOLEAN       := FALSE;
108 
109  /* rejection level system options */
110  l_rejection_level         VARCHAR2(200);
111  l_review_pmts_flag        VARCHAR2(1)   := 'N';
112 
113  l_paymentTab        IBY_PAYGROUP_PUB.paymentTabType;
114  l_docsInPmtTab      IBY_PAYGROUP_PUB.docsInPaymentTabType;
115 
116  /* these two are passed to calling app via hook */
117  l_hookPaymentTab    IBY_PAYGROUP_PUB.hookPaymentTabType;
118  l_hookDocsInPmtTab  IBY_PAYGROUP_PUB.hookDocsInPaymentTabType;
119 
120  /* holds the error messages against failed documents */
121  l_docErrorTab       IBY_VALIDATIONSETS_PUB.docErrorTabType;
122  l_docTokenTab       IBY_VALIDATIONSETS_PUB.trxnErrTokenTabType;
123 
124  /* payment request imposed limits on payments */
125  /* not used but needs to be passed into performDocumentGrouping() method */
126  l_payReqCriteria    IBY_PAYGROUP_PUB.payReqImposedCriteria;
127 
128  BEGIN
129 
130      print_debuginfo(l_module_name, 'ENTER');
131 
132      print_debuginfo(l_module_name, 'Payment Request Id : '||
133          p_payment_request_id);
134 
135      /*
136       * Group the documents of the payment request into payments.
137       */
138      IBY_PAYGROUP_PUB.performDocumentGrouping(p_payment_request_id
139        , l_paymentTab
140        , l_docsInPmtTab
141        , l_ca_id
142        , l_ca_payreq_cd
143        , l_payReqCriteria
144 --     , l_cbrTab
145        );
146 
147      print_debuginfo(l_module_name, 'After grouping '
148          || l_paymentTab.COUNT   || ' payment(s) from '
149          || l_docsInPmtTab.COUNT || ' document(s) for payment request '
150          || p_payment_request_id || ' were created.'
151          );
152 
153      /*
154       * IMPORTANT CHECK FOR SINGLE PAYMENTS:
155       *
156       * After hardcoded grouping not more than one payment should be
157       * created from the given documents for the single payment flow.
158       *
159       * This is because the calling app is expected to have performed
160       * the hardcoded grouping before the single payment API is invoked.
161       *
162       * If we have created more than one payment from the given document,
163       * it is an error and return failure.
164       */
165      IF (l_paymentTab.COUNT <> 1) THEN
166 
167          print_debuginfo(l_module_name, 'Application of hardcoded '
168              || 'grouping rules did not generate exactly one payment. '
169              || 'Only one payment can be created for single payments. '
170              || 'Payment creation failed.'
171              );
172 
173          x_return_status := FND_API.G_RET_STS_ERROR;
174 
175          APP_EXCEPTION.RAISE_EXCEPTION;
176 
177      END IF;
178 
179      /*
180       * Fix for bug 5357948:
181       *
182       * Search for common attributes of the documents
183       * of each payment, and set the corresponding
184       * attribute on the parent payment itself if
185       * such a common attribute is found.
186       */
187      IBY_PAYGROUP_PUB.sweepCommonPmtAttributes(l_paymentTab, l_docsInPmtTab);
188 
189      /*
190       * Set the default attributes for the created payments.
191       */
192      initializePmts(l_paymentTab);
193 
194      /*
195       * Handle credit memos
196       */
197 
198      /*
199       * Update: Credit memo handling is now performed at the calling
200       * application itself.
201       * - rameshsh, 3/29/2005
202       */
203      --printDocsInPmtTab(l_docsInPmtTab);
204      --performCreditMemoHandling(l_paymentTab, l_docsInPmtTab);
205      --printDocsInPmtTab(l_docsInPmtTab);
206 
207      /*
208       * Maturity date calculation
209       *
210       * For bills payable
211       *   a.k.a promissory notes
212       *   a.k.a future dated payments
213       */
214 
215      /*
216       * Fix for bug 5334222:
217       *
218       * There is no need to calculate the maturity date for
219       * single payments. The maturity date for single payments
220       * is expected to be passed in.
221       *
222       * Simply assign the passed in maturity date to the
223       * created payment in case it is a bills payable.
224       */
225      IF (UPPER(p_bill_payable_flag) = 'Y') THEN
226 
227          /*
228           * We can use index 1 to access the payment because
229           * only one payment is expected to be created
230           * (this being a single payment).
231           */
232          l_paymentTab(1).maturity_date := p_maturity_date;
233 
234          /*
235           * Fix for bug 5334222:
236           *
237           * Set the bills payable flag to 'Y' whenever the
238           * maturity date is set.
239           */
240          l_paymentTab(1).bill_payable_flag := 'Y';
241 
242          print_debuginfo(l_module_name, 'Payment '
243              || l_paymentTab(1).payment_id
244              || ' is a bills payable; Maturity date '
245              || ' set to '
246              || l_paymentTab(1).maturity_date
247              );
248 
249      ELSE
250 
251          print_debuginfo(l_module_name, 'Not setting maturity '
252              || 'date for payment '
253              || l_paymentTab(1).payment_id
254              || ' as it is not a bill payable.'
255              );
256 
257      END IF;
258 
259      /*
260       * Fix for bug 5935493:
261       *
262       * Payment validations are dependent upon finding the
263       * payments in the IBY_PAYMENTS_ALL table. Therefore, insert
264       * the payments from the PLSQL table into the
265       * IBY_PAYMENTS_ALL table.
266       *
267       * Central bank reporting could be implemented via a hook
268       * that is expecting payments to be populated in
269       * IBY_PAYMENTS_ALL table. Therefore, payments need to
270       * inserted before performing central bank reporting as well.
271       */
272      IBY_PAYGROUP_PUB.insertPayments(l_paymentTab);
273 
274      /*
275       * Fix for bug 5972585:
276       *
277       * Update the documents payable that are part of the created
278       * payments with payment ids.
279       *
280       * This is normally done in performDBUpdates(..) call at
281       * the end of this method. However, some customers might
282       * want to do custom validations on documents that are
283       * part of the created payments. Therefore, update the
284       * documents with payment ids before the payment validation
285       * call.
286       *
287       * We do this even before central bank reporting because
288       * again the customer could potentially want to retrieve
289       * documents that are part of the created payments in the
290       * central bank reporting hook.
291       */
292      IBY_PAYGROUP_PUB.updateDocsWithPaymentID(l_docsInPmtTab);
293 
294      /*
295       * Fix for bug 5972585:
296       *
297       * Update the payments table with audit data before
298       * calling central bank reporting or payment validations.
299       *
300       * This is because the customer could have implemented
301       * custom central bank reporting or custom payment
302       * validations that could depend upon the denormalized
303       * payment attributes being present in the the payments
304       * table.
305       */
306 
307      /*
308       * Fix for bug 5511781:
309       *
310       * Along with the payment we insert the audit data for the
311       * payment as well. These are denormalized data from payment
312       * related tables like payee, payer, payee bank, payer bank
313       * etc.
314       *
315       * This information is also used by the extract and format
316       * logic.
317       */
318      IBY_PAYGROUP_PUB.auditPaymentData(l_paymentTab);
319 
320      /*
321       * Fix for bug 5337671:
322       *
323       * Perform central bank reporting prior to calling
324       * payment validations.
325       *
326       * This is because some validations are dependent upon
327       * whether the payment has the 'declare payment flag'
328       * set to 'Y'.
329       */
330 
331      /*
332       * Perform declarations / central bank reporting.
333       */
334      IBY_PAYGROUP_PUB.performCentralBankReporting(
335          l_paymentTab
336        , l_docsInPmtTab
337 --     , l_cbrTab
338          );
339 
340      /*
341       * Fix for bug 5935493:
342       *
343       * After central bank reporting is completed,
344       * the declare payments flag could be set on some/all
345       * payments by the hook. Therefore, we need to
346       * update the payments in IBY_PAYMENTS_ALL table
347       * so that this flag is accessible for validation.
348       */
349      IBY_PAYGROUP_PUB.updatePayments(l_paymentTab);
350 
351 
352      /*
353       * Payment validations
354       */
355      IBY_PAYGROUP_PUB.applyPaymentValidationSets(l_paymentTab,
356          l_docsInPmtTab, l_docErrorTab, l_docTokenTab);
357 
358 
359     /* Validation check for negative payment amounts
360      * Added for the Bug 7344352
361      */
362     negativePmtAmountCheck(l_paymentTab,
363          l_docsInPmtTab, l_docErrorTab, l_docTokenTab);
364 
365      /*
366       * Payment grouping number validation.
367       */
368 
369      /*
370       * Commented out because of performance impact
371       * - Ramesh, Nov 17 2006.
372       */
373      --IBY_PAYGROUP_PUB.performPmtGrpNumberValidation(l_paymentTab,
374      --    l_docsInPmtTab, l_docErrorTab, l_docTokenTab);
375 
376      /*
377       * Payment validation might have failed some payments (and by
378       * cascade, the documents that were part of these payments).
379       *
380       * Make sure to fail related documents whenever documents are
381       * failed.
382       */
383      IBY_PAYGROUP_PUB.adjustSisterDocsAndPmts(l_paymentTab,
384          l_docsInPmtTab, l_docErrorTab, l_docTokenTab);
385 
386      /*
387       * Call post-payment creation hook. This hook will pass
388       * the created payments to the calling application for
389       * approval/adjustment.
390       *
391       * The adjusted payments are read back and inserted into
392       * IBY_PAYMENTS_LL table.
393       *
394       * This is a general hook that is called for all other
395       * products except AP. For AP special hooks are called
396       * below.
397       */
398      IF (l_ca_id <> 200) THEN
399 
400          /*
401           * Only successful payments are passed to be passed to
402           * to the calling application via the hook / callout.
403           *
404           * From the existing list of all payments, create new data
405           * structures that only store successful payments. This
406           * 'success only' list of payments will be passed to the
407           * calling application.
408           *
409           * This method writes the payment data to global temp tables.
410           */
411          IBY_PAYGROUP_PUB.performPreHookProcess(
412              l_ca_payreq_cd, l_ca_id, l_paymentTab,
413              l_docsInPmtTab, l_hookPaymentTab,
414              l_hookDocsInPmtTab);
415 
416          /*
417           * Hook to call external application for implementation of the
418           * following functionality:
419           *
420           * 1. Bank charge calculation
421           * 2. Tax withtholding
422           *
423           * Any other miscellaneous correction of payment/document data
424           * is also allowed in the hook.
425           */
426          IBY_PAYGROUP_PUB.callHook(p_payment_request_id);
427 
428          /*
429           * The external app may decide not to pay a document(s)
430           * within a payment, or may decide not to make a payment(s).
431           * In such cases, the external app will set the 'don't pay flag'
432           * and provide a 'don't pay reason' at the document / payment
433           * level (as appropriate) in the provided data structures.
434           *
435           * If a document(s) is marked as don't pay, then we must
436           * adjust the payment amount appropriately.
437           *
438           * Also, some documents are related via 'payment grouping number'.
439           * All documents that are related must be failed and their
440           * constituent payment amounts must be adjusted
441           *
442           * This method reads the payment data from global temp tables.
443           */
444          IBY_PAYGROUP_PUB.performPostHookProcess(
445              l_paymentTab, l_docsInPmtTab,
446              l_hookPaymentTab, l_hookDocsInPmtTab,
447              l_docErrorTab, l_docTokenTab);
448 
449      END IF; -- if calling product <> AP
450 
451 
452      /*
453       * SPECIAL HOOKS FOR AP:
454       *
455       * NOTE:
456       * -----
457       * + Extended withholding hook should not be invoked for
458       *   single payments.
459       *
460       * + Japanese bank charges hook should not be invoked for
461       *   single payments.
462       */
463      IF (l_ca_id = 200) THEN
464          print_debuginfo(l_module_name, 'Not invoking any AP hooks.');
465      END IF;
466 
467      /*
468       * Flag payments that require separate remittance
469       * advice.
470       */
471      IBY_PAYGROUP_PUB.flagSeparateRemitAdvicePmts(l_paymentTab,
472          l_docsInPmtTab);
473 
474      /*
475       * Get the rejection level system option and pass
476       * it to subsequent methods.
477       */
478 
479      /*
480       * For single payments, there is no concept of
481       * payment rejection level system option. In the
482       * single payments flow, only one payment will be
483       * created, so if the payment fails, the request
484       * fails.
485       *
486       * So for single payments, the payment rejection
487       * level is implictly 'REQUEST'.
488       */
489      l_rejection_level := 'REQUEST';
490 
491      /*
492       * There is no question of reviewing the payment for
493       * single payments. Review payments flag is only
494       * applicable to standard payments built by the
495       * Build Program.
496       *
497       * Hardcode the review payments flag to 'N' for single
498       * payments.
499       */
500      l_review_pmts_flag := 'N';
501 
502      /*
503       * All payments for this payment request have been
504       * created and stored in a PLSQL table. Now write these
505       * payments to the database.
506       *
507       * Similarly, update the documents table by providing a
508       * payment id to each document.
509       */
510      performDBUpdates(p_payment_request_id, l_rejection_level,
511          l_review_pmts_flag, p_override_complete_point,
512          l_paymentTab, l_docsInPmtTab, l_all_pmts_success_flag,
513          l_all_pmts_failed_flag, x_return_status,
514          l_docErrorTab, l_docTokenTab
515          );
516 
517      /*
518       * NOTE:
519       *
520       * Do not raise business events / invoke callouts for
521       * single payments. This is because Single Payments API
522       * is a synchronous API and we do not commit any data if
523       * there are validation failures.
524       */
525 
526      print_debuginfo(l_module_name, 'EXIT');
527 
528  END createPayments;
529 
530 /*--------------------------------------------------------------------
531  | NAME:
532  |     performDBUpdates
533  |
534  | PURPOSE:
535  |     This is the top level method that is called by the
536  |     payment creation program to:
537  |         1. insert payments to DB
538  |         2. update documents with payment id
539  |         3. update status of payment request
540  |
541  |     This method will read the 'rejection level' system option
542  |     and do updates accordingly.
543  |
544  | PARAMETERS:
545  |     IN
546  |
547  |
548  |     OUT
549  |
550  |
551  | RETURNS:
552  |
553  |
554  | NOTES:
555  |
556  *---------------------------------------------------------------------*/
557  PROCEDURE performDBUpdates(
558      p_payreq_id          IN            IBY_PAY_SERVICE_REQUESTS.
559                                           payment_service_request_id%type,
560      p_rej_level          IN            VARCHAR2,
561      p_review_pmts_flag   IN            VARCHAR2,
562      p_override_compl_pt  IN            VARCHAR2,
563      x_paymentTab         IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
564      x_docsInPmtTab       IN OUT NOCOPY IBY_PAYGROUP_PUB.docsInPaymentTabType,
565      x_allPmtsSuccessFlag IN OUT NOCOPY BOOLEAN,
566      x_allPmtsFailedFlag  IN OUT NOCOPY BOOLEAN,
567      x_return_status      IN OUT NOCOPY VARCHAR2,
568      x_docErrorTab        IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.
569                                             docErrorTabType,
570      x_errTokenTab        IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.
571                                             trxnErrTokenTabType
572      )
573  IS
574  l_module_name       VARCHAR2(200)  := G_PKG_NAME || '.performDBUpdates';
575  l_allsuccess_flag   BOOLEAN := TRUE;
576  l_allfailed_flag    BOOLEAN := TRUE;
577  l_request_status    VARCHAR2(200);
578 
579  --l_doc_err_rec       IBY_VALIDATIONSETS_PUB.docErrorRecType;
580  l_doc_err_rec       IBY_TRANSACTION_ERRORS%ROWTYPE;
581 
582  l_triggering_pmt_id IBY_PAYMENTS_ALL.payment_id%TYPE;
583 
584  BEGIN
585 
586      print_debuginfo(l_module_name, 'ENTER');
587 
588      /*
589       * Print the rejection level system option
590       */
591      print_debuginfo(l_module_name, 'Rejection level system option set to: '
592          || p_rej_level);
593 
594      /*
595       * Find out whether all the payments within this
596       * payment request have 'success' status. This
597       * information is used below.
598       */
599      FOR i in  x_paymentTab.FIRST ..  x_paymentTab.LAST LOOP
600          IF (x_paymentTab(i).payment_status <> PAY_STATUS_CREATED) THEN
601              l_triggering_pmt_id := x_paymentTab(i).payment_id;
602              l_allsuccess_flag := FALSE;
603              print_debuginfo(l_module_name, 'At least one payment has '
604                  || 'failed validation.');
605              EXIT WHEN (1=1);
606          END IF;
607      END LOOP;
608 
609      /*
610       * Check if all payments have failed for this
611       * payment request. This information is used below.
612       */
613      FOR i in  x_paymentTab.FIRST .. x_paymentTab.LAST LOOP
614          IF (x_paymentTab(i).payment_status = PAY_STATUS_CREATED) THEN
615              l_allfailed_flag := FALSE;
616              print_debuginfo(l_module_name, 'At least one payment has '
617                  || 'has been successfully validated.');
618              EXIT WHEN (1=1);
619          END IF;
620      END LOOP;
621 
622      /*
623       * Update the status of the payments/documents
624       * as per the rejection level (if necessary).
625       */
626      IF (p_rej_level = REJ_LVL_REQUEST) THEN
627 
628          IF (l_allsuccess_flag = FALSE) THEN
629              /*
630               * This means that at least one payment in this
631               * payment request has failed.
632               *
633               * For 'request' rejection level:
634               * If any payment in the request fails validation,
635               * the entire payment request should be rejected;
636               * So fail all payments in this payment request.
637               */
638              print_debuginfo(l_module_name, 'Failing all payments and '
639                      || 'documents for payment request '
640                      || p_payreq_id);
641              FOR i in  x_paymentTab.FIRST ..  x_paymentTab.LAST LOOP
642 
643                  IF (x_paymentTab(i).payment_status = PAY_STATUS_CREATED) THEN
644 
645                      x_paymentTab(i).payment_status :=
646                          PAY_STATUS_FAIL_BY_REJLVL;
647 
648                      /*
649                       * Once we fail a payment, we need to create
650                       * an error record and insert this record
651                       * into the errors table.
652                       */
653                      IBY_BUILD_UTILS_PKG.createErrorRecord(
654                          TRXN_TYPE_PMT,
655                          x_paymentTab(i).payment_id,
656                          x_paymentTab(i).payment_status,
657                          NULL,
658                          x_paymentTab(i).payment_id,
659                          NULL,
660                          NULL,
661                          NULL,
662                          NULL,
663                          NULL,
664                          l_doc_err_rec,
665                          x_errTokenTab,
666                          l_triggering_pmt_id
667                          );
668 
669                      IBY_VALIDATIONSETS_PUB.insertIntoErrorTable(
670                          l_doc_err_rec, x_docErrorTab, x_errTokenTab);
671 
672                      IBY_PAYGROUP_PUB.failDocsOfPayment(
673                          x_paymentTab(i).payment_id,
674                          DOC_STATUS_PAY_VAL_FAIL,
675                          x_docsInPmtTab, x_docErrorTab,
676                          x_errTokenTab);
677 
678                  END IF;
679 
680              END LOOP;
681 
682              /* set the status of the payment request to failed */
683              l_request_status := REQ_STATUS_FAIL_PAY_CR;
684 
685          ELSE
686 
687              /*
688               * For single payments, ignore the review proposed
689               * payments flag and blindly set the request status
690               * to 'payments created'.
691               */
692 
693              /* set the status of the payment request to pmts created */
694              l_request_status := REQ_STATUS_PAY_CRTD;
695 
696          END IF;
697 
698      ELSIF (p_rej_level = REJ_LVL_PAYMENT) THEN
699 
700          /*
701           * Check if all payments in the request have failed.
702           */
703          IF (l_allfailed_flag = TRUE) THEN
704 
705              l_request_status := REQ_STATUS_FAIL_PAY_CR;
706 
707          ELSE
708 
709              /*
710               * At least one payment in the request was
711               * successful.
712               */
713 
714              /*
715               * For single payments, ignore the review proposed
716               * payments flag and blindly set the payment
717               * status to 'payments created'.
718               */
719 
720              /* set the status of the payment request to pmts created */
721              l_request_status := REQ_STATUS_PAY_CRTD;
722 
723              print_debuginfo(l_module_name, 'Review proposed payments '
724                  || 'flag has not been set. Setting status of successful '
725                  || 'request to created.');
726 
727          END IF;
728 
729      ELSIF (p_rej_level = REJ_LVL_NONE) THEN
730 
731          /*
732           * For single payments, ignore the review proposed
733           * payments flag and the user review errors flag.
734           */
735          IF (l_allfailed_flag = TRUE) THEN
736              l_request_status := REQ_STATUS_FAIL_PAY_CR;
737          ELSE
738              l_request_status := REQ_STATUS_PAY_CRTD;
739          END IF;
740 
741      ELSE
742 
743          print_debuginfo(l_module_name, 'Unknown rejection level: '
744              || p_rej_level
745              || '. Aborting payment creation ..' );
746 
747          APP_EXCEPTION.RAISE_EXCEPTION;
748 
749      END IF;
750 
751      /*
752       * If this single payment has been created successfully,
753       * and the override completion point flag is set, then set
754       * the payment completed flag to 'yes'.
755       */
756      IF (x_allPmtsSuccessFlag = TRUE) THEN
757          IF (UPPER(p_override_compl_pt) = 'Y') THEN
758              FOR i IN x_paymentTab.FIRST .. x_paymentTab.LAST LOOP
759                  x_paymentTab(i).payments_complete_flag := 'Y';
760              END LOOP;
761          END IF;
762      END IF;
763 
764      /*
765       * All payments for this payment request have been
766       * created and stored in a PLSQL table. Now write these
767       * payments to the database.
768       */
769      IBY_PAYGROUP_PUB.updatePayments(x_paymentTab);
770 
771      /*
772       * Update the documents table by providing a payment id to
773       * each document.
774       */
775      IBY_PAYGROUP_PUB.updateDocsWithPaymentID(x_docsInPmtTab);
776 
777      /*
778       * If any payments/documents were failed, the IBY_TRANSACTION_
779       * ERRORS table must be populated with the corresponding error
780       * messages.
781       */
782      IBY_VALIDATIONSETS_PUB.insert_transaction_errors('N', x_docErrorTab,
783          x_errTokenTab);
784 
785      /*
786       * Update the status of the payment request.
787       */
788      print_debuginfo(l_module_name, 'Updating status of payment request '
789          || p_payreq_id || ' to ' || l_request_status || '.');
790 
791      UPDATE
792          IBY_PAY_SERVICE_REQUESTS
793      SET
794          payment_service_request_status = l_request_status
795      WHERE
796          payment_service_request_id = p_payreq_id
797      ;
798 
799      /* Pass back the request status to the caller */
800      x_return_status := l_request_status;
801 
802      /*
803       * Pass the 'all payments success' and 'all payments
804       * failed' flags back to the caller.
805       *
806       * These flag will be used in raising business events.
807       */
808      x_allPmtsSuccessFlag := l_allsuccess_flag;
809      x_allPmtsFailedFlag  := l_allfailed_flag;
810 
811      print_debuginfo(l_module_name, 'EXIT');
812 
813  EXCEPTION
814 
815      WHEN OTHERS THEN
816          print_debuginfo(l_module_name, 'Fatal: Exception when updating '
817              || 'payment request/payment/document status after payment '
818              || 'creation. All changes will be rolled back. Payment request '
819              || 'id is ' || p_payreq_id);
820          print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
821          print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
822 
823          /*
824           * Propogate exception to caller.
825           */
826          RAISE;
827 
828  END performDBUpdates;
829 
830 /*--------------------------------------------------------------------
831  | NAME:
832  |     initializePmts
833  |
834  | PURPOSE:
835  |     Sets the default attributes for a created payment such as
836  |     payment status, process type etc.
837  |
838  | PARAMETERS:
839  |     IN
840  |
841  |
842  |     OUT
843  |
844  |
845  | RETURNS:
846  |
847  | NOTES:
848  |
849  *---------------------------------------------------------------------*/
850  PROCEDURE initializePmts(
851      x_paymentTab      IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType
852      )
853  IS
854  BEGIN
855 
856      IF (x_paymentTab.COUNT = 0) THEN
857          RETURN;
858      END IF;
859 
860      FOR i IN x_paymentTab.FIRST .. x_paymentTab.LAST LOOP
861 
862          x_paymentTab(i).payment_status                 := 'CREATED';
863          x_paymentTab(i).process_type                   := 'IMMEDIATE';
864          x_paymentTab(i).payments_complete_flag         := 'N';
865          x_paymentTab(i).bill_payable_flag              := 'N';
866          x_paymentTab(i).exclusive_payment_flag         := 'N';
867          x_paymentTab(i).separate_remit_advice_req_flag := 'N';
868          x_paymentTab(i).declare_payment_flag           := 'N';
869          x_paymentTab(i).pregrouped_payment_flag        := 'N';
870          x_paymentTab(i).stop_confirmed_flag            := 'N';
871          x_paymentTab(i).stop_released_flag             := 'N';
872          x_paymentTab(i).stop_request_placed_flag       := 'N';
873          x_paymentTab(i).created_by                     := fnd_global.user_id;
874          x_paymentTab(i).creation_date                  := sysdate;
875          x_paymentTab(i).last_updated_by                := fnd_global.user_id;
876          x_paymentTab(i).last_update_login              := fnd_global.user_id;
877          x_paymentTab(i).last_update_date               := sysdate;
878          x_paymentTab(i).object_version_number          := 1;
879 
880      END LOOP;
881 
882  END initializePmts;
883 
884 
885  /*--------------------------------------------------------------------
886  | NAME:
887  |     negativePmtAmountCheck
888  |
889  | PURPOSE: Validation to check that payment amount is not a negative
890  |value
891  |
892  | PARAMETERS:
893  |     IN
894  |
895  |
896  |     OUT
897  |
898  |
899  | RETURNS:
900  |
901  | NOTES: Added for the bug 7344352
902  |
903  *---------------------------------------------------------------------*/
904  PROCEDURE negativePmtAmountCheck(
905      x_paymentTab      IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
906      x_docsInPmtTab  IN OUT NOCOPY IBY_PAYGROUP_PUB.docsInPaymentTabType,
907      x_docErrorTab   IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.docErrorTabType,
908      x_errTokenTab   IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.trxnErrTokenTabType
909      )
910  IS
911   l_module_name   VARCHAR2(200)  := G_PKG_NAME || '.negativePmtAmountCheck';
912   l_doc_err_rec   IBY_TRANSACTION_ERRORS%ROWTYPE;
913   l_error_code    VARCHAR2(100);
914   l_error_msg     VARCHAR2(500);
915   l_token_rec     IBY_TRXN_ERROR_TOKENS%ROWTYPE;
916  BEGIN
917             print_debuginfo(l_module_name, 'ENTER');
918 
919 	         FOR i in x_paymentTab.FIRST ..  x_paymentTab.LAST LOOP
920 
921                       IF (x_paymentTab(i).payment_status = PAY_STATUS_CREATED) THEN
922 
923 			    IF (x_paymentTab(i).payment_amount < 0) THEN
924 
925 				 x_paymentTab(i).payment_status
926 				     := PAY_STATUS_REJECTED;
927 
928 				 print_debuginfo(l_module_name, 'Failed payment '
929 				     || x_paymentTab(i).payment_id
930 				     || ' because payment amount '
931 				     || x_paymentTab(i).payment_amount
932                                      ||' is less than zero'
933 				     );
934 
935 				 l_error_code := 'IBY_PMT_NEGATIVE_AMT';
936 				 FND_MESSAGE.set_name('IBY', l_error_code);
937 
938 				 FND_MESSAGE.SET_TOKEN('PMT_AMOUNT',
939 				     x_paymentTab(i).payment_amount,
940 				     FALSE);
941 
942 				 l_token_rec.token_name  := 'PMT_AMOUNT';
943 				 l_token_rec.token_value := x_paymentTab(i).payment_amount;
944 				 x_errTokenTab(x_errTokenTab.COUNT + 1) := l_token_rec;
945 
946 				 /*
947 				  * Once we fail a payment, we need to create
948 				  * an error record and insert this record
949 				  * into the errors table.
950 				  */
951 				 IBY_BUILD_UTILS_PKG.createPmtErrorRecord(
952 				     x_paymentTab(i).payment_id,
953 				     x_paymentTab(i).payment_status,
954 				     l_error_code,
955 				     FND_MESSAGE.get,
956 				     l_doc_err_rec
957 				     );
958 
959 				 IBY_VALIDATIONSETS_PUB.insertIntoErrorTable(
960 				     l_doc_err_rec, x_docErrorTab, x_errTokenTab);
961 
962 				 /* fail the docs of this payment */
963 				 IBY_PAYGROUP_PUB.failDocsOfPayment(x_paymentTab(i).payment_id,
964 				     DOC_STATUS_PAY_VAL_FAIL, x_docsInPmtTab,
965 				     x_docErrorTab, x_errTokenTab);
966 
967 			     END IF;
968 			 END IF;
969 	        END LOOP;
970             print_debuginfo(l_module_name, 'EXIT');
971  END negativePmtAmountCheck;
972 
973 
974 
975 
976 /*--------------------------------------------------------------------
977  | NAME:
978  |     print_debuginfo
979  |
980  | PURPOSE:
981  |     This procedure prints the debug message to the concurrent manager
982  |     log file.
983  |
984  | PARAMETERS:
985  |     IN
986  |      p_debug_text - The debug message to be printed
987  |
988  |     OUT
989  |
990  |
991  | RETURNS:
992  |
993  | NOTES:
994  |
995  *---------------------------------------------------------------------*/
996  PROCEDURE print_debuginfo(p_module IN VARCHAR2,
997      p_debug_text IN VARCHAR2)
998  IS
999 
1000  BEGIN
1001 
1002      /*
1003       * Write the debug message to the concurrent manager log file.
1004       */
1005      iby_build_utils_pkg.print_debuginfo(p_module, p_debug_text);
1006 
1007  END print_debuginfo;
1008 
1009 
1010 END IBY_SINGPAY_PUB;