DBA Data[Home] [Help]

PACKAGE BODY: APPS.IBY_SINGPAY_PUB

Source


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