DBA Data[Home] [Help]

PACKAGE BODY: APPS.IBY_CHECKNUMBER_PUB

Source


1 PACKAGE BODY IBY_CHECKNUMBER_PUB AS
2 /*$Header: ibyckprb.pls 120.85.12020000.4 2013/02/20 09:55:57 sgogula ship $*/
3 
4  --
5  -- Declare global variables
6  --
7  G_PKG_NAME CONSTANT VARCHAR2(30) := 'IBY_CHECKNUMBER_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  --
12  -- List of instruction statuses that are used / set in this
13  -- module (payment instruction creation flow).
14  --
15  -- This module will only process payment instructions that are in
16  -- 'created' status.
17  --
18  -- If there were any problems when numbering the payment instructions
19  -- this module will set the status of the payment instruction to
20  -- 'printing deferred' status and the check printing module has to
21  -- be called again on this payment instruction.
22  --
23  -- This module will never set the status of a payment instruction to
24  -- 'creation error' because that can only be done by the PICP.
25  --
26  INS_STATUS_CREATED         CONSTANT VARCHAR2(100) := 'CREATED';
27  INS_STATUS_PRINT_DEFR      CONSTANT VARCHAR2(100) := 'PRINTING_DEFERRED';
28  INS_STATUS_READY_TO_PRINT  CONSTANT VARCHAR2(100) :=
29                                          'CREATED_READY_FOR_PRINTING';
30  INS_STATUS_READY_TO_FORMAT CONSTANT VARCHAR2(100) :=
31                                          'CREATED_READY_FOR_FORMATTING';
32 
33  --
34  -- List of payment statuses that are used / set in this
35  -- module (payment instruction creation flow).
36  --
37  PMT_STATUS_CREATED        CONSTANT VARCHAR2(100) := 'CREATED';
38  PMT_STATUS_INS_CREATED    CONSTANT VARCHAR2(100) := 'INSTRUCTION_CREATED';
39 
40  --
41  -- List of document statuses that are used / set in this
42  -- module (payment instruction creation flow).
43  --
44  DOC_STATUS_PAY_CREATED    CONSTANT VARCHAR2(100) := 'PAYMENT_CREATED';
45 
46  -- Transaction types (for inserting into IBY_TRANSACTION_ERRORS table)
47  TRXN_TYPE_INSTR  CONSTANT VARCHAR2(100) := 'INSTRUCTION';
48  TRXN_TYPE_PMT    CONSTANT VARCHAR2(100) := 'PAYMENT';
49 
50  --
51  -- List of process ciompletion statuses that are returned to
52  -- the caller after completing this flow.
53  --
54  PROCESS_STATUS_SUCCESS   CONSTANT VARCHAR2(100) := 'SUCCESS';
55  PROCESS_STATUS_FAILED    CONSTANT VARCHAR2(100) := 'FAILURE';
56  /*
57   * List of process types.
58   */
59  PROCESS_TYPE_IMMEDIATE CONSTANT VARCHAR2(100) := 'IMMEDIATE';
60  PROCESS_TYPE_STANDARD  CONSTANT VARCHAR2(100) := 'STANDARD';
61  PROCESS_TYPE_MANUAL    CONSTANT VARCHAR2(100) := 'MANUAL';
62 
63  --
64  -- Forward declarations
65  --
66  PROCEDURE print_debuginfo(
67               p_module      IN VARCHAR2,
68               p_debug_text  IN VARCHAR2,
69               p_debug_level IN VARCHAR2 DEFAULT FND_LOG.LEVEL_STATEMENT
70               );
71 
72 /*--------------------------------------------------------------------
73  | NAME:
74  |     performCheckNumbering
75  |
76  | PURPOSE:
77  |     Prints the given payment instruction on the provided paper stock
78  |     (payment document).
79  |
80  |
81  | PARAMETERS:
82  |     IN
83  |
84  |
85  |     OUT
86  |
87  |
88  | RETURNS:
89  |
90  | NOTES:
91  |
92  |
93  *---------------------------------------------------------------------*/
94  PROCEDURE performCheckNumbering(
95              p_instruction_id           IN IBY_PAY_INSTRUCTIONS_ALL.
96                                                payment_instruction_id%TYPE,
97              p_pmt_document_id          IN CE_PAYMENT_DOCUMENTS.
98                                                payment_document_id%TYPE,
99              p_user_assgn_num           IN IBY_PAYMENTS_ALL.
100                                                paper_document_number%TYPE,
101              x_return_status            IN OUT NOCOPY VARCHAR2,
102              x_return_message           IN OUT NOCOPY VARCHAR2,
103              x_msg_count                IN OUT NOCOPY NUMBER,
104              x_msg_data                 IN OUT NOCOPY VARCHAR2
105              )
106  IS
107 
108  l_module_name       VARCHAR2(200) := G_PKG_NAME || '.performCheckNumbering';
109 
110  l_ret_status        NUMBER := -1;
111  l_ret_message       VARCHAR2(2000);
112 
113  l_pmtInstrRec       IBY_PAY_INSTRUCTIONS_ALL%ROWTYPE;
114 
115  l_pmtsInInstrRec    IBY_PAYINSTR_PUB.pmtsInPmtInstrRecType;
116  l_pmtsInInstrTab    IBY_PAYINSTR_PUB.pmtsInpmtInstrTabType;
117 
118  l_error_code        VARCHAR2(500);
119 
120  l_instruction_id    NUMBER(15);
121 
122  /*
123   * These two are used for holding dummy payments and dummy
124   * documents that are associated with setup and overflow
125   * documents.
126   */
127  l_dummy_pmts_tab    IBY_PAYGROUP_PUB.paymentTabType;
128  l_dummy_docs_tab    docsTabType;
129  l_overflow_docs_tab overflowDocsTabType;
130 
131  l_instr_err_tab     IBY_VALIDATIONSETS_PUB.docErrorTabType;
132  l_err_tokens_tab    IBY_VALIDATIONSETS_PUB.trxnErrTokenTabType;
133 
134  l_pkg_name          CONSTANT VARCHAR2(100) := 'AP_AWT_CALLOUT_PKG';
135 
136  l_callout_name      VARCHAR2(500);
137  l_stmt              VARCHAR2(1000);
138 
139  /* used in invocation of callout procedure */
140  l_api_version       CONSTANT NUMBER := 1.0;
141  l_msg_count         NUMBER;
142  l_msg_data          VARCHAR2(2000);
143 
144  /*
145   * Cursor to pick up the payments (and related fields)
146   * of a given payment instruction.
147   */
148  CURSOR c_pmts_in_instruction (p_instr_id IBY_PAY_INSTRUCTIONS_ALL.
149                                               payment_instruction_id%TYPE)
150  IS
151  SELECT
152      pmt.payment_id,
153      instr.payment_instruction_id,
154      pmt.payment_amount,
155      pmt.payment_currency_code,
156      pmt.payment_status,
157      pmt.payment_profile_id,
158      prof.processing_type,
159      -1, /* pmt_details_len */
160      -1, /* document_count */
161      pmt.separate_remit_advice_req_flag,
162      pmt.paper_document_number
163  FROM
164      IBY_PAYMENTS_ALL pmt,
165      IBY_PAY_INSTRUCTIONS_ALL instr,
166      IBY_PAYMENT_PROFILES prof
167  WHERE
168      instr.payment_instruction_id = p_instr_id AND
169      instr.payment_instruction_id = pmt.payment_instruction_id AND
170      instr.payment_profile_id     = pmt.payment_profile_id AND
171      instr.payment_profile_id     = prof.payment_profile_id AND
172      pmt.payment_status           = PMT_STATUS_INS_CREATED
173 
174  /*
175   * Fix for bug 5198523:
176   *
177   * Ordering the payments by payment reference number
178   * guarantees that the paper document numbers provided
179   * to these payments downstream also follow the same
180   * order.
181   */
182  ORDER BY pmt.payment_reference_number ASC
183  ;
184 
185 
186  /*
187   * Implementing the callout is optional for the calling app.
188   * If the calling app does not implement the hook, then
189   * the call to the hook will result in ORA-06576 error.
190   *
191   * There is no exception name associated with this code, so
192   * we create one called 'PROCEDURE_NOT_IMPLEMENTED'. If this
193   * exception occurs, it is not fatal: we log the error and
194   * proceed.
195   *
196   * If, on the other hand, the calling app implements the
197   * callout, but the callout throws an exception, it is fatal
198   * and we must abort the program (this will be caught
199   * in WHEN OTHERS block).
200   */
201  PROCEDURE_NOT_IMPLEMENTED EXCEPTION;
202  PRAGMA EXCEPTION_INIT(PROCEDURE_NOT_IMPLEMENTED, -6576);
203 
204  BEGIN
205      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
206 	     print_debuginfo(l_module_name, 'ENTER');
207 
208 	     print_debuginfo(l_module_name, 'Provided payment instruction id: '
209 	         || p_instruction_id);
210 
211      END IF;
212      /*
213       * Pick up all attributes of the given payment instruction
214       * from the IBY_PAY_INSTRUCTIONS_ALL table.
215       */
216      BEGIN
217 
218          SELECT
219              payment_instruction_id,
220              payment_profile_id,
221              process_type,
222              payment_instruction_status,
223              payments_complete_code,
224              generate_sep_remit_advice_flag,
225              remittance_advice_created_flag,
226              regulatory_report_created_flag,
227              bill_payable_flag,
228              legal_entity_id,
229              payment_count,
230              positive_pay_file_created_flag,
231              print_instruction_immed_flag,
232              transmit_instr_immed_flag,
233              created_by,
234              creation_date,
235              last_updated_by,
236              last_update_date,
237              last_update_login,
238              object_version_number,
239              internal_bank_account_id,
240              pay_admin_assigned_ref_code,
241              transmission_date,
242              acknowledgement_date,
243              comments,
244              bank_assigned_ref_code,
245              org_id,
246              org_type,
247              payment_date,
248              payment_currency_code,
249              payment_service_request_id,
250              payment_function,
251              payment_reason_code,
252              rfc_identifier,
253              payment_reason_comments,
254              payment_document_id,
255              printer_name,
256              attribute_category,
257              attribute1,
258              attribute2,
259              attribute3,
260              attribute4,
261              attribute5,
262              attribute6,
263              attribute7,
264              attribute8,
265              attribute9,
266              attribute10,
267              attribute11,
268              attribute12,
269              attribute13,
270              attribute14,
271              attribute15
272          INTO
273              l_pmtInstrRec.payment_instruction_id,
274              l_pmtInstrRec.payment_profile_id,
275              l_pmtInstrRec.process_type,
276              l_pmtInstrRec.payment_instruction_status,
277              l_pmtInstrRec.payments_complete_code,
278              l_pmtInstrRec.generate_sep_remit_advice_flag,
279              l_pmtInstrRec.remittance_advice_created_flag,
280              l_pmtInstrRec.regulatory_report_created_flag,
281              l_pmtInstrRec.bill_payable_flag,
282              l_pmtInstrRec.legal_entity_id,
283              l_pmtInstrRec.payment_count,
284              l_pmtInstrRec.positive_pay_file_created_flag,
285              l_pmtInstrRec.print_instruction_immed_flag,
286              l_pmtInstrRec.transmit_instr_immed_flag,
287              l_pmtInstrRec.created_by,
288              l_pmtInstrRec.creation_date,
289              l_pmtInstrRec.last_updated_by,
290              l_pmtInstrRec.last_update_date,
291              l_pmtInstrRec.last_update_login,
292              l_pmtInstrRec.object_version_number,
293              l_pmtInstrRec.internal_bank_account_id,
294              l_pmtInstrRec.pay_admin_assigned_ref_code,
295              l_pmtInstrRec.transmission_date,
296              l_pmtInstrRec.acknowledgement_date,
297              l_pmtInstrRec.comments,
298              l_pmtInstrRec.bank_assigned_ref_code,
299              l_pmtInstrRec.org_id,
300              l_pmtInstrRec.org_type,
301              l_pmtInstrRec.payment_date,
302              l_pmtInstrRec.payment_currency_code,
303              l_pmtInstrRec.payment_service_request_id,
304              l_pmtInstrRec.payment_function,
305              l_pmtInstrRec.payment_reason_code,
306              l_pmtInstrRec.rfc_identifier,
307              l_pmtInstrRec.payment_reason_comments,
308              l_pmtInstrRec.payment_document_id,
309              l_pmtInstrRec.printer_name,
310              l_pmtInstrRec.attribute_category,
311              l_pmtInstrRec.attribute1,
312              l_pmtInstrRec.attribute2,
313              l_pmtInstrRec.attribute3,
314              l_pmtInstrRec.attribute4,
315              l_pmtInstrRec.attribute5,
316              l_pmtInstrRec.attribute6,
317              l_pmtInstrRec.attribute7,
318              l_pmtInstrRec.attribute8,
319              l_pmtInstrRec.attribute9,
320              l_pmtInstrRec.attribute10,
321              l_pmtInstrRec.attribute11,
322              l_pmtInstrRec.attribute12,
323              l_pmtInstrRec.attribute13,
324              l_pmtInstrRec.attribute14,
325              l_pmtInstrRec.attribute15
326          FROM
327              IBY_PAY_INSTRUCTIONS_ALL
328          WHERE
329              payment_instruction_id = p_instruction_id
330              ;
331 
332      EXCEPTION
333 
334          WHEN OTHERS THEN
335          /*
336           * This error condition will be handled below.
337           */
338          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
339 	         print_debuginfo(l_module_name, 'Exception occured when '
340 	             || 'retrieving details of payment instruction '
341 	             || p_instruction_id
342 	             );
343 	         print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
344 	         print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
345 
346          END IF;
347      END;
348 
349      IF (l_pmtInstrRec.payment_instruction_id IS NULL) THEN
350 
351          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
352 	         print_debuginfo(l_module_name, 'Provided payment instruction id '
353 	             || p_instruction_id
354 	             || ' not found in IBY_PAY_INSTRUCTIONS_ALL table. '
355 	             || 'Processing cannot continue. Aborting program.'
356 	             );
357 
358          END IF;
359          x_return_status := FND_API.G_RET_STS_ERROR;
360 
361          l_error_code := 'IBY_INS_NOT_FOUND';
362          FND_MESSAGE.set_name('IBY', l_error_code);
363 
364          FND_MESSAGE.SET_TOKEN('INS_ID',
365              p_instruction_id,
366              FALSE);
367 
368          x_return_message := FND_MESSAGE.get;
369 
370          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
371 	         print_debuginfo(l_module_name, 'EXIT');
372 
373          END IF;
374          RETURN;
375 
376      END IF;
377 
378      /*
379       * Only proceed if the payment instruction is in the
380       * 'created' status.
381       */
382      IF (l_pmtInstrRec.payment_instruction_status
383              <> INS_STATUS_CREATED                    AND
384          l_pmtInstrRec.payment_instruction_status
385              <> INS_STATUS_READY_TO_PRINT             AND
386          l_pmtInstrRec.payment_instruction_status
387              <> INS_STATUS_READY_TO_FORMAT
388         ) THEN
389 
390          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
391 	         print_debuginfo(l_module_name, 'Payment instruction id '
392 	             || p_instruction_id
393 	             || ' has status '
394 	             || l_pmtInstrRec.payment_instruction_status
395 	             || '. Payment instruction must be in '
396 	             || INS_STATUS_READY_TO_PRINT
397 	             || ' or '
398 	             || INS_STATUS_READY_TO_FORMAT
399 	             || ' for check numbering. '
400 	             || 'Processing cannot continue. Aborting program.'
401 	             );
402 
403          END IF;
404          x_return_status  := FND_API.G_RET_STS_ERROR;
405 
406          l_error_code := 'IBY_INS_NOT_NUM_STATUS';
407          FND_MESSAGE.set_name('IBY', l_error_code);
408 
409          FND_MESSAGE.SET_TOKEN('INS_ID',
410              p_instruction_id,
411              FALSE);
412 
413          FND_MESSAGE.SET_TOKEN('BAD_STATUS',
414              l_pmtInstrRec.payment_instruction_status,
415              FALSE);
416 
417          FND_MESSAGE.SET_TOKEN('GOOD_STATUS1',
418              INS_STATUS_READY_TO_PRINT,
419              FALSE);
420 
421          FND_MESSAGE.SET_TOKEN('GOOD_STATUS2',
422              INS_STATUS_READY_TO_FORMAT,
423              FALSE);
424 
425          FND_MESSAGE.SET_TOKEN('GOOD_STATUS3',
426              INS_STATUS_CREATED,
427              FALSE);
428 
429          x_return_message := FND_MESSAGE.get;
430 
431          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
432 	         print_debuginfo(l_module_name, 'EXIT');
433 
434          END IF;
435          RETURN;
436 
437      ELSE
438 
439          /*
440           * If we reached here, it means that the given payment
441           * instruction is in an appropriate status for numbering.
442           *
443           * SPECIAL CASE:
444           *
445           * Check for a special case, where this payment instruction
446           * might have already been numbered earlier, but the format
447           * program crashed or raised an exception. In that case, the
448           * status of the payment instruction would not have been
449           * changed.
450           *
451           * Such a payment instruction would re-enter the check
452           * numbering flow, but we must not renumber this instruction
453           * because we have already numbered it.
454           *
455           * If the specified payment document is already locked by the
456           * given payment instruction, then we know that this payment
457           * instruction has already been numbered and is re-entering
458           * the check numbering flow.
459           *
460           * Simply return success and exit.
461           */
462          BEGIN
463 
464              SELECT
465                  ce.payment_instruction_id
466              INTO
467                  l_instruction_id
468              FROM
469                  CE_PAYMENT_DOCUMENTS ce
470              WHERE
471                  ce.payment_document_id = p_pmt_document_id
472              ;
473 
474              IF (l_instruction_id = p_instruction_id) THEN
475 
476                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
477 	                 print_debuginfo(l_module_name, 'Payment instruction '
478 	                     || p_instruction_id
479 	                     || ' has already been numbered. Returning '
480 	                     || 'success response ..'
481 	                     );
482 
483                  END IF;
484                  x_return_status  := FND_API.G_RET_STS_SUCCESS;
485                  x_return_message := 'SUCCESS';
486 
487                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
488 	                 print_debuginfo(l_module_name, 'EXIT');
489 
490                  END IF;
491                  RETURN;
492 
493              ELSE
494 
495                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
496 	                 print_debuginfo(l_module_name, 'Payment instruction '
497 	                     || p_instruction_id
498 	                     || ' has not been previously numbered.'
499 	                     );
500 
501                  END IF;
502              END IF;
503 
504 
505          EXCEPTION
506              WHEN OTHERS THEN
507 
508 
509 	             print_debuginfo(l_module_name, 'Exception occured when '
510 	                 || 'getting details of payment document id '
511 	                 || p_pmt_document_id
512 	                 || ' from CE_PAYMENT_DOCUMENTS table.',
513 	                 FND_LOG.LEVEL_UNEXPECTED
514 	                 );
515 
516 	             print_debuginfo(l_module_name, 'SQL code: '
517 	                 || SQLCODE, FND_LOG.LEVEL_UNEXPECTED);
518 	             print_debuginfo(l_module_name, 'SQL err msg: '
519 	                 || SQLERRM, FND_LOG.LEVEL_UNEXPECTED);
520 
521 
522              /*
523               * Propogate exception to caller.
524               */
525              RAISE;
526 
527          END;
528 
529      END IF;
530 
531      /*
532       * Pick up all payments of the given payment instruction
533       * from the IBY_PAYMENTS_ALL table.
534       */
535      OPEN  c_pmts_in_instruction(p_instruction_id);
536      FETCH c_pmts_in_instruction BULK COLLECT INTO l_pmtsInInstrTab;
537      CLOSE c_pmts_in_instruction;
538 
539      IF (l_pmtsInInstrTab.COUNT = 0) THEN
540 
541          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
542 	         print_debuginfo(l_module_name, 'Cannot retrieve payments '
543 	             || 'and profile details for the provided payment '
544 	             || 'instruction id. Processing cannot continue. '
545 	             || 'Aborting program.'
546 	             );
547 
548          END IF;
549          x_return_status  := FND_API.G_RET_STS_ERROR;
550 
551          l_error_code := 'IBY_INS_PMTS_NOT_FOUND';
552          FND_MESSAGE.set_name('IBY', l_error_code);
553 
554          FND_MESSAGE.SET_TOKEN('INS_ID',
555              p_instruction_id,
556              FALSE);
557 
558          x_return_message := FND_MESSAGE.get;
559 
560          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
561 	         print_debuginfo(l_module_name, 'EXIT');
562 
563          END IF;
564          RETURN;
565 
566      END IF;
567 
568      /* populate the document count associated with each payment */
569        /* removed the call to populateDocumentCount, alternatively in
570         * processPaperPayments() API, the count of document is got through
571         * a query on iby_docs_payable_all  - AtT Build pmts perf issue
572         */
573    --  populateDocumentCount(l_pmtsInInstrTab);
574 
575      /*
576       * Calculate the number of setup and overflow documents for
577       * this payment instruction.
578       *
579       * Then provide all the payments with check numbers.
580       */
581      processPaperPayments(
582          p_pmt_document_id, p_user_assgn_num, l_pmtInstrRec,
583          l_pmtsInInstrTab, l_dummy_pmts_tab, l_dummy_docs_tab,
584          l_overflow_docs_tab, l_instr_err_tab, l_err_tokens_tab,
585          l_ret_status, l_ret_message, x_msg_count, x_msg_data);
586 
587      /*
588       * Now, that we have completed check printing, update
589       * the payments of the payment instruction with check
590       * numbers.
591       *
592       * Insert the created dummy documents (setup and overflow
593       * documents) into the database.
594       *
595       * Finally, change the status of the payment instruction
596       * to 'submitted for printing'.
597       */
598      IF (l_ret_status = 0) THEN
599 
600          performDBUpdates(p_instruction_id,
601              l_pmtsInInstrTab, l_dummy_pmts_tab,
602              l_dummy_docs_tab, l_overflow_docs_tab,
603              l_instr_err_tab, l_err_tokens_tab);
604 
605      ELSE
606 
607 
608 	         print_debuginfo(l_module_name, 'Check numbering process '
609 	             || 'did not succeed. Raising exception ..',
610 	             FND_LOG.LEVEL_UNEXPECTED
611 	             );
612 
613 
614          /*
615           * Raise an exception.
616           */
617          APP_EXCEPTION.RAISE_EXCEPTION;
618 
619      END IF;
620 
621      /*
622       * If we reached here, it means that the payments of the
623       * payment instruction have been numbered successfully
624       * and that the status of the payment instruction is now
625       * 'CREATED_READY_FOR_PRINTING' | 'CREATED_READY_FOR_FORMATTING'.
626       *
627       * After check numbering has been completed, invoke the withholding
628       * certificates hook. This is relevant only for AP, but we will
629       * call this hook blindly and let AP figure out whether there
630       * are any payments of interest for them.
631       */
632      l_callout_name := l_pkg_name || '.' || 'zx_witholdingCertificatesHook';
633 
634      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
635 	     print_debuginfo(l_module_name, 'Attempting to call hook: '
636 	         || l_callout_name);
637 
638      END IF;
639      l_stmt := 'CALL '|| l_callout_name || '(:1, :2, :3, :4, :5, :6, :7, :8)';
640 
641      BEGIN
642 
643          EXECUTE IMMEDIATE
644              (l_stmt)
645          USING
646              IN  p_instruction_id,
647              IN  'GENERATE',
648              IN  l_api_version,
649              IN  FND_API.G_FALSE,
650              IN  FND_API.G_FALSE,
651              OUT x_return_status,
652              OUT l_msg_count,
653              OUT l_msg_data
654          ;
655 
656          /*
657           * If the called procedure did not return success,
658           * raise an exception.
659           */
660          IF (x_return_status IS NULL OR
661              x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
662 
663 
664 	             print_debuginfo(l_module_name, 'Fatal: External app callout '''
665 	                 || l_callout_name
666 	                 || ''', returned failure status - '
667 	                 || x_return_status
668 	                 || '. Raising exception.',
669 	                 FND_LOG.LEVEL_UNEXPECTED
670 	                 );
671 
672 
673              l_error_code := 'IBY_INS_AWT_CERT_HOOK_FAILED';
674              FND_MESSAGE.set_name('IBY', l_error_code);
675 
676              l_ret_message := FND_MESSAGE.get;
677 
678              APP_EXCEPTION.RAISE_EXCEPTION;
679 
680          END IF;
681 
682      EXCEPTION
683 
684          WHEN PROCEDURE_NOT_IMPLEMENTED THEN
685              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
686 	             print_debuginfo(l_module_name, 'Callout "' || l_callout_name
687 	                 || '" not implemented by calling app - AP'
688 	                 );
689 
690 	             print_debuginfo(l_module_name, 'Skipping hook call.');
691 
692              END IF;
693          WHEN OTHERS THEN
694 
695 	             print_debuginfo(l_module_name, 'Fatal: External app callout '''
696 	                 || l_callout_name
697 	                 || ''', generated exception.',
698 	                 FND_LOG.LEVEL_UNEXPECTED
699 	                 );
700 
701 	             print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE,
702 	                 FND_LOG.LEVEL_UNEXPECTED);
703 	             print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM,
704 	                 FND_LOG.LEVEL_UNEXPECTED);
705 
706 
707              /*
708               * Propogate exception to caller.
709               */
710              RAISE;
711      END;
712 
713      x_return_status  := FND_API.G_RET_STS_SUCCESS;
714      x_return_message := 'SUCCESS';
715 
716      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
717 	     print_debuginfo(l_module_name, 'Returning success response ..');
718 
719 	     print_debuginfo(l_module_name, 'EXIT');
720 
721      END IF;
722  EXCEPTION
723      WHEN OTHERS THEN
724      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
725 	     print_debuginfo(l_module_name, 'Exception occured when '
726 	         || 'performing payment numbering. Payment numbering '
727 	         || 'process will be aborted.'
728 	         );
729 	     print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
730 	     print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
731 
732      END IF;
733      x_return_status := FND_API.G_RET_STS_ERROR;
734      x_return_message := l_ret_message;
735 
736      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
737 	     print_debuginfo(l_module_name, 'EXIT');
738 
739      END IF;
740  END performCheckNumbering;
741 
742 /*--------------------------------------------------------------------
743  | NAME:
744  |     populateDocumentCount
745  |
746  | PURPOSE:
747  |
748  |
749  |
750  | PARAMETERS:
751  |     IN
752  |
753  |     OUT
754  |
755  |
756  | RETURNS:
757  |
758  | NOTES:
759  |
760  *---------------------------------------------------------------------*/
761  PROCEDURE populateDocumentCount(
762      x_pmtsInPmtInstrTab  IN OUT NOCOPY IBY_PAYINSTR_PUB.pmtsInpmtInstrTabType
763      )
764  IS
765 
766  l_module_name VARCHAR2(200) := G_PKG_NAME || '.populateDocumentCount';
767  l_docs_in_pmt_count docsInPmtCountTabType;
768 
769  CURSOR c_document_count(pmt_instruction_id Number)
770  IS
771  SELECT
772      count(*),
773      DOCS.payment_id
774  FROM
775      IBY_DOCS_PAYABLE_ALL DOCS, IBY_PAYMENTS_ALL PMTS
776  WHERE
777              PMTS.PAYMENT_INSTRUCTION_ID = pmt_instruction_id
778 	 AND PMTS.PAYMENT_ID = DOCS.PAYMENT_ID
779 	 AND DOCS.document_status = DOC_STATUS_PAY_CREATED
780 
781  GROUP BY
782     DOCS.payment_id
783  ;
784 
785  BEGIN
786 
787      OPEN  c_document_count(x_pmtsInPmtInstrTab(x_pmtsInPmtInstrTab.FIRST).pay_instr_id);
788      FETCH c_document_count BULK COLLECT INTO l_docs_in_pmt_count;
789      CLOSE c_document_count;
790 
791      IF (l_docs_in_pmt_count.COUNT = 0) THEN
792 
793          /*
794           * Normally this shouldn't happen.
795           */
796 
797 	         print_debuginfo(l_module_name, 'No documents payable '
798 	             || 'were found in ''payments created'' status '
799 	             || 'though created payments exist. '
800 	             || 'Possible data corruption. Aborting ..',
801 	             FND_LOG.LEVEL_UNEXPECTED
802 	             );
803 
804 
805          APP_EXCEPTION.RAISE_EXCEPTION;
806 
807      END IF;
808 
809      FOR i in x_pmtsInPmtInstrTab.FIRST .. x_pmtsInPmtInstrTab.LAST LOOP
810 
811          FOR j in l_docs_in_pmt_count.FIRST .. l_docs_in_pmt_count.LAST LOOP
812 
813              IF (x_pmtsInPmtInstrTab(i).payment_id = l_docs_in_pmt_count(j).
814                  payment_id) THEN
815 
816                  x_pmtsInPmtInstrTab(i).document_count :=
817                      l_docs_in_pmt_count(j).doc_count;
818 
819                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
820 	                 print_debuginfo(l_module_name, 'Num docs for payment: '
821 	                     || x_pmtsInPmtInstrTab(i).payment_id
822 	                     || ' is: '
823 	                     || x_pmtsInPmtInstrTab(i).document_count
824 	                     );
825 
826                  END IF;
827                  /* exit inner loop */
828                  EXIT;
829 
830              END IF;
831 
832          END LOOP;
833 
834      END LOOP;
835 
836  END populateDocumentCount;
837 
838 /*--------------------------------------------------------------------
839  | NAME:
840  |     updatePaymentInstructions
841  |
842  | PURPOSE:
843  |     Performs an update of all created instructions from PLSQL
844  |     table into IBY_PAY_INSTRUCTIONS_ALL table.
845  |
846  |     The created instructions have already been inserted into
847  |     IBY_PAY_INSTRUCTIONS_ALL after grouping (and before validation).
848  |     So we only need to update certain fields of the instruction
849  |     that have been changed after the grouping was performed.
850  |
851  | PARAMETERS:
852  |     IN
853  |
854  |
855  |     OUT
856  |
857  |
858  | RETURNS:
859  |
860  | NOTES:
861  |
862  *---------------------------------------------------------------------*/
863  PROCEDURE updatePaymentInstructions(
864      p_payInstrTab   IN IBY_PAYINSTR_PUB.pmtInstrTabType
865      )
866  IS
867  l_module_name VARCHAR2(200) := G_PKG_NAME || '.updatePaymentInstructions';
868 
869  BEGIN
870 
871      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
872 	     print_debuginfo(l_module_name, 'ENTER');
873 
874      END IF;
875      /* Normally, this shouldn't happen */
876      IF (p_payInstrTab.COUNT = 0) THEN
877          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
878 	         print_debuginfo(l_module_name, 'No payment instructions'
879 	             || ' were found to update IBY_PAY_INSTRUCTIONS_ALL table.');
880          END IF;
881          RETURN;
882      END IF;
883 
884      FOR i in p_payInstrTab.FIRST..p_payInstrTab.LAST LOOP
885          UPDATE
886              IBY_PAY_INSTRUCTIONS_ALL
887          SET
888              payment_instruction_status = p_payInstrTab(i).
889                                               payment_instruction_status
890          WHERE
891              payment_instruction_id = p_payInstrTab(i).payment_instruction_id;
892      END LOOP;
893 
894      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
895 	     print_debuginfo(l_module_name, 'EXIT');
896 
897      END IF;
898  END updatePaymentInstructions;
899 
900 /*--------------------------------------------------------------------
901  | NAME:
902  |     insertPaperDocuments
903  |
904  | PURPOSE:
905  |
906  |
907  |
908  | PARAMETERS:
909  |     IN
910  |
911  |
912  |     OUT
913  |
914  |
915  | RETURNS:
916  |
917  | NOTES:
918  |
919  *---------------------------------------------------------------------*/
920  PROCEDURE insertPaperDocuments(
921      p_paperPmtsTab      IN IBY_PAYGROUP_PUB.paymentTabType,
922      p_setupDocsTab      IN docsTabType,
923      p_overflowDocsTab   IN overflowDocsTabType
924      )
925  IS
926  l_setup_pmts_tab     IBY_PAYGROUP_PUB.paymentTabType;
927  l_overflow_pmts_tab  IBY_PAYGROUP_PUB.paymentTabType;
928 
929  l_module_name VARCHAR2(200) := G_PKG_NAME || '.insertPaperDocuments';
930  BEGIN
931 
932      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
933 	     print_debuginfo(l_module_name, 'ENTER');
934 
935      END IF;
936      IF (p_paperPmtsTab.COUNT = 0) THEN
937          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
938 	         print_debuginfo(l_module_name, 'No paper documents were '
939 	             || 'provided for insert. Exiting ..'
940 	             );
941 	         print_debuginfo(l_module_name, 'EXIT');
942          END IF;
943          RETURN;
944      END IF;
945 
946      /*
947       * Split the p_paperPmtsTab to get the setup payments
948       * and overflow payments into separate data structures.
949       */
950      splitPaymentsByType(p_paperPmtsTab, l_setup_pmts_tab,
951          l_overflow_pmts_tab);
952 
953      /*
954       * Handle setup payments.
955       */
956      IF (l_setup_pmts_tab.COUNT <> 0) THEN
957 
958          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
959 	         print_debuginfo(l_module_name, 'Inserting '
960 	             || l_setup_pmts_tab.COUNT
961 	             || ' setup payments.'
962 	             );
963 
964          END IF;
965          /* setup payments can be bulk inserted */
966          FORALL i in l_setup_pmts_tab.FIRST..l_setup_pmts_tab.LAST
967              INSERT INTO IBY_PAYMENTS_ALL VALUES l_setup_pmts_tab(i);
968 
969          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
970 	         print_debuginfo(l_module_name, 'Inserting '
971 	             || p_setupDocsTab.COUNT
972 	             || ' setup documents.'
973 	             );
974 
975          END IF;
976          /* documents related to setup payments can be bulk inserted */
977          FORALL i in p_setupDocsTab.FIRST..p_setupDocsTab.LAST
978              INSERT INTO IBY_DOCS_PAYABLE_ALL VALUES p_setupDocsTab(i);
979 
980      END IF;
981 
982      /*
983       * Handle overflow payments.
984       */
985      IF (l_overflow_pmts_tab.COUNT <> 0) THEN
986 
987          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
988 	         print_debuginfo(l_module_name, 'Inserting '
989 	             || l_overflow_pmts_tab.COUNT
990 	             || ' overflow payments.'
991 	             );
992 
993          END IF;
994          /* overflow payments can be bulk inserted */
995          FORALL i in l_overflow_pmts_tab.FIRST..l_overflow_pmts_tab.LAST
996              INSERT INTO IBY_PAYMENTS_ALL VALUES l_overflow_pmts_tab(i);
997 
998 
999          /*
1000           * Fix for bug 6765314:
1001           *
1002           * The overflow payment is a dummy payment that is related
1003           * to a real payment. Copy the important attributes of the
1004           * real payment onto the original payment. This will ensure
1005           * that when the overflow payment is printed, it contains
1006           * the payee name, payer name etc.
1007           *
1008           * The external bank account id field on the overflow
1009           * payment actually contains the payment id of the
1010           * real payment. See KLUDGE in performSpecialPaperHandling()
1011           * for more information on this.
1012           */
1013          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1014 	         print_debuginfo(l_module_name, 'Updating '
1015 	             || 'overflow payments with attributes '
1016 	             || 'from related real payments.'
1017 	             );
1018 
1019          END IF;
1020          FOR i in l_overflow_pmts_tab.FIRST..l_overflow_pmts_tab.LAST LOOP
1021 
1022              UPDATE
1023                  iby_payments_all overflow
1024              SET
1025                      (
1026                      overflow.payment_method_code,
1027                      overflow.internal_bank_account_id,
1028                      overflow.org_id,
1029                      overflow.org_type,
1030                      overflow.legal_entity_id,
1031                      overflow.delivery_channel_code,
1032                      overflow.ext_payee_id,
1033                      overflow.payment_profile_id,
1034                      overflow.payee_party_id,
1035                      overflow.party_site_id,
1036                      overflow.supplier_site_id,
1037                      overflow.payment_reason_code,
1038                      overflow.payment_reason_comments,
1039                      overflow.payment_date,
1040                      overflow.remittance_message1,
1041                      overflow.remittance_message2,
1042                      overflow.remittance_message3,
1043                      overflow.payment_due_date,
1044                      overflow.beneficiary_party,
1045                      overflow.remit_to_location_id,
1046                      overflow.payee_name,
1047                      overflow.payee_address1,
1048                      overflow.payee_address2,
1049                      overflow.payee_address3,
1050                      overflow.payee_address4,
1051                      overflow.payee_city,
1052                      overflow.payee_postal_code,
1053                      overflow.payee_state,
1054                      overflow.payee_province,
1055                      overflow.payee_county,
1056                      overflow.payee_country,
1057                      overflow.org_name,
1058                      overflow.payer_legal_entity_name,
1059                      overflow.payee_party_name,
1060                      overflow.payer_party_site_name,
1061                      overflow.payee_address_concat,
1062                      overflow.beneficiary_name,
1063                      overflow.payer_party_number,
1064                      overflow.payee_party_number,
1065                      overflow.payee_alternate_name,
1066                      overflow.payee_site_alternate_name,
1067                      overflow.payee_supplier_number,
1068                      overflow.payee_first_party_reference,
1069                      overflow.address_source,
1070                      overflow.employee_address_code,
1071                      overflow.employee_person_id,
1072                      overflow.employee_payment_flag,
1073                      overflow.employee_address_id,
1074                      overflow.payer_party_id,
1075                      overflow.payer_location_id,
1076                      overflow.payee_supplier_id,
1077                      overflow.payee_supplier_site_name,
1078                      overflow.payee_supplier_site_alt_name
1079                      ) =
1080                  (
1081                  SELECT
1082                      real.payment_method_code,
1083                      real.internal_bank_account_id,
1084                      real.org_id,
1085                      real.org_type,
1086                      real.legal_entity_id,
1087                      real.delivery_channel_code,
1088                      real.ext_payee_id,
1089                      real.payment_profile_id,
1090                      real.payee_party_id,
1091                      real.party_site_id,
1092                      real.supplier_site_id,
1093                      real.payment_reason_code,
1094                      real.payment_reason_comments,
1095                      real.payment_date,
1096                      real.remittance_message1,
1097                      real.remittance_message2,
1098                      real.remittance_message3,
1099                      real.payment_due_date,
1100                      real.beneficiary_party,
1101                      real.remit_to_location_id,
1102                      real.payee_name,
1103                      real.payee_address1,
1104                      real.payee_address2,
1105                      real.payee_address3,
1106                      real.payee_address4,
1107                      real.payee_city,
1108                      real.payee_postal_code,
1109                      real.payee_state,
1110                      real.payee_province,
1111                      real.payee_county,
1112                      real.payee_country,
1113                      real.org_name,
1114                      real.payer_legal_entity_name,
1115                      real.payee_party_name,
1116                      real.payer_party_site_name,
1117                      real.payee_address_concat,
1118                      real.beneficiary_name,
1119                      real.payer_party_number,
1120                      real.payee_party_number,
1121                      real.payee_alternate_name,
1122                      real.payee_site_alternate_name,
1123                      real.payee_supplier_number,
1124                      real.payee_first_party_reference,
1125                      real.address_source,
1126                      real.employee_address_code,
1127                      real.employee_person_id,
1128                      real.employee_payment_flag,
1129                      real.employee_address_id,
1130                      real.payer_party_id,
1131                      real.payer_location_id,
1132                      real.payee_supplier_id,
1133                      real.payee_supplier_site_name,
1134                      real.payee_supplier_site_alt_name
1135                  FROM
1136                      iby_payments_all real
1137                  WHERE
1138                      real.payment_id = overflow.external_bank_account_id
1139                  )
1140              WHERE overflow.payment_id = l_overflow_pmts_tab(i).payment_id
1141              ;
1142          END LOOP;
1143 
1144          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1145 	         print_debuginfo(l_module_name, 'Updating '
1146 	             || p_overflowDocsTab.COUNT
1147 	             || ' overflow documents.'
1148 	             );
1149 
1150          END IF;
1151          /*
1152           * For overflow payments, the documents are already
1153           * available in the IBY_DOCS_PAYABLE_ALL table. The
1154           * formatting payment id on these documents needs
1155           * to be updated to account for the overflow payments
1156           * (1 overflow payment = 1 printed void check).
1157           */
1158          FOR i in p_overflowDocsTab.FIRST..p_overflowDocsTab.LAST LOOP
1159 
1160              UPDATE
1161                  IBY_DOCS_PAYABLE_ALL
1162              SET
1163                  formatting_payment_id =
1164                      p_overflowDocsTab(i).format_payment_id
1165              WHERE
1166                  document_payable_id = p_overflowDocsTab(i).doc_id;
1167 
1168          END LOOP;
1169 
1170      END IF;
1171 
1172      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1173 	     print_debuginfo(l_module_name, 'EXIT');
1174 
1175      END IF;
1176  END insertPaperDocuments;
1177 
1178 /*--------------------------------------------------------------------
1179  | NAME:
1180  |     splitPaymentsByType
1181  |
1182  | PURPOSE:
1183  |
1184  |
1185  |
1186  | PARAMETERS:
1187  |     IN
1188  |
1189  |
1190  |     OUT
1191  |
1192  |
1193  | RETURNS:
1194  |
1195  | NOTES:
1196  |
1197  *---------------------------------------------------------------------*/
1198  PROCEDURE splitPaymentsByType(
1199      p_paperPmtsTab      IN IBY_PAYGROUP_PUB.paymentTabType,
1200      x_setupPmtsTab      IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
1201      x_overflowPmtsTab   IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType
1202      )
1203  IS
1204 
1205  l_module_name VARCHAR2(200) := G_PKG_NAME || '.splitPaymentsByType';
1206 
1207  BEGIN
1208 
1209      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1210 	     print_debuginfo(l_module_name, 'ENTER');
1211 
1212      END IF;
1213      IF (p_paperPmtsTab.COUNT = 0) THEN
1214 
1215          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1216 	         print_debuginfo(l_module_name, 'No payments to split. Exiting ..');
1217 	         print_debuginfo(l_module_name, 'EXIT');
1218          END IF;
1219          RETURN;
1220 
1221      END IF;
1222 
1223      FOR i in p_paperPmtsTab.FIRST..p_paperPmtsTab.LAST LOOP
1224 
1225          /* setup payments */
1226          IF (p_paperPmtsTab(i).payment_status = 'VOID_BY_SETUP') THEN
1227 
1228              x_setupPmtsTab(x_setupPmtsTab.COUNT + 1)
1229                  := p_paperPmtsTab(i);
1230 
1231          /* overflow payments */
1232          ELSIF (p_paperPmtsTab(i).payment_status = 'VOID_BY_OVERFLOW') THEN
1233 
1234              x_overflowPmtsTab(x_overflowPmtsTab.COUNT + 1)
1235                  := p_paperPmtsTab(i);
1236 
1237          /* normally, shouldn't come here */
1238          ELSE
1239              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1240 	             print_debuginfo(l_module_name, 'Ignoring payment with '
1241 	                 || 'status '
1242 	                 || p_paperPmtsTab(i).payment_status
1243 	                 );
1244              END IF;
1245          END IF;
1246 
1247      END LOOP;
1248 
1249      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1250 	     print_debuginfo(l_module_name, 'Created '
1251 	         || x_setupPmtsTab.COUNT
1252 	         || ' setup payments and '
1253 	         || x_overflowPmtsTab.COUNT
1254 	         || ' overflow payments from '
1255 	         || p_paperPmtsTab.COUNT
1256 	         || ' provided payments.'
1257 	         );
1258 
1259 	     print_debuginfo(l_module_name, 'EXIT');
1260 
1261      END IF;
1262  END splitPaymentsByType;
1263 
1264 /*--------------------------------------------------------------------
1265  | NAME:
1266  |     performDBUpdates
1267  |
1268  | PURPOSE:
1269  |
1270  |
1271  |
1272  | PARAMETERS:
1273  |     IN
1274  |
1275  |
1276  |     OUT
1277  |
1278  |
1279  | RETURNS:
1280  |
1281  |
1282  | NOTES:
1283  |
1284  *---------------------------------------------------------------------*/
1285  PROCEDURE performDBUpdates(
1286      p_instruction_id    IN IBY_PAY_INSTRUCTIONS_ALL.
1287                                 payment_instruction_id%TYPE,
1288      x_pmtsInPmtInstrTab IN OUT NOCOPY IBY_PAYINSTR_PUB.pmtsInpmtInstrTabType,
1289      x_dummyPaperPmtsTab IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
1290      x_setupDocsTab      IN OUT NOCOPY docsTabType,
1291      x_overflowDocsTab   IN OUT NOCOPY overflowDocsTabType,
1292      x_insErrorsTab      IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.docErrorTabType,
1293      x_insTokenTab       IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.
1294                                            trxnErrTokenTabType
1295      )
1296  IS
1297  l_module_name      VARCHAR2(200)  := G_PKG_NAME || '.performDBUpdates';
1298 
1299  BEGIN
1300 
1301      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1302 	     print_debuginfo(l_module_name, 'ENTER');
1303 
1304      END IF;
1305      /*
1306       * Update the payments table by providing a check number to
1307       * each payment.
1308       */
1309      updatePmtsWithCheckNumbers(x_pmtsInPmtInstrTab);
1310 
1311      /*
1312       * Insert the setup and overflow documents that have been
1313       * created as part of paper payments handing.
1314       */
1315      insertPaperDocuments(x_dummyPaperPmtsTab, x_setupDocsTab,
1316          x_overflowDocsTab);
1317 
1318      /*
1319       * Insert any payment instruction errors into
1320       * IBY_TRANSACTION_ERRORS table.
1321       */
1322      IBY_VALIDATIONSETS_PUB.insert_transaction_errors('N', x_insErrorsTab,
1323          x_insTokenTab);
1324 
1325      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1326 	     print_debuginfo(l_module_name, 'EXIT');
1327 
1328      END IF;
1329  EXCEPTION
1330 
1331      WHEN OTHERS THEN
1332 
1333 	         print_debuginfo(l_module_name, 'Fatal: Exception when updating '
1334 	             || 'payment instruction/payment status after payment '
1335 	             || 'instruction creation. All changes will be rolled back.',
1336 	             FND_LOG.LEVEL_UNEXPECTED
1337 	             );
1338 	         print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE,
1339 	             FND_LOG.LEVEL_UNEXPECTED);
1340 	         print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM,
1341 	             FND_LOG.LEVEL_UNEXPECTED);
1342 
1343 
1344          /*
1345           * Propogate exception to caller.
1346           */
1347          RAISE;
1348 
1349  END performDBUpdates;
1350 
1351 /*--------------------------------------------------------------------
1352  | NAME:
1353  |     processPaperPayments
1354  |
1355  | PURPOSE:
1356  |
1357  |
1358  |
1359  | PARAMETERS:
1360  |     IN
1361  |
1362  |
1363  |     OUT
1364  |
1365  |
1366  | RETURNS:
1367  |
1368  | NOTES:
1369  |
1370  *---------------------------------------------------------------------*/
1371  PROCEDURE processPaperPayments(
1372      p_pmt_document_id   IN CE_PAYMENT_DOCUMENTS.payment_document_id%TYPE,
1373      p_user_assgn_num    IN IBY_PAYMENTS_ALL.paper_document_number%TYPE,
1374      x_pmtInstrRec       IN OUT NOCOPY IBY_PAY_INSTRUCTIONS_ALL%ROWTYPE,
1375      x_pmtsInPmtInstrTab IN OUT NOCOPY IBY_PAYINSTR_PUB.pmtsInpmtInstrTabType,
1376      x_dummyPaperPmtsTab IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
1377      x_setupDocsTab      IN OUT NOCOPY docsTabType,
1378      x_overflowDocsTab   IN OUT NOCOPY overflowDocsTabType,
1379      x_instrErrorTab     IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.docErrorTabType,
1380      x_insTokenTab       IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.
1381                                            trxnErrTokenTabType,
1382      x_return_status     IN OUT NOCOPY NUMBER,
1383      x_return_message    IN OUT NOCOPY VARCHAR2,
1384      x_msg_count         IN OUT NOCOPY NUMBER,
1385      x_msg_data          IN OUT NOCOPY VARCHAR2
1386      )
1387  IS
1388 
1389  l_module_name       VARCHAR2(200) := G_PKG_NAME
1390                                           || '.processPaperPayments';
1391  l_processing_type   VARCHAR2(100); -- PRINTED | ELECTRONIC
1392  l_num_printed_docs  NUMBER(15);
1393  l_paper_stock_rec   paperStockRecType;
1394  l_paper_stocks_tab  paperStocksTabType;
1395  l_docs_count        NUMBER;
1396 
1397  l_error_code        VARCHAR2(3000);
1398 
1399  l_paper_special_docs_rec    paperPmtsSpecialDocsRecType;
1400  l_paper_special_docs_tab    paperPmtsSpecialDocsTabType;
1401 
1402  l_pmtsInPmtInstrRec IBY_PAYINSTR_PUB.pmtsInpmtInstrRecType;
1403 
1404  CURSOR c_paper_stock (p_pmt_doc_id IN CE_PAYMENT_DOCUMENTS.
1405                                        payment_document_id%TYPE)
1406  IS
1407  SELECT
1408         payment_document_id,
1409         payment_document_name,
1410         NVL(number_of_setup_documents, 0),
1411         DECODE(attached_remittance_stub_flag,'Y',number_of_lines_per_remit_stub,NULL) number_of_lines_per_remit_stub
1412  FROM
1413         CE_PAYMENT_DOCUMENTS
1414  WHERE
1415         payment_document_id = p_pmt_doc_id
1416  ;
1417 
1418  BEGIN
1419 
1420      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1421 	     print_debuginfo(l_module_name, 'ENTER');
1422 
1423      END IF;
1424      OPEN  c_paper_stock (p_pmt_document_id);
1425      FETCH c_paper_stock BULK COLLECT INTO l_paper_stocks_tab;
1426      CLOSE c_paper_stock;
1427 
1428      /*
1429       * There should be exactly one payment document linked
1430       * to a particular payment document name.
1431       */
1432      IF (l_paper_stocks_tab.COUNT <> 1) THEN
1433 
1434          --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1435 	         print_debuginfo(l_module_name, 'Unable to get matching payment '
1436 	             || 'document from CE_PAYMENT_DOCUMENTS for payment '
1437 	             || 'document id: '
1438 	             || p_pmt_document_id
1439 	             || '. Number of payment documents retrieved: '
1440 	             || l_paper_stocks_tab.COUNT
1441 	             );
1442 
1443          --END IF;
1444          x_return_status := -1;
1445 
1446          l_error_code := 'IBY_INS_NO_PMT_DOC';
1447          FND_MESSAGE.set_name('IBY', l_error_code);
1448 
1449          FND_MESSAGE.SET_TOKEN('PMT_DOC_ID',
1450              p_pmt_document_id,
1451              FALSE);
1452 
1453          x_return_message := FND_MESSAGE.get;
1454 
1455          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1456 	         print_debuginfo(l_module_name, 'EXIT');
1457          END IF;
1458          RETURN;
1459 
1460      END IF;
1461 
1462      /*
1463       * Since, payment instructions are grouped by
1464       * profile id, they are implicitly grouped
1465       * by processing type as well.
1466       *
1467       * pmtsInpmtInstrTabType will have multiple records for
1468       * a payment instruction (one record for each payment
1469       * in the instruction). All these payments will have the
1470       * same profile id, and the same procesing type
1471       * (because only payments with a specific profile id wil
1472       * be grouped into a payment instruction).
1473       *
1474       * Therefore, in order to determine the processing type
1475       * of a payment instruction, we simply need to retrieve
1476       * the processing type from any payment of that
1477       * instruction. We do this by retrieving the processing
1478       * type of the first payment of that instruction.
1479       */
1480      l_pmtsInPmtInstrRec := x_pmtsInPmtInstrTab(x_pmtsInPmtInstrTab.FIRST);
1481      l_processing_type   := l_pmtsInPmtInstrRec.processing_type;
1482 
1483      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1484 	     print_debuginfo(l_module_name, 'For payment instruction '
1485 	         || x_pmtInstrRec.payment_instruction_id
1486 	         || ', profile id: '
1487 	         || x_pmtInstrRec.payment_profile_id
1488 	         || ', processing type: '
1489 	         || l_processing_type
1490 	         || ', # pmts: '
1491 	         || x_pmtInstrRec.payment_count
1492 	         );
1493 
1494      END IF;
1495      /*
1496       * If the processing type for this instruction is set
1497       * to 'PAPER', it means that this payment instruction
1498       * will be physically printed onto paper.
1499       *
1500       * Perform paper payment specific processing such as
1501       * calculating setup and overflow documents.
1502       */
1503      IF (l_processing_type = 'PRINTED') THEN
1504 
1505          /* Get the attributes of the paper stock */
1506          /*
1507           * There will only be one paper stock linked to
1508           * a particular payment document name, so we can
1509           * simply take the first record from the fetched
1510           * paper stocks table.
1511           */
1512          l_paper_stock_rec := l_paper_stocks_tab(1);
1513 
1514          IF (l_paper_stock_rec.doc_id IS NOT NULL) THEN
1515 
1516              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1517 	             print_debuginfo(l_module_name, 'Paper stock matching '
1518 	                 || 'profile id '
1519 	                 || x_pmtInstrRec.payment_profile_id
1520 	                 || ' has following attributes - Name: '
1521 	                 || l_paper_stock_rec.doc_name
1522 	                 || ', num setup docs: '
1523 	                 || l_paper_stock_rec.num_setup_docs
1524 	                 || ', num lines per stub: '
1525 	                 || l_paper_stock_rec.num_lines_per_stub
1526 	                 );
1527 
1528              END IF;
1529          ELSE
1530 
1531              --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1532 	             print_debuginfo(l_module_name, 'Fatal: No paper stock '
1533 	                 || 'linked to profile id '
1534 	                 || x_pmtInstrRec.payment_profile_id
1535 	                 || '. Payment instruction creation cannot continue. '
1536 	                 || 'Aborting program ..'
1537 	                 );
1538 
1539              --END IF;
1540              x_return_status := -1;
1541 
1542              l_error_code := 'IBY_INS_NO_PAPER_STOCK';
1543              FND_MESSAGE.set_name('IBY', l_error_code);
1544 
1545              FND_MESSAGE.SET_TOKEN('INS_ID',
1546                  x_pmtInstrRec.payment_instruction_id,
1547                  FALSE);
1548 
1549              x_return_message := FND_MESSAGE.get;
1550 
1551              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1552 	             print_debuginfo(l_module_name, 'EXIT');
1553              END IF;
1554              RETURN;
1555 
1556          END IF;
1557 
1558          /*
1559           * If we reached here it means paper stock
1560           * attributes were retrieved successfully
1561           * for the profile on the instruction.
1562           */
1563 
1564          /*
1565           * Loop through all the payments for this
1566           * payment instruction, processing them one-by-one.
1567           */
1568          FOR j in x_pmtsInPmtInstrTab.FIRST .. x_pmtsInPmtInstrTab.LAST
1569              LOOP
1570 
1571              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1572 	             print_debuginfo(l_module_name, 'Processing payment '
1573 	                 || x_pmtsInPmtInstrTab(j).payment_id
1574 	                 || ' for instruction '
1575 	                 || x_pmtInstrRec.payment_instruction_id
1576 	                 || ' ..'
1577 	                 );
1578              END IF;
1579          /* Removing the call to getDocumentCount, rather accessing
1580           * IBY_DOCS_PAYABLE_ALL table to get the count of the
1581  	  * documents
1582  	  */
1583            /*  l_docs_count := getDocumentCountForPayment(
1584                                  x_pmtsInPmtInstrTab(j).payment_id,
1585                                  x_pmtsInPmtInstrTab
1586                                  );
1587 	    */
1588 
1589 	            SELECT
1590  	                 COUNT(*)
1591 		    INTO
1592  	                 x_pmtsInPmtInstrTab(j).document_count
1593  	            FROM
1594  	                 IBY_DOCS_PAYABLE_ALL
1595  	            WHERE
1596  	                 payment_id =  x_pmtsInPmtInstrTab(j).payment_id
1597  	            AND
1598  	                 document_status = DOC_STATUS_PAY_CREATED;
1599 
1600 
1601  	            l_docs_count := x_pmtsInPmtInstrTab(j).document_count;
1602              IF (l_docs_count <= 0) THEN
1603                  /*
1604                   * A successful payment must be linked to at least
1605                   * least one successful document payable. If not
1606                   * there is a data consistency issue.
1607                   *
1608                   * Raise an alert and abort the program.
1609                   */
1610                  --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1611 	                 print_debuginfo(l_module_name, 'Fatal: No successful '
1612 	                     || 'docs were found for successful pmt with id '
1613 	                     || x_pmtsInPmtInstrTab(j).payment_id
1614 	                     || '. Possible data corruption. '
1615 	                     || 'Aborting program ..'
1616 	                     );
1617 
1618                  --END IF;
1619                   x_return_status := -1;
1620 
1621                   l_error_code := 'IBY_INS_PMT_NO_DOCS';
1622                   FND_MESSAGE.set_name('IBY', l_error_code);
1623 
1624                   FND_MESSAGE.SET_TOKEN('PMT_ID',
1625                      x_pmtsInPmtInstrTab(j).payment_id,
1626                      FALSE);
1627 
1628                   FND_MESSAGE.SET_TOKEN('INS_ID',
1629                      x_pmtInstrRec.payment_instruction_id,
1630                      FALSE);
1631 
1632                   x_return_message := FND_MESSAGE.get;
1633 
1634                   IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1635 	                  print_debuginfo(l_module_name, 'EXIT');
1636                   END IF;
1637                   RETURN;
1638 
1639              END IF;
1640 
1641              l_num_printed_docs := getNumPrintedDocsByFormula(
1642                                        l_docs_count,
1643                                        l_paper_stock_rec.
1644                                            num_lines_per_stub
1645                                        );
1646 
1647              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1648 	             print_debuginfo(l_module_name, 'For payment id '
1649 	                 || x_pmtsInPmtInstrTab(j).payment_id
1650 	                 || ', docs count on payment: '
1651 	                 || l_docs_count
1652 	                 || ', lines per stub on stock: '
1653 	                 || l_paper_stock_rec.num_lines_per_stub
1654 	                 || ', calculated number of printed docs: '
1655 	                 || l_num_printed_docs);
1656 
1657              END IF;
1658              /*
1659               * Add the details about the setup docs and
1660               * overflow docs for this payment into the
1661               * special docs table. This special docs table
1662               * will be used for inserting dummy payments
1663               * into the IBY_DOCS_PAYABLE_ALL and
1664               * IBY_PAYMENTS_ALL tables to account for setup
1665               * and overflow checks.
1666               */
1667              l_paper_special_docs_rec.payment_id          :=
1668                  x_pmtsInPmtInstrTab(j).payment_id;
1669 
1670              l_paper_special_docs_rec.instruction_id      :=
1671                  x_pmtsInPmtInstrTab(j).pay_instr_id;
1672 
1673              /*
1674               * Only one printed document per payment will be a
1675               * valid payment document. The rest of the documents
1676               * will be overflow documents that will be void and
1677               * are only used to store the document payable
1678               * ids.
1679               */
1680              l_paper_special_docs_rec.num_overflow_docs   :=
1681                  l_num_printed_docs - 1;
1682 
1683              /*
1684               * Number of setup documents to print is
1685               * specified in the paper stock set up.
1686               */
1687              /*
1688               * Set up Docs are not considered for quick payments
1689               * Defaulting the set up docs to '0'
1690               */
1691 
1692 	     IF (x_pmtInstrRec.process_type = PROCESS_TYPE_IMMEDIATE ) THEN
1693                     l_paper_special_docs_rec.num_setup_docs      := 0;
1694              ELSE
1695                  l_paper_special_docs_rec.num_setup_docs      :=   l_paper_stock_rec.num_setup_docs;
1696 	     END IF;
1697 
1698              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1699 	                 print_debuginfo(l_module_name, 'Set Up docs : ' || l_paper_special_docs_rec.num_setup_docs );
1700              END IF;
1701 
1702              /*
1703               * Lines per stub in used in populating
1704               * dummy documents payable for this
1705               * payment.
1706               */
1707              l_paper_special_docs_rec.num_lines_per_stub  :=
1708                  l_paper_stock_rec.num_lines_per_stub;
1709 
1710              /* add record to dummy docs table */
1711              l_paper_special_docs_tab(l_paper_special_docs_tab.COUNT
1712                  + 1) := l_paper_special_docs_rec;
1713              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1714 	                 print_debuginfo(l_module_name, 'Processing type of parent '
1715 		             || 'request is '
1716 		             || x_pmtInstrRec.process_type
1717 		             );
1718 
1719              END IF;
1720 
1721 	     IF (x_pmtInstrRec.process_type = PROCESS_TYPE_IMMEDIATE AND l_paper_special_docs_rec.num_overflow_docs > 0) THEN
1722                  /*
1723                   * Single payments should not result in void by overflow checks
1724                   * Raise an alert and abort the program.
1725                   */
1726                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1727 	                 print_debuginfo(l_module_name, 'Fatal: Void by overflow checks resulted for quick payment with payment ID'
1728 	                     || x_pmtsInPmtInstrTab(j).payment_id
1729 	                     || '. Aborting program ..'
1730 	                     );
1731 
1732                  END IF;
1733                   x_return_status := -1;
1734                   l_error_code := 'IBY_PAY_EXCEEDS_INV_PER_STUB';
1735                   FND_MESSAGE.set_name('IBY', l_error_code);
1736                   FND_MESSAGE.SET_TOKEN('STUB', l_paper_stock_rec.num_lines_per_stub, FALSE);
1737                   x_return_message := FND_MESSAGE.get;
1738                   IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1739 	                  print_debuginfo(l_module_name, 'EXIT');
1740                   END IF;
1741                   RETURN;
1742              END IF;
1743 
1744          END LOOP; -- for each payment in this instruction
1745 
1746          /*
1747           * If we reached here, it means that 'num overflow docs'
1748           * and 'num setup docs' has been populated for each
1749           * paper payment in the l_paper_special_docs_tab table.
1750           *
1751           * Use this information to create appropriate number
1752           * of dummy payments (to insert into IBY_PAYMENTS_ALL table)
1753           * and corresponding documents (to insert into
1754           * IBY_DOCS_PAYABLE_ALL table).
1755           */
1756          performSpecialPaperDocHandling(
1757              l_paper_special_docs_tab,
1758              x_dummyPaperPmtsTab,
1759              x_setupDocsTab,
1760              x_overflowDocsTab
1761              );
1762 
1763          /*
1764           * After setup and overflow payments have been
1765           * handled, we can start assigning physical check
1766           * numbers to the paper payments.
1767           *
1768           * The 'paper special docs tab' holds real payments
1769           * that have to be printed onto paper; the 'paper pmts
1770           * tab' holds the dummy payments that also have to
1771           * printed onto paper. So both types of payments
1772           * need to be provided with check numbers.
1773           */
1774          assignCheckNumbers(
1775              x_pmtInstrRec,
1776              l_paper_stock_rec.doc_id,
1777              p_user_assgn_num,
1778              l_paper_special_docs_tab,
1779              x_dummyPaperPmtsTab,
1780              x_instrErrorTab,
1781              x_insTokenTab,
1782              x_return_message,
1783              x_return_status,
1784              x_msg_count,
1785              x_msg_data
1786              );
1787 
1788          IF (x_return_status = -1) THEN
1789 
1790              /*
1791               * Return back the x_return status and
1792               * x_return_message values that we received
1793               * from assignCheckNumbers() call.
1794               */
1795              --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1796 	             print_debuginfo(l_module_name, 'Check numbering did '
1797 	                 || 'not succeed.'
1798 	                 );
1799                IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1800 	             print_debuginfo(l_module_name, 'EXIT');
1801              END IF;
1802              RETURN;
1803 
1804          END IF;
1805 
1806          /*
1807           * l_paper_special_docs_tab contains list of paper
1808           * payments that now have check number assigned.
1809           *
1810           * But this data structure is a local object. We
1811           * have to copy back the check numbers into
1812           * x_pmtsInPmtInstrTab which will be used to
1813           * finally update the database.
1814           */
1815 
1816 	  /* 16366300: POOR PEFORMANCE OF IBY PAYMENT BUILD PROCESS (IBYBUILD) - Start */
1817 
1818 	 FOR p in x_pmtsInPmtInstrTab.FIRST ..
1819              x_pmtsInPmtInstrTab.LAST LOOP
1820 
1821              FOR m in l_paper_special_docs_tab.FIRST ..
1822                  l_paper_special_docs_tab.LAST LOOP
1823 
1824                  IF (l_paper_special_docs_tab(m).payment_id
1825                      = x_pmtsInPmtInstrTab(p).payment_id) THEN
1826 
1827                      x_pmtsInPmtInstrTab(p).check_number
1828                          := l_paper_special_docs_tab(m).check_number;
1829 
1830 		     l_paper_special_docs_tab.DELETE(m);
1831 		     /* Delete this record as its updated,no need to have it in the next time we loop */
1832 		     EXIT; /* exit out the loop since check_number is unique. */
1833 
1834                  END IF;
1835 
1836              END LOOP; -- for m in l_paper_special_docs_tab
1837 
1838          END LOOP; -- for p in x_pmtsInPmtInstrTab
1839 
1840 	  /* 16366300: POOR PEFORMANCE OF IBY PAYMENT BUILD PROCESS (IBYBUILD) - End */
1841 
1842      ELSIF (l_processing_type = 'ELECTRONIC') THEN
1843 
1844          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1845 	         print_debuginfo(l_module_name, 'Provided processing '
1846 	             || 'type : '
1847 	             || l_processing_type
1848 	             || ' does not require printed '
1849 	             || 'documents. '
1850 	             || 'No processing will be performed.'
1851 	             );
1852          End IF;
1853 	          /*
1854 	           * There will only be one paper stock linked to
1855 	           * a particular payment document name, so we can
1856 	           * simply take the first record from the fetched
1857 	           * paper stocks table.
1858 	           */
1859 	          l_paper_stock_rec := l_paper_stocks_tab(1);
1860 
1861 	          IF (l_paper_stock_rec.doc_id IS NOT NULL) THEN
1862 
1863                     IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1864 	              print_debuginfo(l_module_name, 'Paper stock matching '
1865 	                  || 'profile id '
1866 	                  || x_pmtInstrRec.payment_profile_id
1867 	                  || ' has following attributes - Name: '
1868 	                  || l_paper_stock_rec.doc_name
1869 	                  || ', num setup docs: '
1870 	                  || l_paper_stock_rec.num_setup_docs
1871 	                  || ', num lines per stub: '
1872 	                  || l_paper_stock_rec.num_lines_per_stub
1873 	                  );
1874                    END IF;
1875 
1876 	          ELSE
1877 
1878                     --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1879 	              print_debuginfo(l_module_name, 'Fatal: No paper stock '
1880 	                  || 'linked to profile id '
1881 	                  || x_pmtInstrRec.payment_profile_id
1882 	                  || '. Payment instruction creation cannot continue. '
1883 	                  || 'Aborting program ..'
1884 	                  );
1885                    --END IF;
1886 
1887 	              x_return_status := -1;
1888 
1889 	              l_error_code := 'IBY_INS_NO_PAPER_STOCK';
1890 	              FND_MESSAGE.set_name('IBY', l_error_code);
1891 
1892 	              FND_MESSAGE.SET_TOKEN('INS_ID',
1893 	                  x_pmtInstrRec.payment_instruction_id,
1894 	                  FALSE);
1895 
1896 	              x_return_message := FND_MESSAGE.get;
1897 
1898 	              print_debuginfo(l_module_name, 'EXIT');
1899 	              RETURN;
1900 
1901 	          END IF;
1902 
1903 	          /*
1904 	           * If we reached here it means paper stock
1905 	           * attributes were retrieved successfully
1906 	           * for the profile on the instruction.
1907 	           */
1908 
1909 	          /*
1910 	           * Loop through all the payments for this
1911 	           * payment instruction, processing them one-by-one.
1912 	           */
1913 	          FOR j in x_pmtsInPmtInstrTab.FIRST .. x_pmtsInPmtInstrTab.LAST
1914 	              LOOP
1915 
1916                     IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1917 	              print_debuginfo(l_module_name, 'Processing payment '
1918 	                  || x_pmtsInPmtInstrTab(j).payment_id
1919 	                  || ' for instruction '
1920 	                  || x_pmtInstrRec.payment_instruction_id
1921 	                  || ' ..'
1922 	                  );
1923                    END IF;
1924 	          /* Removing the call to getDocumentCount, rather accessing
1925 	           * IBY_DOCS_PAYABLE_ALL table to get the count of the
1926 	  	  * documents
1927 	  	  */
1928 	            /*  l_docs_count := getDocumentCountForPayment(
1929 	                                  x_pmtsInPmtInstrTab(j).payment_id,
1930 	                                  x_pmtsInPmtInstrTab
1931 	                                  );
1932 	 	    */
1933 
1934 	 	            SELECT
1935 	  	                 COUNT(*)
1936 	 		    INTO
1937 	  	                 x_pmtsInPmtInstrTab(j).document_count
1938 	  	            FROM
1939 	  	                 IBY_DOCS_PAYABLE_ALL
1940 	  	            WHERE
1941 	  	                 payment_id =  x_pmtsInPmtInstrTab(j).payment_id
1942 	  	            AND
1943 	  	                 document_status = DOC_STATUS_PAY_CREATED;
1944 
1945 
1946 	  	            l_docs_count := x_pmtsInPmtInstrTab(j).document_count;
1947 	              IF (l_docs_count <= 0) THEN
1948 	                  /*
1949 	                   * A successful payment must be linked to at least
1950 	                   * least one successful document payable. If not
1951 	                   * there is a data consistency issue.
1952 	                   *
1953 	                   * Raise an alert and abort the program.
1954 	                   */
1955                     --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1956 	                  print_debuginfo(l_module_name, 'Fatal: No successful '
1957 	                      || 'docs were found for successful pmt with id '
1958 	                      || x_pmtsInPmtInstrTab(j).payment_id
1959 	                      || '. Possible data corruption. '
1960 	                      || 'Aborting program ..'
1961 	                      );
1962                    --END IF;
1963 
1964 	                   x_return_status := -1;
1965 
1966 	                   l_error_code := 'IBY_INS_PMT_NO_DOCS';
1967 	                   FND_MESSAGE.set_name('IBY', l_error_code);
1968 
1969 	                   FND_MESSAGE.SET_TOKEN('PMT_ID',
1970 	                      x_pmtsInPmtInstrTab(j).payment_id,
1971 	                      FALSE);
1972 
1973 	                   FND_MESSAGE.SET_TOKEN('INS_ID',
1974 	                      x_pmtInstrRec.payment_instruction_id,
1975 	                      FALSE);
1976 
1977 	                   x_return_message := FND_MESSAGE.get;
1978 
1979 	                   print_debuginfo(l_module_name, 'EXIT');
1980 	                   RETURN;
1981 
1982 	              END IF;
1983 
1984 	              l_num_printed_docs := getNumPrintedDocsByFormula(
1985 	                                        l_docs_count,
1986 	                                        l_paper_stock_rec.
1987 	                                            num_lines_per_stub
1988 	                                        );
1989 
1990                     IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1991 	              print_debuginfo(l_module_name, 'For payment id '
1992 	                  || x_pmtsInPmtInstrTab(j).payment_id
1993 	                  || ', docs count on payment: '
1994 	                  || l_docs_count
1995 	                  || ', lines per stub on stock: '
1996 	                  || l_paper_stock_rec.num_lines_per_stub
1997 	                  || ', calculated number of printed docs: '
1998 	                  || l_num_printed_docs);
1999                    END IF;
2000 
2001 	              /*
2002 	               * Add the details about the setup docs and
2003 	               * overflow docs for this payment into the
2004 	               * special docs table. This special docs table
2005 	               * will be used for inserting dummy payments
2006 	               * into the IBY_DOCS_PAYABLE_ALL and
2007 	               * IBY_PAYMENTS_ALL tables to account for setup
2008 	               * and overflow checks.
2009 	               */
2010 	              l_paper_special_docs_rec.payment_id          :=
2011 	                  x_pmtsInPmtInstrTab(j).payment_id;
2012 
2013 	              l_paper_special_docs_rec.instruction_id      :=
2014 	                  x_pmtsInPmtInstrTab(j).pay_instr_id;
2015 
2016 	              /*
2017 	               * Only one printed document per payment will be a
2018 	               * valid payment document. The rest of the documents
2019 	               * will be overflow documents that will be void and
2020 	               * are only used to store the document payable
2021 	               * ids.
2022 	               */
2023 	              l_paper_special_docs_rec.num_overflow_docs   :=
2024 	                  l_num_printed_docs - 1;
2025 
2026 	              /*
2027 	               * Number of setup documents to print is
2028 	               * specified in the paper stock set up.
2029 	               */
2030 	              l_paper_special_docs_rec.num_setup_docs      :=
2031 	                  l_paper_stock_rec.num_setup_docs;
2032 
2033 	              /*
2034 	               * Lines per stub in used in populating
2035 	               * dummy documents payable for this
2036 	               * payment.
2037 	               */
2038 	              l_paper_special_docs_rec.num_lines_per_stub  :=
2039 	                  l_paper_stock_rec.num_lines_per_stub;
2040 
2041 	              /* add record to dummy docs table */
2042 	              l_paper_special_docs_tab(l_paper_special_docs_tab.COUNT
2043 	                  + 1) := l_paper_special_docs_rec;
2044 
2045 	          END LOOP; -- for each payment in this instruction
2046 
2047 	          /*
2048 	           * If we reached here, it means that 'num overflow docs'
2049 	           * and 'num setup docs' has been populated for each
2050 	           * paper payment in the l_paper_special_docs_tab table.
2051 	           *
2052 	           * Use this information to create appropriate number
2053 	           * of dummy payments (to insert into IBY_PAYMENTS_ALL table)
2054 	           * and corresponding documents (to insert into
2055 	           * IBY_DOCS_PAYABLE_ALL table).
2056 	           */
2057                    /*Special Paper Doc Handling is not required for Electronic type of payments*/
2058 	          /*performSpecialPaperDocHandling(
2059 	              l_paper_special_docs_tab,
2060 	              x_dummyPaperPmtsTab,
2061 	              x_setupDocsTab,
2062 	              x_overflowDocsTab
2063 	              );*/
2064 
2065 	          /*
2066 	           * After setup and overflow payments have been
2067 	           * handled, we can start assigning physical check
2068 	           * numbers to the paper payments.
2069 	           *
2070 	           * The 'paper special docs tab' holds real payments
2071 	           * that have to be printed onto paper; the 'paper pmts
2072 	           * tab' holds the dummy payments that also have to
2073 	           * printed onto paper. So both types of payments
2074 	           * need to be provided with check numbers.
2075 	           */
2076 	          assignElectronicCheckNumbers(
2077 	              x_pmtInstrRec,
2078 	              l_paper_stock_rec.doc_id,
2079 	              p_user_assgn_num,
2080 	              l_paper_special_docs_tab,
2081 	              x_dummyPaperPmtsTab,
2082 	              x_instrErrorTab,
2083 	              x_insTokenTab,
2084 	              x_return_message,
2085 	              x_return_status,
2086 	              x_msg_count,
2087 	              x_msg_data
2088 	              );
2089 
2090 	          IF (x_return_status = -1) THEN
2091 
2092 	              /*
2093 	               * Return back the x_return status and
2094 	               * x_return_message values that we received
2095 	               * from assignCheckNumbers() call.
2096 	               */
2097                     --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2098 	              print_debuginfo(l_module_name, 'Check numbering did '
2099 	                  || 'not succeed.'
2100 	                  );
2101 	              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2102 	              print_debuginfo(l_module_name, 'EXIT');
2103                    END IF;
2104 	              RETURN;
2105 
2106 	          END IF;
2107 
2108 	          /*
2109 	           * l_paper_special_docs_tab contains list of paper
2110 	           * payments that now have check number assigned.
2111 	           *
2112 	           * But this data structure is a local object. We
2113 	           * have to copy back the check numbers into
2114 	           * x_pmtsInPmtInstrTab which will be used to
2115 	           * finally update the database.
2116 	           */
2117 	  /* 16366300: POOR PEFORMANCE OF IBY PAYMENT BUILD PROCESS (IBYBUILD) - Start */
2118 
2119 	 FOR p in x_pmtsInPmtInstrTab.FIRST ..
2120              x_pmtsInPmtInstrTab.LAST LOOP
2121 
2122              FOR m in l_paper_special_docs_tab.FIRST ..
2123                  l_paper_special_docs_tab.LAST LOOP
2124 
2125                  IF (l_paper_special_docs_tab(m).payment_id
2126                      = x_pmtsInPmtInstrTab(p).payment_id) THEN
2127 
2128                      x_pmtsInPmtInstrTab(p).check_number
2129                          := l_paper_special_docs_tab(m).check_number;
2130 
2131 		     l_paper_special_docs_tab.DELETE(m);
2132 		     /* Delete this record as its updated,no need to have it in the next time we loop */
2133 		     EXIT; /* exit out the loop since check_number is unique. */
2134 
2135                  END IF;
2136 
2137              END LOOP; -- for m in l_paper_special_docs_tab
2138 
2139          END LOOP; -- for p in x_pmtsInPmtInstrTab
2140 
2141 	  /* 16366300: POOR PEFORMANCE OF IBY PAYMENT BUILD PROCESS (IBYBUILD) - End */
2142 
2143 
2144      ELSE
2145 
2146          --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2147 	         print_debuginfo(l_module_name, 'Unknown processing '
2148 	             || 'type provided: '
2149 	             || l_processing_type
2150 	             || '. Aborting program ..'
2151 	             );
2152 
2153          --END IF;
2154           x_return_status := -1;
2155 
2156           l_error_code := 'IBY_INS_UNK_PROC_TYPE';
2157           FND_MESSAGE.set_name('IBY', l_error_code);
2158 
2159           FND_MESSAGE.SET_TOKEN('UNK_PROC_TYPE',
2160               l_processing_type,
2161               FALSE);
2162 
2163           FND_MESSAGE.SET_TOKEN('INS_ID',
2164               x_pmtInstrRec.payment_instruction_id,
2165               FALSE);
2166 
2167           x_return_message := FND_MESSAGE.get;
2168 
2169           IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2170 	          print_debuginfo(l_module_name, 'EXIT');
2171           END IF;
2172           RETURN;
2173 
2174      END IF; -- if processing_type = 'PRINTED'
2175 
2176      /*
2177       * If we reached here, return success.
2178       */
2179      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2180 	     print_debuginfo(l_module_name, 'Returning success response ..');
2181      END IF;
2182      x_return_status := 0;
2183      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2184 	     print_debuginfo(l_module_name, 'EXIT');
2185 
2186      END IF;
2187  END processPaperPayments;
2188 
2189 /*--------------------------------------------------------------------
2190  | NAME:
2191  |     getDocumentCountForPayment
2192  |
2193  | PURPOSE:
2194  |
2195  |
2196  |
2197  | PARAMETERS:
2198  |     IN
2199  |
2200  |     OUT
2201  |
2202  |
2203  | RETURNS:
2204  |
2205  | NOTES:
2206  |
2207  *---------------------------------------------------------------------*/
2208  FUNCTION getDocumentCountForPayment(
2209      p_payment_id         IN IBY_PAYMENTS_ALL.payment_id%TYPE,
2210      p_pmtsInPmtInstrTab  IN IBY_PAYINSTR_PUB.pmtsInpmtInstrTabType
2211      )
2212  RETURN NUMBER
2213  IS
2214  l_doc_count  NUMBER := -1;
2215 
2216  BEGIN
2217 
2218      FOR i in p_pmtsInPmtInstrTab.FIRST .. p_pmtsInPmtInstrTab.LAST LOOP
2219 
2220          IF (p_pmtsInPmtInstrTab(i).payment_id = p_payment_id) THEN
2221 
2222              l_doc_count := p_pmtsInPmtInstrTab(i).document_count;
2223              EXIT;
2224 
2225          END IF;
2226 
2227      END LOOP;
2228 
2229      RETURN l_doc_count;
2230 
2231  END getDocumentCountForPayment;
2232 
2233 /*--------------------------------------------------------------------
2234  | NAME:
2235  |     assignCheckNumbers
2236  |
2237  | PURPOSE:
2238  |
2239  |
2240  |
2241  | PARAMETERS:
2242  |     IN
2243  |
2244  |
2245  |     OUT
2246  |
2247  |
2248  | RETURNS:
2249  |
2250  |
2251  | NOTES:
2252  |     This method will perform a COMMIT.
2253  |
2254  *---------------------------------------------------------------------*/
2255  PROCEDURE assignCheckNumbers(
2256      x_pmtInstrRec       IN OUT NOCOPY IBY_PAY_INSTRUCTIONS_ALL%ROWTYPE,
2257      p_payment_doc_id    IN CE_PAYMENT_DOCUMENTS.payment_document_id%TYPE,
2258      p_user_assgn_num    IN IBY_PAYMENTS_ALL.paper_document_number%TYPE,
2259      x_paperPmtsTab      IN OUT NOCOPY paperPmtsSpecialDocsTabType,
2260      x_dummyPaperPmtsTab IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
2261      x_instrErrorTab     IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.docErrorTabType,
2262      x_insTokenTab       IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.
2263                                            trxnErrTokenTabType,
2264      x_return_message    IN OUT NOCOPY VARCHAR2,
2265      x_return_status     IN OUT NOCOPY NUMBER,
2266      x_msg_count         IN OUT NOCOPY NUMBER,
2267      x_msg_data          IN OUT NOCOPY VARCHAR2
2268      )
2269  IS
2270 
2271  l_paper_pmts_count     NUMBER := 0;
2272  l_last_used_check_num  NUMBER := 0;
2273  l_last_avail_check_num NUMBER := 0;
2274  l_physical_stock_count NUMBER := 0;
2275  l_anticipated_last_check_num  NUMBER := 0;
2276 
2277  l_pmt_doc_name      VARCHAR2(200) := '';
2278  l_pmt_instr_id      IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_id%TYPE;
2279 
2280  l_error_code        IBY_TRANSACTION_ERRORS.error_code%TYPE;
2281  l_instr_err_rec     IBY_TRANSACTION_ERRORS%ROWTYPE;
2282  l_token_rec         IBY_TRXN_ERROR_TOKENS%ROWTYPE;
2283 
2284  l_send_to_file_flag VARCHAR2(1);
2285  l_instr_status      IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_status%TYPE;
2286 
2287  l_single_pmt_flag   BOOLEAN;
2288  l_nos_avlbl_flag    BOOLEAN;
2289  l_used_flag         BOOLEAN;
2290 
2291  l_module_name       VARCHAR2(200) := G_PKG_NAME || '.assignCheckNumbers';
2292 
2293  BEGIN
2294 
2295      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2296 	     print_debuginfo(l_module_name, 'ENTER');
2297 
2298      END IF;
2299      /*
2300       * Total number of paper payments is sum of real paper payments
2301       * and dummy paper payments.
2302       */
2303      l_paper_pmts_count := x_paperPmtsTab.COUNT + x_dummyPaperPmtsTab.COUNT;
2304 
2305      /* should never come into if, but just in case */
2306      IF (l_paper_pmts_count = 0) THEN
2307 
2308          /*
2309           * Shouldn't come here. This method was called because there
2310           * was atleast one payment instruction with processing type
2311           * 'PAPER'. This implies that there should be at least one
2312           * payment instruction with processing type 'PAPER'.
2313           *
2314           * If no such payment exists, about the program.
2315           */
2316          --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2317 	         print_debuginfo(l_module_name, 'Total # of paper payments '
2318 	             || 'is 0. Possible data corruption. Aborting ..'
2319 	             );
2320 
2321 	         print_debuginfo(l_module_name, 'EXIT');
2322          --END IF;
2323          x_return_status := -1;
2324 
2325          l_error_code := 'IBY_INS_PMTS_NOT_FOUND';
2326          FND_MESSAGE.set_name('IBY', l_error_code);
2327 
2328          FND_MESSAGE.SET_TOKEN('INS_ID',
2329              x_pmtInstrRec.payment_instruction_id,
2330              FALSE);
2331 
2332          FND_MSG_PUB.ADD;
2333 
2334          FND_MSG_PUB.COUNT_AND_GET(
2335              p_count => x_msg_count,
2336              p_data  => x_msg_data
2337              );
2338 
2339          x_return_message := FND_MESSAGE.get;
2340 
2341          RETURN;
2342 
2343      ELSE
2344 
2345          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2346 	         print_debuginfo(l_module_name, 'Total # of paper payments: '
2347 	             || l_paper_pmts_count
2348 	             );
2349 
2350          END IF;
2351      END IF;
2352 
2353      /*
2354       * When this printed payment instruction is formatted, the
2355       * output can be sent to any of two places:
2356       *
2357       * a. To the printer
2358       * b. To a file (for printing outside the Oracle system).
2359       *
2360       * The status of the payment instruction needs to be adjusted
2361       * as per this destination flag.
2362       */
2363      BEGIN
2364 
2365          SELECT
2366              send_to_file_flag
2367          INTO
2368              l_send_to_file_flag
2369          FROM
2370              IBY_PAYMENT_PROFILES
2371          WHERE
2372              payment_profile_id = x_pmtInstrRec.payment_profile_id
2373          ;
2374 
2375      EXCEPTION
2376          WHEN OTHERS THEN
2377 
2378          --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2379 	         print_debuginfo(l_module_name, 'Fatal: Exception when '
2380 	             || 'attempting to get "send to file flag" for payment '
2381 	             || 'instruction '
2382 	             || x_pmtInstrRec.payment_instruction_id
2383 	             || ' with payment profile id '
2384 	             || x_pmtInstrRec.payment_profile_id
2385 	             );
2386 
2387 	         print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
2388 	         print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
2389 
2390 	         print_debuginfo(l_module_name, 'Aborting numbering process ..');
2391 
2392          --END IF;
2393          x_return_status := -1;
2394 
2395          l_error_code := 'IBY_INS_PROF_EXCEP';
2396          FND_MESSAGE.set_name('IBY', l_error_code);
2397 
2398          FND_MESSAGE.SET_TOKEN('INS_ID',
2399              x_pmtInstrRec.payment_instruction_id,
2400              FALSE);
2401 
2402          FND_MESSAGE.SET_TOKEN('PROF_ID',
2403              x_pmtInstrRec.payment_profile_id,
2404              FALSE);
2405 
2406          FND_MSG_PUB.ADD;
2407 
2408          FND_MSG_PUB.COUNT_AND_GET(
2409              p_count => x_msg_count,
2410              p_data  => x_msg_data
2411              );
2412 
2413          x_return_message := FND_MESSAGE.get;
2414 
2415          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2416 	         print_debuginfo(l_module_name, 'EXIT');
2417 
2418          END IF;
2419          RETURN;
2420 
2421      END;
2422 
2423      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2424 	     print_debuginfo(l_module_name, 'For payment instruction '
2425 	         || x_pmtInstrRec.payment_instruction_id
2426 	         || ' with payment profile id '
2427 	         || x_pmtInstrRec.payment_profile_id
2428 	         || ', send to file flag: '
2429 	         || l_send_to_file_flag
2430 	         );
2431 
2432      END IF;
2433      /*
2434       * The payment instruction status is dependant upon
2435       * the 'send to file' flag. Preset the instruction
2436       * status appropriately.
2437       */
2438      IF (UPPER(l_send_to_file_flag) = 'Y') THEN
2439          l_instr_status := INS_STATUS_READY_TO_FORMAT;
2440      ELSE
2441          l_instr_status := INS_STATUS_READY_TO_PRINT;
2442      END IF;
2443 
2444      /*
2445       * Check whether the provided payments list consists
2446       * of a single payment.
2447       */
2448      l_single_pmt_flag := isSinglePayment(x_paperPmtsTab);
2449 
2450      /*
2451       * IMPORTANT NOTE:
2452       * Irrespective of whether this payment instruction
2453       * could be numbered successfully or not, we will
2454       * change the status of the payment instruction at
2455       * this point from 'CREATED' -> 'CREATED_READY_FOR_PRINTING'
2456       * or 'CREATED_READY_FOR_FORMATTING'.
2457       *
2458       * In case, the payments could be numbered successfully,
2459       * the new payment instruction status becomes a transient
2460       * status (because the format will immediately change the
2461       * payment status to 'FORMATTED').
2462       *
2463       * In case, the  numbering failed for some reason, or some
2464       * other exception was thrown, the payment instruction
2465       * will remain in the new status. This will be sufficient
2466       * for the UI to recognize that the payment instruction
2467       * did not finish the numbering operation successfully.
2468       *
2469       * Therefore, the UI will call the check numering flow
2470       * again, and we will have another go at numbering this
2471       * payment instruction.
2472       */
2473 
2474      /*
2475       * Blindly update the payment instruction status
2476       * (see above comment).
2477       */
2478      UPDATE
2479          IBY_PAY_INSTRUCTIONS_ALL
2480      SET
2481          payment_instruction_status = l_instr_status
2482      WHERE
2483          payment_instruction_id = x_pmtInstrRec.payment_instruction_id;
2484 
2485      /*
2486       * For single payments, do not perform any commits because
2487       * single payments API is session based and only the caller
2488       * decides to commit / not commit.
2489       */
2490      IF (l_single_pmt_flag <> TRUE) THEN
2491 
2492          /*
2493           * This commit is needed so that in case of any exceptions
2494           * in this method (e.g., payment document locked), the
2495           * payment instruction status is changed from 'CREATED'
2496           * to the next valid status.
2497           *
2498           * Payments in 'CREATED' status are not visible in the UI,
2499           * this is because 'CREATED' is a transient status.
2500           */
2501          COMMIT;
2502 
2503          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2504 	         print_debuginfo(l_module_name, 'Payment instruction '
2505 	             || x_pmtInstrRec.payment_instruction_id
2506 	             || ' status committed to '
2507 	             || l_instr_status
2508 	             || ' before numbering.'
2509 	             );
2510 
2511          END IF;
2512      END IF;
2513 
2514      /*
2515       * Pull up the details of the paper stock, like the
2516       * last used check number and the last available
2517       * check number.
2518       *
2519       * Note: This SELECT will lock the underlying base
2520       * table IBY_PAYMENT_DOCUMENTS_B. We need to lock this
2521       * table because we need to update the last_document_number.
2522       */
2523     SELECT
2524          payment_document_name,
2525          payment_instruction_id
2526      INTO
2527          l_pmt_doc_name,
2528          l_pmt_instr_id
2529      FROM
2530          CE_PAYMENT_DOCUMENTS
2531      WHERE
2532          payment_document_id = p_payment_doc_id
2533      ;
2534 
2535 
2536       IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2537 	      print_debuginfo(l_module_name, 'Got the payment document name');
2538 
2539       END IF;
2540      /*
2541       *
2542       * Pull up the details of the paper stock, like the
2543       * last used check number and the last available
2544       * check number.
2545       *
2546       * Note: This SELECT will lock the underlying base
2547       * table IBY_PAYMENT_DOCUMENTS_B. We need to lock this
2548       * table because we need to update the last_document_number.
2549       *
2550       *  If document is already locked for single payment,
2551       * NO_DATA_FOUND exception would be thrown.
2552       * Bug - 7499044
2553       */
2554      BEGIN
2555      SELECT
2556          NVL(last_issued_document_number, 0),
2557          NVL(last_available_document_number, -1),
2558          payment_document_name,
2559          payment_instruction_id
2560      INTO
2561          l_last_used_check_num,
2562          l_last_avail_check_num,
2563          l_pmt_doc_name,
2564          l_pmt_instr_id
2565      FROM
2566          CE_PAYMENT_DOCUMENTS
2567      WHERE
2568          payment_document_id = p_payment_doc_id
2569      FOR UPDATE SKIP LOCKED
2570      ;
2571      EXCEPTION
2572         WHEN NO_DATA_FOUND THEN
2573                      --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2574 	                     print_debuginfo(l_module_name, 'Payment document '
2575 	             || ''''
2576 	             || l_pmt_doc_name
2577 	             || ''''
2578 	             || ' with payment doc id '
2579 	             || p_payment_doc_id
2580 	             || ' has been locked from payments workbench ',
2581 	             FND_LOG.LEVEL_UNEXPECTED
2582 	             );
2583 
2584 	         print_debuginfo(l_module_name, 'Processing cannot continue '
2585 	             || 'because payment document is unavailable (locked).',
2586 	             FND_LOG.LEVEL_UNEXPECTED
2587 	             );
2588 
2589 	         print_debuginfo(l_module_name, 'Changing the status of the '
2590 	             || 'payment instruction to '
2591 	             || l_instr_status
2592 	             );
2593 
2594          --END IF;
2595          /*
2596           * Fix for bug 5735030:
2597           *
2598           * Populate error message in output file so that
2599           * the user knows the cause of the failure even
2600           * if logging is turned off.
2601           */
2602          l_error_code := 'IBY_PMT_DOC_SING_LOCKED';
2603          FND_MESSAGE.SET_NAME('IBY', l_error_code);
2604 
2605          FND_MESSAGE.SET_TOKEN('DOC_NAME',
2606              l_pmt_doc_name,
2607              FALSE);
2608 
2609          FND_FILE.PUT_LINE(FND_FILE.OUTPUT, FND_MESSAGE.GET);
2610 
2611          /*
2612           * Return failure status.
2613           */
2614          x_return_status := -1;
2615 
2616          l_error_code := 'IBY_PMT_DOC_SING_LOCKED';
2617          FND_MESSAGE.set_name('IBY', l_error_code);
2618 
2619          FND_MESSAGE.SET_TOKEN('DOC_NAME',
2620              l_pmt_doc_name,
2621              FALSE);
2622 
2623          FND_MSG_PUB.ADD;
2624 
2625          FND_MSG_PUB.COUNT_AND_GET(
2626              p_count => x_msg_count,
2627              p_data  => x_msg_data
2628              );
2629 
2630          x_return_message := FND_MESSAGE.get;
2631 
2632          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2633 	         print_debuginfo(l_module_name, 'EXIT');
2634          END IF;
2635          RETURN;
2636 
2637 
2638      END;
2639      IF (l_pmt_instr_id IS NOT NULL) THEN
2640          --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2641 	         print_debuginfo(l_module_name, 'Payment document '
2642 	             || ''''
2643 	             || l_pmt_doc_name
2644 	             || ''''
2645 	             || ' with payment doc id '
2646 	             || p_payment_doc_id
2647 	             || ' has been locked by payment instruction '
2648 	             || l_pmt_instr_id,
2649 	             FND_LOG.LEVEL_UNEXPECTED
2650 	             );
2651 
2652 	         print_debuginfo(l_module_name, 'Processing cannot continue '
2653 	             || 'because payment document is unavailable (locked).',
2654 	             FND_LOG.LEVEL_UNEXPECTED
2655 	             );
2656 
2657 	         print_debuginfo(l_module_name, 'Changing the status of the '
2658 	             || 'payment instruction to '
2659 	             || l_instr_status
2660 	             );
2661 
2662          --END IF;
2663          /*
2664           * Fix for bug 5735030:
2665           *
2666           * Populate error message in output file so that
2667           * the user knows the cause of the failure even
2668           * if logging is turned off.
2669           */
2670          l_error_code := 'IBY_INS_PMT_DOC_LOCKED_DETAIL';
2671          FND_MESSAGE.SET_NAME('IBY', l_error_code);
2672 
2673          FND_MESSAGE.SET_TOKEN('THIS_INS_NUM',
2674              x_pmtInstrRec.payment_instruction_id,
2675              FALSE);
2676 
2677          FND_MESSAGE.SET_TOKEN('PREV_INS_NUM',
2678              l_pmt_instr_id,
2679              FALSE);
2680 
2681          FND_MESSAGE.SET_TOKEN('DOC_NAME',
2682              l_pmt_doc_name,
2683              FALSE);
2684 
2685          FND_FILE.PUT_LINE(FND_FILE.OUTPUT, FND_MESSAGE.GET);
2686 
2687          /*
2688           * Return failure status.
2689           */
2690          x_return_status := -1;
2691 
2692          l_error_code := 'IBY_INS_PMT_DOC_LOCKED';
2693          FND_MESSAGE.set_name('IBY', l_error_code);
2694 
2695          FND_MESSAGE.SET_TOKEN('INS_ID',
2696              l_pmt_instr_id,
2697              FALSE);
2698 
2699          FND_MSG_PUB.ADD;
2700 
2701          FND_MSG_PUB.COUNT_AND_GET(
2702              p_count => x_msg_count,
2703              p_data  => x_msg_data
2704              );
2705 
2706          x_return_message := FND_MESSAGE.get;
2707 
2708          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2709 	         print_debuginfo(l_module_name, 'EXIT');
2710          END IF;
2711          RETURN;
2712 
2713      END IF;
2714 
2715      /*
2716       * Log warnings if there is any missing/incomplete information.
2717       */
2718      IF (l_last_avail_check_num = -1) THEN
2719 
2720          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2721 	         print_debuginfo(l_module_name, 'Warning: payment document id '
2722 	             || p_payment_doc_id
2723 	             || ' has no last available document number set. '
2724 	             || 'Assuming that infinite number of paper documents '
2725 	             || 'can be printed for this payment document.'
2726 	             );
2727 
2728          END IF;
2729      END IF;
2730 
2731      IF (l_last_used_check_num = 0) THEN
2732 
2733          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2734 	         print_debuginfo(l_module_name, 'Warning: payment document id '
2735 	             || p_payment_doc_id
2736 	             || ' has last used document number set to zero. '
2737 	             || 'Assuming that no paper documents have yet '
2738 	             || 'been printed for this payment document.'
2739 	             );
2740 
2741          END IF;
2742      END IF;
2743 
2744 
2745      /*
2746       * If user has explicitly provided a start number for check
2747       * numbering, we have to use it in our numbering logic.
2748       * This will only happen for single payments.
2749       *
2750       * For Build Program invoked numbering, we will always start
2751       * from the last issued check number on the payment document + 1.
2752       */
2753      IF (p_user_assgn_num IS NULL) THEN
2754 
2755          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2756 	         print_debuginfo(l_module_name, 'User has not explicitly '
2757 	             || 'provided a check number to start numbering from. '
2758 	             || 'Numbering will start from last issued check number '
2759 	             || 'on check stock.'
2760 	             );
2761 
2762          END IF;
2763      ELSE
2764 
2765          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2766 	         print_debuginfo(l_module_name, 'User has explicitly '
2767 	             || 'provided start number for numbering: '
2768 	             || p_user_assgn_num
2769 	             );
2770 
2771          END IF;
2772          /*
2773           * The code below uses the variable 'l_last_used_check_num'
2774           * as the starting number for check numbering. The numbering
2775           * will begin from l_last_used_check_num + 1.
2776           *
2777           * If the user has explicitly provided a start number for
2778           * numbering, we need to adjust the l_last_used_check_num
2779           * value accordingly.
2780           */
2781          l_last_used_check_num := p_user_assgn_num - 1;
2782 
2783      END IF;
2784 
2785      /*
2786       * Check if enough paper documents are available to complete
2787       * this payment instruction.
2788       *
2789       * Perform this check only if a value has been provided
2790       * for the last available document number. If no value is
2791       * set assume that an infinite number of checks can be
2792       * printed for this paper stock (payment document).
2793       */
2794      IF (l_last_avail_check_num <> -1) THEN
2795 
2796          /*
2797           * Check if enough paper documents are available to complete
2798           * this payment instruction.
2799           */
2800          l_physical_stock_count := l_last_avail_check_num
2801                                        - l_last_used_check_num;
2802 
2803          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2804 	         print_debuginfo(l_module_name, 'Available paper stock = '
2805 	             || l_physical_stock_count
2806 	             || ' for payment document name '
2807 	             || ''''
2808 	             || l_pmt_doc_name
2809 	             || ''''
2810 	             );
2811 
2812          END IF;
2813          IF (l_physical_stock_count < l_paper_pmts_count) THEN
2814 
2815              /*
2816               * Not enough paper stock is available to print
2817               * the checks for this payment instruction.
2818               *
2819               * Set the status of the payment instruction to
2820               * failed.
2821               */
2822 
2823 	             print_debuginfo(l_module_name, 'Deferring payment '
2824 	                 || 'instruction print '
2825 	                 || x_pmtInstrRec.payment_instruction_id
2826 	                 || ' because of insufficient paper stock.',
2827 	                 FND_LOG.LEVEL_UNEXPECTED
2828 	                 );
2829 
2830 
2831              x_pmtInstrRec.payment_instruction_status := l_instr_status;
2832 
2833              l_error_code := 'IBY_INS_INSUFFICIENT_PAY_DOCS';
2834 
2835              FND_MESSAGE.set_name('IBY', l_error_code);
2836 
2837              FND_MESSAGE.SET_TOKEN('NUM_AVAIL',
2838                  l_physical_stock_count,
2839                  FALSE);
2840 
2841              l_token_rec.token_name  := 'NUM_AVAIL';
2842              l_token_rec.token_value := l_physical_stock_count;
2843              x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
2844 
2845              FND_MESSAGE.SET_TOKEN('NUM_REQD',
2846                  l_paper_pmts_count,
2847                  FALSE);
2848 
2849              l_token_rec.token_name  := 'NUM_REQD';
2850              l_token_rec.token_value := l_paper_pmts_count;
2851              x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
2852 
2853              /*
2854               * Once we fail a pmt instruction, we must add a
2855               * corresponding error message to the errors table.
2856               */
2857              IBY_PAYINSTR_UTILS_PKG.createErrorRecord(
2858                  x_pmtInstrRec.payment_instruction_id,
2859                  x_pmtInstrRec.payment_instruction_status,
2860                  l_error_code,
2861                  FND_MESSAGE.get,
2862                  'N',
2863                  l_instr_err_rec
2864                  );
2865 
2866              IBY_VALIDATIONSETS_PUB.insertIntoErrorTable(
2867                  l_instr_err_rec,
2868                  x_instrErrorTab,
2869                  x_insTokenTab
2870                  );
2871 
2872              /* add error message to msg stack */
2873              FND_MSG_PUB.ADD;
2874 
2875              FND_MSG_PUB.COUNT_AND_GET(
2876                  p_count => x_msg_count,
2877                  p_data  => x_msg_data
2878                  );
2879 
2880              /* set error message to return to caller */
2881              x_return_message := FND_MESSAGE.get;
2882 
2883              /*
2884               * Now, raise an exception. This will be caught
2885               * in the exception handler below and the changes
2886               * made to the DB in this transaction
2887               * will be rolled back.
2888               */
2889              APP_EXCEPTION.RAISE_EXCEPTION;
2890 
2891          ELSE
2892 
2893              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2894 	             print_debuginfo(l_module_name, 'Sufficient paper stock '
2895 	                 || 'is available to print this instruction.'
2896 	                 );
2897 
2898              END IF;
2899          END IF;
2900 
2901      END IF; -- l_last_avail_check_num <> -1
2902 
2903      /*
2904       * If sufficient paper stock is available, we will be using
2905       * up the paper stock by assigning it to the available
2906       * paper payments. Therefore, update the last used paper
2907       * stock number in CE_PAYMENT_DOCUMENTS.
2908       *
2909       * That way if another instance of the payment instruction
2910       * creation program is operating concurrently, it will
2911       * be blocked by the SELECT .. FOR UPDATE statement in
2912       * this method.
2913       *
2914       */
2915      l_anticipated_last_check_num := l_last_used_check_num
2916                                          + l_paper_pmts_count;
2917 
2918      /*
2919       * We will be printing the checks starting with
2920       * paper doc num 'l_last_used_check_num + 1' and
2921       * ending with paper doc num l_anticipated_last_check_num.
2922       *
2923       * Check whether all the paper doc numbers within this
2924       * range are available. We cannot have any gaps in the
2925       * numbering because checks have to be numbered
2926       * contiguously.
2927       */
2928      l_nos_avlbl_flag := isContigPaperNumAvlbl(
2929                              p_payment_doc_id,
2930                              l_last_used_check_num + 1,
2931                              l_anticipated_last_check_num
2932                              );
2933 
2934      IF (l_nos_avlbl_flag = FALSE) THEN
2935 
2936          --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2937 	         print_debuginfo(l_module_name, 'Contiguous paper stock '
2938 	             || 'is not available for printing payment instruction '
2939 	             || x_pmtInstrRec.payment_instruction_id
2940 	             );
2941 
2942          --END IF;
2943          /*
2944           * Return failure status.
2945           */
2946          x_return_status := -1;
2947 
2948          l_error_code := 'IBY_INS_NSF_CONTIG_NUM';
2949          FND_MESSAGE.set_name('IBY', l_error_code);
2950 
2951          FND_MESSAGE.SET_TOKEN('NUM_PMT_DOCS',
2952              l_paper_pmts_count,
2953              FALSE);
2954 
2955          FND_MSG_PUB.ADD;
2956 
2957          FND_MSG_PUB.COUNT_AND_GET(
2958              p_count => x_msg_count,
2959              p_data  => x_msg_data
2960              );
2961 
2962          x_return_message := FND_MESSAGE.get;
2963 
2964          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
2965 	         print_debuginfo(l_module_name, 'EXIT');
2966          END IF;
2967          RETURN;
2968 
2969      END IF;
2970 
2971      /*
2972       * A paper document number (check number) is considered
2973       * unused if it is not present in IBY_USED_PAYMENT_DOCS
2974       * table.
2975       *
2976       * This logic will work when check numbering is invoked
2977       * from the Build Program. In this case, the numbering
2978       * logic always starts with the last issued doc number + 1
2979       * when assigning new check numbers. Therefore, the
2980       * check numbers will always be unique (unused).
2981       *
2982       * However, when check numbering is invoked for single
2983       * payments, the user is allowed to provide the start
2984       * number for check numbering. It is possible that
2985       * a payment has already been numbered with the user
2986       * provided start number, but this paper document may
2987       * not yet have been inserted into the IBY_USED_PAYMENT_DOCS
2988       * table (because the user has not yet confirmed the
2989       * payment).
2990       *
2991       * Therefore, for single payments, when the user provides
2992       * the start number for check numbering, we will have to
2993       * verify that the provided number is unused by checking
2994       * the paper document number on existing payments.
2995       */
2996      IF (p_user_assgn_num IS NOT NULL) THEN
2997 
2998          l_used_flag := isPaperNosUsedOnExistPmt(
2999                             p_payment_doc_id,
3000                             l_last_used_check_num + 1,
3001                             l_anticipated_last_check_num);
3002 
3003          IF (l_used_flag = TRUE) THEN
3004 
3005              --IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3006 	             print_debuginfo(l_module_name, 'Paper document number(s) '
3007 	                 || 'generated after numbering are invalid (already used). '
3008 	                 || 'User needs to provide a new start number or use '
3009 	                 || 'the defaulted start number.'
3010 	                 );
3011 
3012              --END IF;
3013              /*
3014               * Return failure status.
3015               */
3016              x_return_status := -1;
3017 
3018              l_error_code := 'IBY_INS_ALREADY_USED_NUM';
3019              FND_MESSAGE.set_name('IBY', l_error_code);
3020 
3021              FND_MSG_PUB.ADD;
3022 
3023              FND_MSG_PUB.COUNT_AND_GET(
3024                  p_count => x_msg_count,
3025                  p_data  => x_msg_data
3026                  );
3027 
3028              x_return_message := FND_MESSAGE.get;
3029 
3030              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3031 	             print_debuginfo(l_module_name, 'EXIT');
3032              END IF;
3033              RETURN;
3034 
3035          ELSE
3036 
3037              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3038 	             print_debuginfo(l_module_name, 'Paper document number(s) '
3039 	                 || 'generated after numbering are unused. '
3040 	                 );
3041 
3042              END IF;
3043          END IF;
3044 
3045      END IF;
3046 
3047      /*
3048       * For single payments, the payment document should
3049       * not be locked (see bug 4597718).
3050       */
3051      IF (l_single_pmt_flag = TRUE) THEN
3052 
3053          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3054 	         print_debuginfo(l_module_name, 'This is a single payment. '
3055 	             || 'Payment document will not be locked ..'
3056 	             );
3057 
3058          END IF;
3059          /*
3060           * Update the check stock to reflect the latest used
3061           * check number.
3062           */
3063          UPDATE
3064              CE_PAYMENT_DOCUMENTS
3065          SET
3066              last_issued_document_number = l_anticipated_last_check_num
3067          WHERE
3068              payment_document_id         = p_payment_doc_id
3069          AND
3070 	    last_issued_document_number < l_anticipated_last_check_num
3071          ;
3072 
3073      ELSE
3074 
3075          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3076 	         print_debuginfo(l_module_name, 'This is not a single payment. '
3077 	             || 'Payment document will be locked ..'
3078 	             );
3079 
3080          END IF;
3081          /*
3082           * Update the check stock to reflect the latest used
3083           * check number, and lock the check stock.
3084           */
3085          UPDATE
3086              CE_PAYMENT_DOCUMENTS
3087          SET
3088              last_issued_document_number = l_anticipated_last_check_num,
3089              payment_instruction_id      = x_pmtInstrRec.payment_instruction_id
3090          WHERE
3091              payment_document_id         = p_payment_doc_id
3092 
3093          ;
3094 
3095      END IF;
3096 
3097      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3098 	     print_debuginfo(l_module_name, 'Finished updating the last '
3099 	         || 'available check number in CE_PAYMENT_DOCUMENTS. '
3100 	         || 'Current last check number: '
3101 	         || l_anticipated_last_check_num
3102 	         );
3103 
3104      END IF;
3105      /* uncomment for debug purposes */
3106      --print_debuginfo(l_module_name, 'x_dummyPaperPmtsTab.COUNT: '
3107      --    || x_dummyPaperPmtsTab.COUNT);
3108      --print_debuginfo(l_module_name, 'x_paperPmtsTab.COUNT: '
3109      --    || x_paperPmtsTab.COUNT);
3110 
3111      /*
3112       * Assign contiguous check numbers to the setup checks.
3113       * These are dummy checks that are printed at the
3114       * beginning of the payment instruction print run.
3115       */
3116      IF (x_dummyPaperPmtsTab.COUNT <> 0) THEN
3117 
3118          FOR i in x_dummyPaperPmtsTab.FIRST .. x_dummyPaperPmtsTab.LAST LOOP
3119 
3120              IF (x_dummyPaperPmtsTab(i).payment_status = 'VOID_BY_SETUP') THEN
3121 
3122                  l_last_used_check_num := l_last_used_check_num + 1;
3123                  x_dummyPaperPmtsTab(i).paper_document_number
3124                      := l_last_used_check_num;
3125 
3126              END IF;
3127 
3128          END LOOP; -- for all setup payments in x_dummyPaperPmtsTab
3129 
3130      END IF;
3131 
3132      /* handle real checks and overflow checks here */
3133      FOR i in x_paperPmtsTab.FIRST .. x_paperPmtsTab.LAST LOOP
3134 
3135          /*
3136           * We must assign the check numbers in sequence
3137           * so that when a paper payment is printed, all the
3138           * paper documents for that payment have contiguous
3139           * number.
3140           */
3141 
3142 
3143          /*
3144           * If this payment has any overflow documents, then
3145           * some overflow payments would have been created.
3146           * Assign check numbers to these overflow payments
3147           * too.
3148           *
3149           * Overflow payments are created one-by-one and are
3150           * assigned incremental payment ids. So no need to sort
3151           * these overflow payments (they are already sorted).
3152           *
3153           * Simply find the overflow payments related to the real
3154           * payment and assign them with contiguous check numbers.
3155           */
3156          IF (x_dummyPaperPmtsTab.COUNT <> 0) THEN
3157 
3158              FOR j in x_dummyPaperPmtsTab.FIRST .. x_dummyPaperPmtsTab.LAST LOOP
3159 
3160                  /*
3161                   * The external_bank_account_id field actually contains
3162                   * the original payment id (the payment that originally
3163                   * contained the documents payable stored in the dummy
3164                   * overflow payment).
3165                   *
3166                   * See KLUDGE in performSpecialPaperHandling()
3167                   * method to see why this was done.
3168                   */
3169                  IF (x_dummyPaperPmtsTab(j).payment_status = 'VOID_BY_OVERFLOW')
3170                      THEN
3171 
3172                      IF (x_dummyPaperPmtsTab(j).external_bank_account_id
3173                          = x_paperPmtsTab(i).payment_id) THEN
3174 
3175                          l_last_used_check_num := l_last_used_check_num + 1;
3176                          x_dummyPaperPmtsTab(j).paper_document_number
3177                              := l_last_used_check_num;
3178 
3179                      END IF;
3180 
3181                  END IF;
3182 
3183              END LOOP; -- for all overflow pmts in x_dummyPaperPmtsTab
3184 
3185          END IF;
3186 
3187           /* Bug 7252846 -  priting of overflow and original payments must be such that, the overflow payments must be
3188 	  printed first, followed by original ones. In this case, the numbering should happen first for overflow payments
3189 	  followed by original ones */
3190 
3191 	  /* assign check number to paper payment */
3192          l_last_used_check_num := l_last_used_check_num + 1;
3193          x_paperPmtsTab(i).check_number := l_last_used_check_num;
3194 
3195 
3196      END LOOP; -- for all pmts in x_paperPmtsTab
3197 
3198      /*
3199       * Final check:
3200       *
3201       * If all paper payments (including real payments, setup payments
3202       * and overflow payments) have been assigned check numbers
3203       * correctly, then the number of check numbers used up should
3204       * match the total paper payments count.
3205       *
3206       * If the two don't match, it means that some check numbers were
3207       * unassigned, or multiply assigned. In either case, abort the
3208       * program. This check will reveal any bugs in this method.
3209       */
3210      IF (l_anticipated_last_check_num <> l_last_used_check_num) THEN
3211 
3212 
3213 	         print_debuginfo(l_module_name, 'Check numbers were not '
3214 	             || 'properly assigned. '
3215 	             || 'Anticipated last used check number: '
3216 	             || l_anticipated_last_check_num
3217 	             || '. Actual last used check number: '
3218 	             || l_last_used_check_num
3219 	             || '. Deferring print for payment instruction '
3220 	             || x_pmtInstrRec.payment_instruction_id,
3221 	             FND_LOG.LEVEL_UNEXPECTED
3222 	             );
3223 
3224 
3225          x_pmtInstrRec.payment_instruction_status := l_instr_status;
3226 
3227          l_error_code := 'IBY_INS_NUMBERING_ERR_1';
3228 
3229          FND_MESSAGE.set_name('IBY', l_error_code);
3230 
3231          FND_MESSAGE.SET_TOKEN('NUM_CALC',
3232              l_anticipated_last_check_num,
3233              FALSE);
3234 
3235          l_token_rec.token_name  := 'NUM_CALC';
3236          l_token_rec.token_value := l_anticipated_last_check_num;
3237          x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
3238 
3239          FND_MESSAGE.SET_TOKEN('NUM_ACTU',
3240              l_last_used_check_num,
3241              FALSE);
3242 
3243          l_token_rec.token_name  := 'NUM_ACTU';
3244          l_token_rec.token_value := l_last_used_check_num;
3245          x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
3246 
3247          /*
3248           * Once we fail a pmt instruction, we must add a
3249           * corresponding error message to the errors table.
3250           */
3251          IBY_PAYINSTR_UTILS_PKG.createErrorRecord(
3252              x_pmtInstrRec.payment_instruction_id,
3253              x_pmtInstrRec.payment_instruction_status,
3254              l_error_code,
3255              FND_MESSAGE.get,
3256              'N',
3257              l_instr_err_rec
3258              );
3259 
3260          IBY_VALIDATIONSETS_PUB.insertIntoErrorTable(
3261              l_instr_err_rec,
3262              x_instrErrorTab,
3263              x_insTokenTab
3264              );
3265 
3266          /* add error msg to message stack */
3267          FND_MSG_PUB.ADD;
3268 
3269          FND_MSG_PUB.COUNT_AND_GET(
3270              p_count => x_msg_count,
3271              p_data  => x_msg_data
3272              );
3273 
3274          /* set error message to return to caller */
3275          x_return_message := FND_MESSAGE.get;
3276 
3277          APP_EXCEPTION.RAISE_EXCEPTION;
3278 
3279      END IF;
3280 
3281      /*
3282       * Return success status.
3283       */
3284      x_return_message := 'SUCCESS';
3285      x_return_status  := 0;
3286 
3287      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3288 	     print_debuginfo(l_module_name, 'EXIT');
3289 
3290      END IF;
3291      EXCEPTION
3292          WHEN OTHERS THEN
3293 
3294          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3295 	         print_debuginfo(l_module_name, 'Exception occured when '
3296 	             || 'performing document numbering. '
3297 	             );
3298 	         print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
3299 	         print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
3300 
3301          END IF;
3302          /*
3303           * Rollback any DB changes made in this method.
3304           */
3305          ROLLBACK;
3306 
3307          /*
3308           * Return error status to caller.
3309           * The error message would have already been set.
3310           */
3311          x_return_status := -1;
3312 
3313          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3314 	         print_debuginfo(l_module_name, 'EXIT');
3315 
3316          END IF;
3317  END assignCheckNumbers;
3318 
3319 /*--------------------------------------------------------------------
3320  | NAME:
3321  |     getNumPrintedDocsByFormula
3322  |
3323  | PURPOSE:
3324  |
3325  |
3326  | PARAMETERS:
3327  |     IN
3328  |
3329  |     OUT
3330  |
3331  |
3332  | RETURNS:
3333  |
3334  | NOTES:
3335  |
3336  *---------------------------------------------------------------------*/
3337  FUNCTION getNumPrintedDocsByFormula(
3338      p_num_docs_payable      IN NUMBER,
3339      p_num_lines_per_stub    IN NUMBER
3340      )
3341      RETURN NUMBER
3342  IS
3343 
3344  l_num_printed_docs  NUMBER := -1;
3345  l_carryover         NUMBER := -1;
3346  l_extra_printed_doc NUMBER := -1;
3347 
3348  BEGIN
3349 
3350     /*
3351      * We will try to fit n docs payable into m stubs, where
3352      * p = number of lines per stub. The problem is to calculate
3353      * m, given n and p.
3354      *
3355      * Now, number of stubs (i.e., printed docs) will be at least n/p
3356      *
3357      * Therefore, m >= n/p
3358      *
3359      * If n/p division is not exact, it means that some docs payable
3360      * are left over.  Now, the number of docs payable left over (i.e.,
3361      * the reminder) is necessarily less than p, because reminder is
3362      * always less than the divisor.
3363      *
3364      * So, the reminder docs payable will definitely fit into one stub.
3365      *
3366      * Therefore, m = n/p + r
3367      *
3368      * where r = 0, if the reminder is zero i.e., n mod p = 0
3369      *  else r = 1, if the reminder is non-zero i.e., n mod p > 0
3370      */
3371 
3372     l_carryover := MOD(p_num_docs_payable, p_num_lines_per_stub);
3373 
3374     IF (l_carryover <> 0) THEN
3375         l_extra_printed_doc := 1;
3376     ELSE
3377         l_extra_printed_doc := 0;
3378     END IF;
3379 
3380     l_num_printed_docs := FLOOR(p_num_docs_payable / p_num_lines_per_stub)
3381                               + l_extra_printed_doc;
3382 
3383     return l_num_printed_docs;
3384 
3385  END getNumPrintedDocsByFormula;
3386 
3387 /*--------------------------------------------------------------------
3388  | NAME:
3389  |     performSpecialPaperDocHandling
3390  |
3391  | PURPOSE:
3392  |
3393  |
3394  |
3395  | PARAMETERS:
3396  |     IN
3397  |
3398  |
3399  |     OUT
3400  |
3401  |
3402  | RETURNS:
3403  |
3404  | NOTES:
3405  |
3406  *---------------------------------------------------------------------*/
3407  PROCEDURE performSpecialPaperDocHandling(
3408      x_paperSpecialTab   IN OUT NOCOPY paperPmtsSpecialDocsTabType,
3409      x_dummyPaperPmtsTab IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
3410      x_setupDocsTab      IN OUT NOCOPY docsTabType,
3411      x_overflowDocsTab   IN OUT NOCOPY overflowDocsTabType
3412      )
3413  IS
3414  l_doc_rec     iby_docs_payable_all%ROWTYPE;
3415  l_pmt_rec     IBY_PAYMENTS_ALL%ROWTYPE;
3416 
3417  l_payment_id  IBY_PAYMENTS_ALL.payment_id%TYPE;
3418 
3419  l_pmtsInPmtInstrRec IBY_PAYINSTR_PUB.pmtsInPmtInstrRecType;
3420 
3421 --Bug 6486816
3422 -- Previously formatting_payment_id was updated for each document of payment but
3423 --after which x_overflowDocsTab was updates for next payment, losing the
3424 --previous values. So, storing all the overflow docs in a new table which will
3425 --be passed to  calling function
3426 
3427 x_overflowDocsTab_out overflowDocsTabType;
3428 l_begin_doc_index_outrec NUMBER := 1;
3429 
3430  l_module_name VARCHAR2(200) := G_PKG_NAME
3431                                     || '.performSpecialPaperDocHandling';
3432  l_begin_doc_index NUMBER := 0;
3433  l_end_doc_index   NUMBER := 0;
3434 
3435  /* payments cursor */
3436  CURSOR c_document_data(p_payment_id IBY_DOCS_PAYABLE_ALL.payment_id%TYPE)
3437  IS
3438  SELECT
3439      document_payable_id,
3440      payment_id,
3441      payment_currency_code,
3442      payment_function,
3443      formatting_payment_id,
3444      org_id,
3445      org_type
3446  FROM
3447      IBY_DOCS_PAYABLE_ALL
3448  WHERE
3449      payment_id = p_payment_id
3450  ORDER BY
3451      document_payable_id ASC
3452  ;
3453 
3454  BEGIN
3455 
3456      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3457 	     print_debuginfo(l_module_name, 'ENTER');
3458 
3459      END IF;
3460      /*
3461       * STEP 1:
3462       * Handle setup documents.
3463       *
3464       * Setup documents are dummy checks that are printed at the
3465       * beginning of a check print run. They are basically void checks
3466       * used to align the printer.
3467       *
3468       * Since each setup document is to be printed as a separate check
3469       * do the following:
3470       * a. Insert a dummy payment for each setup document that is to be
3471       *    printed.
3472       * b. For each inserted dummy payment, insert as many dummy documents
3473       *    payable as will fit onto the check stub of the setup document.
3474       * c. Add this dummy payment to the corresponding payment instruction.
3475       *
3476       * Note that setup checks are to be printed once per payment
3477       * instruction (not once per payment).
3478       */
3479      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3480 	     print_debuginfo(l_module_name, 'Performing setup document handling ..');
3481 
3482      END IF;
3483      FOR i IN x_paperSpecialTab.FIRST .. x_paperSpecialTab.LAST LOOP
3484 
3485          /*
3486           * Setup documents have to be generated once per payment
3487           * instruction. Generate setup docs for an instruction
3488           * only if the 'setup docs flag' is set to 'N'.
3489           */
3490          IF (x_paperSpecialTab(i).setup_docs_for_instr_finished <> 'Y') THEN
3491 
3492              FOR j IN 1 .. x_paperSpecialTab(i).num_setup_docs LOOP
3493 
3494                  /*
3495                   * Insert a dummy payment into IBY_PAYMENTS_ALL
3496                   * table for each setup document.
3497                   */
3498 
3499                  /*
3500                   * This is a new payment; Get an id for this payment
3501                   */
3502                  IBY_PAYGROUP_PUB.getNextPaymentID(l_payment_id);
3503 
3504                  l_pmt_rec.payment_id               := l_payment_id;
3505                  l_pmt_rec.payment_profile_id       :=  -1;
3506                  l_pmt_rec.payment_status           := 'VOID_BY_SETUP';
3507                  l_pmt_rec.payment_amount           := 0;
3508                  l_pmt_rec.internal_bank_account_id := -1;
3509                  l_pmt_rec.created_by               := fnd_global.user_id;
3510                  l_pmt_rec.creation_date            := sysdate;
3511                  l_pmt_rec.last_updated_by          := fnd_global.user_id;
3512                  l_pmt_rec.last_update_date         := sysdate;
3513                  l_pmt_rec.last_update_login        := fnd_global.login_id;
3514                  l_pmt_rec.object_version_number    := 1;
3515                  l_pmt_rec.ext_payee_id             := -1;
3516                  l_pmt_rec.payment_service_request_id := -1;
3517 
3518                  /*
3519                   * Fix for bug 5336487:
3520                   *
3521                   * For setup checks, set the payment currency
3522                   * to '-1'.
3523                   */
3524                  l_pmt_rec.payment_currency_code    := '-1';
3525 
3526                  l_pmt_rec.org_id                   := -1;
3527                  l_pmt_rec.org_type                 := 'OPERATING_UNIT';
3528                  l_pmt_rec.legal_entity_id          := -1;
3529 
3530                  /*
3531                   * Fix for bug 5336487:
3532                   *
3533                   * For setup checks, set the payment function
3534                   * to '-1'.
3535                   */
3536                  l_pmt_rec.payment_function         := '-1';
3537 
3538                  l_pmt_rec.process_type             := 'STANDARD';
3539                  l_pmt_rec.payments_complete_flag   := 'N';
3540                  l_pmt_rec.bill_payable_flag        := 'N';
3541                  l_pmt_rec.exclusive_payment_flag   := 'N';
3542                  l_pmt_rec.declare_payment_flag     := 'N';
3543                  l_pmt_rec.pregrouped_payment_flag  := 'N';
3544                  l_pmt_rec.stop_confirmed_flag      := 'N';
3545                  l_pmt_rec.stop_released_flag       := 'N';
3546                  l_pmt_rec.stop_request_placed_flag := 'N';
3547                  l_pmt_rec.separate_remit_advice_req_flag
3548                                                     := 'N';
3549                  l_pmt_rec.payment_method_code      := '-1';
3550 
3551                  /*
3552                   * Set the instruction id for this payment to the
3553                   * currently running payment instruction id
3554                   */
3555                  l_pmt_rec.payment_instruction_id   := x_paperSpecialTab(i).
3556                                                            instruction_id;
3557 
3558                  /* add payment to PLSQL table of payments */
3559                  /* this will be used to insert into IBY_PAMENTS table */
3560                  x_dummyPaperPmtsTab(x_dummyPaperPmtsTab.COUNT + 1)
3561                      := l_pmt_rec;
3562 
3563                  /*
3564                   * No need to add this payment to the payment instructions
3565                   * PLSQL table 'x_pmtsInPmtInstrTab'. This is because
3566                   * setup payments are dummy payments that are handled
3567                   * separately.
3568                   */
3569 
3570                  /*
3571                   * For each dummy payment, insert corresponding dummy
3572                   * documents. Insert as many dummy documents as will
3573                   * fit into the stub of the printed document.
3574                   */
3575 
3576                  /*
3577                   * Fix for bug 5642449:
3578                   *
3579                   * Only create dummy documents to stamp on the setup
3580                   * check if we know the number of lines per stub.
3581                   * Otherwise, simply create the setup checks without
3582                   * populating the check stub with document ids (because
3583                   * we do not know how many document ids will fit on the
3584                   * check stub).
3585                   */
3586                  IF (x_paperSpecialTab(i).num_lines_per_stub IS NOT NULL AND
3587                      x_paperSpecialTab(i).num_lines_per_stub > 0) THEN
3588 
3589                      FOR k IN 1 .. x_paperSpecialTab(i).num_lines_per_stub LOOP
3590 
3591                          /*
3592                           * This is a new document; Get an id for this document
3593                           */
3594                          l_doc_rec.document_payable_id :=
3595                              IBY_DISBURSE_SUBMIT_PUB_PKG.
3596                                  getNextDocumentPayableID();
3597 
3598                          /*
3599                           * By default, set the formatting payment id to
3600                           * payment id for each document
3601                           */
3602                          l_doc_rec.formatting_payment_id :=
3603                              l_payment_id;
3604                          l_doc_rec.calling_app_id        := -1;
3605                          l_doc_rec.document_type         := 'INVOICE';
3606                          l_doc_rec.document_status       := 'VOID_BY_SETUP';
3607                          l_doc_rec.payment_id            := l_payment_id;
3608                          l_doc_rec.payment_amount        := -1;
3609                          l_doc_rec.payment_method_code   := -1;
3610                          l_doc_rec.exclusive_payment_flag:= 'N';
3611                          l_doc_rec.payee_party_id        := -1;
3612                          l_doc_rec.legal_entity_id       := -1;
3613                          l_doc_rec.created_by            := fnd_global.user_id;
3614                          l_doc_rec.creation_date         := sysdate;
3615                          l_doc_rec.last_updated_by       := fnd_global.user_id;
3616                          l_doc_rec.last_update_date      := sysdate;
3617                          l_doc_rec.last_update_login     := fnd_global.login_id;
3618                          l_doc_rec.object_version_number := 1;
3619 
3620                          /*
3621                           * Fix for bug 5336487:
3622                           *
3623                           * For setup documents, set the payment currency
3624                           * to '-1'.
3625                           */
3626                          l_doc_rec.document_currency_code:= '-1';
3627                          l_doc_rec.payment_currency_code := '-1';
3628 
3629                          l_doc_rec.payment_service_request_id
3630                                                          := -1;
3631                          l_doc_rec.org_id                := -1;
3632                          l_doc_rec.org_type              := 'OPERATING_UNIT';
3633                          l_doc_rec.calling_app_doc_unique_ref1 := '-1';
3634                          l_doc_rec.calling_app_doc_unique_ref2 := '-1';
3635                          l_doc_rec.calling_app_doc_unique_ref3 := '-1';
3636                          l_doc_rec.calling_app_doc_unique_ref4 := '-1';
3637                          l_doc_rec.calling_app_doc_unique_ref5 := '-1';
3638                          l_doc_rec.pay_proc_trxn_type_code
3639                                                          := '-1';
3640 
3641                          /*
3642                           * Fix for bug 5336487:
3643                           *
3644                           * For setup documents, set the payment function
3645                           * to '-1'.
3646                           */
3647                          l_doc_rec.payment_function      := '-1';
3648 
3649                          l_doc_rec.calling_app_doc_ref_number := -1;
3650                          l_doc_rec.payment_date          := sysdate;
3651                          l_doc_rec.document_date         := sysdate;
3652                          l_doc_rec.document_amount       := 0;
3653                          l_doc_rec.straight_through_flag := 'Y';
3654                          l_doc_rec.allow_removing_document_flag := 'N';
3655                          l_doc_rec.ext_payee_id          := -1;
3656 
3657                          /* add document to PLSQL table of documents */
3658                          x_setupDocsTab(x_setupDocsTab.COUNT + 1)  := l_doc_rec;
3659 
3660                      END LOOP; -- for num_lines_per_stub
3661 
3662                  ELSE
3663 
3664                      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3665 	                     print_debuginfo(l_module_name, 'Setup checks will not '
3666 	                         || 'contain invoice numbers because number of lines '
3667 	                         || 'per stub is unknown.'
3668 	                         );
3669 
3670                      END IF;
3671                  END IF; -- if num lines per stub is not null
3672 
3673              END LOOP; -- for num_setup_docs in payment
3674 
3675              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3676 	             print_debuginfo(l_module_name, 'Added '
3677 	                 || x_paperSpecialTab(i).num_setup_docs
3678 	                 || ' setup payments with '
3679 	                 ||  x_paperSpecialTab(i).num_lines_per_stub
3680 	                 || ' dummy documents payable each, to payment instruction '
3681 	                 || x_paperSpecialTab(i).instruction_id
3682 	                 );
3683 
3684              END IF;
3685              /*
3686               * Once we have finished generating setup documents for an
3687               * instruction, set the 'setup docs flag' to 'Y' for all
3688               * records with the same instruction id in the paperSpecialTab
3689               * PLSQL table. This is to prevent the code fro generating
3690               * setup docs more than once for a payment instruction.
3691               */
3692              updateSetupDocsFlagForInstr(x_paperSpecialTab(i).instruction_id,
3693                  x_paperSpecialTab);
3694 
3695          END IF; -- if setup_docs_for_instr_finished <> 'Y'
3696 
3697      END LOOP; -- for each pmt in instruction with process type 'PAPER'
3698 
3699      /*
3700       * STEP 2:
3701       * Handle overflow documents.
3702       *
3703       * The number of lines that can be printed onto a check stub
3704       * is limited by the physical dimenensions of the paper stock.
3705       * The number of lines per stub is available as an attribute of
3706       * the paper stock.
3707       *
3708       * In each line on the stub, we will print the id of the
3709       * documents payable that are paid by that check.
3710       * So one check, can accomodate 'n' documents payable where
3711       * 'n' is the number of lines per stub for the paper stock
3712       * of the check.
3713       *
3714       * If a payment has more documents payable lined to it than
3715       * will fit onto the check stub, do the following:
3716       *
3717       * a. Calculate the number of overflow checks that need to
3718       *    be printed to accomodate the excess documents payable.
3719       *    (this is already accomplished by the document numbering
3720       *     flow).
3721       * b. For each overflow check, insert a dummy payment.
3722       * c. Add this dummy payment to the correspoding payment instruction.
3723       */
3724      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3725 	     print_debuginfo(l_module_name, 'Performing overflow document '
3726 	         || 'handling ..');
3727 
3728      END IF;
3729      FOR i IN x_paperSpecialTab.FIRST .. x_paperSpecialTab.LAST LOOP
3730 
3731          /*
3732           * Pull up all the documents associated with this payment id.
3733           * The format_payment_id of these documents will be changed
3734           * to handle overflows.
3735           *
3736           * Only do this if a payment has non-zero overflow documents.
3737           */
3738          IF (x_paperSpecialTab(i).num_overflow_docs IS NOT NULL AND
3739              x_paperSpecialTab(i).num_overflow_docs > 0) THEN
3740 
3741              OPEN  c_document_data(x_paperSpecialTab(i).payment_id);
3742              FETCH c_document_data BULK COLLECT INTO x_overflowDocsTab;
3743              CLOSE c_document_data;
3744 
3745              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3746 	             print_debuginfo(l_module_name, 'Payment '
3747 	                 || x_paperSpecialTab(i).payment_id
3748 	                 || ' has overflow documents payable. '
3749 	                 || x_paperSpecialTab(i).num_overflow_docs
3750 	                 || ' overflow paper payments will be '
3751 	                 || ' created for this payment.'
3752 	                 );
3753 
3754              END IF;
3755          END IF;
3756 
3757          /* initialize indices on overflow docs array before entering loop */
3758          l_begin_doc_index := 1;
3759          l_end_doc_index   := 0;
3760 
3761          /*
3762           * If there are no overflow docs for a payment, that payment
3763           * will not enter this loop.
3764           */
3765 
3766          /*
3767           * Fix for bug 5252629:
3768           *
3769           * If number of overflow docs is null for a payment, it means
3770           * that the user did not specify the number of lines per
3771           * stub for the check stock that the payment is meant to
3772           * be printed on.
3773           *
3774           * In this case we cannot do overflow handling. Handle this
3775           * situation gracefully by skipping overflow handling.
3776           */
3777          IF ( x_paperSpecialTab(i).num_overflow_docs IS NOT NULL) THEN
3778 
3779              /* informative debug message */
3780              IF (x_paperSpecialTab(i).num_overflow_docs = 0) THEN
3781 
3782                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3783 	                 print_debuginfo(l_module_name, 'Overflow handling not '
3784 	                     || 'required for payment instruction '
3785 	                     || x_paperSpecialTab(i).instruction_id
3786 	                     );
3787 
3788                  END IF;
3789              END IF;
3790 
3791              FOR j IN 1 .. x_paperSpecialTab(i).num_overflow_docs LOOP
3792 
3793                  /*
3794                   * Insert a dummy payment into IBY_PAYMENTS_ALL
3795                   * table for each set of overflow documents.
3796                   */
3797 
3798                  /*
3799                   * This is a new payment; Get an id for this payment
3800                   */
3801                  IBY_PAYGROUP_PUB.getNextPaymentID(l_payment_id);
3802 
3803                  l_pmt_rec.payment_id               := l_payment_id;
3804                  l_pmt_rec.payment_profile_id       :=  -1;
3805                  l_pmt_rec.payment_status           := 'VOID_BY_OVERFLOW';
3806                  l_pmt_rec.payment_amount           := 0;
3807                  l_pmt_rec.internal_bank_account_id := -1;
3808                  l_pmt_rec.created_by               := fnd_global.user_id;
3809                  l_pmt_rec.creation_date            := sysdate;
3810                  l_pmt_rec.last_updated_by          := fnd_global.user_id;
3811                  l_pmt_rec.last_update_date         := sysdate;
3812                  l_pmt_rec.last_update_login        := fnd_global.login_id;
3813                  l_pmt_rec.object_version_number    := 1;
3814                  l_pmt_rec.ext_payee_id             := -1;
3815                  l_pmt_rec.payment_service_request_id
3816                                                 := -1;
3817 
3818                  /*
3819                   * Fix for bug 5336487:
3820                   *
3821                   * For overflow documents, set the currency
3822                   * of the documents to the currency of the
3823                   * parent payment (instead of hardcoding to
3824                   * a dummy value).
3825                   *
3826                   * Since grouping by payment curency is a
3827                   * hardcoded grouping rule, we can use the
3828                   * payment currency from any real document
3829                   * of this payment.
3830                   */
3831                  l_pmt_rec.payment_currency_code    := x_overflowDocsTab(1).
3832                                                            pmt_currency;
3833 
3834                  /*
3835                   * Fix for bug 5332172:
3836                   *
3837                   * Do not hardcode the org id to -1 because the UI
3838                   * restricts the viewing of these payments by org.
3839                   *
3840                   * Instead, use the org id of one of the overflow
3841                   * documents payable that will be printed on this
3842                   * overflow payment.
3843                   *
3844                   * We can use any of the documents that will be
3845                   * part of this payment because all documents
3846                   * payable that are part of a payment are guaranteed
3847                   * to have the same (org id, org type); this is
3848                   * a hardcoded grouping rule.
3849                   */
3850                  l_pmt_rec.org_id                   := x_overflowDocsTab(1).
3851                                                            org_id;
3852                  l_pmt_rec.org_type                 := x_overflowDocsTab(1).
3853                                                            org_type;
3854 
3855                  l_pmt_rec.legal_entity_id          := -1;
3856 
3857                  /*
3858                   * Fix for bug 5336487:
3859                   *
3860                   * For overflow payments, set the payment function
3861                   * to the same as it's child documents.
3862                   *
3863                   * Since grouping by payment function is a hardcoded
3864                   * grouping rule, we can pick up the payment
3865                   * function from any of the documents and set it to
3866                   * the payment.
3867                   */
3868                  l_pmt_rec.payment_function         := x_overflowDocsTab(1).
3869                                                            pmt_function;
3870 
3871                  l_pmt_rec.process_type             := 'STANDARD';
3872                  l_pmt_rec.payments_complete_flag   := 'N';
3873                  l_pmt_rec.bill_payable_flag        := 'N';
3874                  l_pmt_rec.exclusive_payment_flag   := 'N';
3875                  l_pmt_rec.declare_payment_flag     := 'N';
3876                  l_pmt_rec.pregrouped_payment_flag  := 'N';
3877                  l_pmt_rec.stop_confirmed_flag      := 'N';
3878                  l_pmt_rec.stop_released_flag       := 'N';
3879                  l_pmt_rec.stop_request_placed_flag := 'N';
3880                  l_pmt_rec.separate_remit_advice_req_flag
3881                                                 := 'N';
3882                  l_pmt_rec.payment_method_code      := '-1';
3883 
3884                  /*
3885                   * KLUDGE:
3886                   *
3887                   * We are creating a dummy payment to store overflow
3888                   * documents. These payments are actually part of a real
3889                   * payment indicated by x_paperSpecialTab(i).payment_id.
3890                   *
3891                   * When it is time for check numbering, we want to number
3892                   * the real payment and the dummy payments contiguously.
3893                   * Therefore, we need to know what dummy payments are
3894                   * related to which real payment.
3895                   *
3896                   * The l_pmt_rec structure cannot store the real payment
3897                   * id because it is exactly mapped to a row in
3898                   * IBY_PAYMENTS_ALL.
3899                   *
3900                   * Instead of creating a new data structure to hold
3901                   * (real payment id, dummy payment id), we use an
3902                   * optional field in the l_pmt_rec record to store the
3903                   * real payment id.
3904                   *
3905                   * This is the 'payee party site id' field. Since this is
3906                   * a dummy payment any value we provide for this field
3907                   * does not really matter.
3908                   *
3909                   * This field will be accessed in assignCheckNumbers()
3910                   * method to find out all dummy payments related to a
3911                   * real payment.
3912                   */
3913 
3914                  /*
3915                   * UPDATE:
3916                   * Use external_bank_account_id as the placeholder
3917                   * for the related original payment id. We are trying to
3918                   * use some field on the payment, that is relatively
3919                   * useless, to store some extra information.
3920                   *
3921                   * The external bank account id is a good candidate
3922                   * for this because this field is expected to be
3923                   * not used for paper payments anyway. The payee
3924                   * party site id field will be overwritten with data
3925                   * from the original payment as part of fix for
3926                   * bug 6765314.
3927                   *
3928                   * Even though, we really don't need this link between
3929                   * the overflow payment and the original payment
3930                   * outside of this package, it would be a good idea to
3931                   * persist this information somehow so that we can
3932                   * quickly answer the question "What is the original
3933                   * payment that this overflow payment is related to?"
3934                   *
3935                   * Ideally we should have a specific column on the
3936                   * payment to store this information, so that we don't
3937                   * have these kludges.
3938                   */
3939                  l_pmt_rec.external_bank_account_id :=
3940                      x_paperSpecialTab(i).payment_id;
3941 
3942                  /*
3943                   * Set the instruction id for this payment to the
3944                   * currently running payment instruction id
3945                   */
3946                  l_pmt_rec.payment_instruction_id   := x_paperSpecialTab(i).
3947                                                        instruction_id;
3948 
3949                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
3950 	                 print_debuginfo(l_module_name, 'Creating dummy overflow '
3951 	                     || ' payment '
3952 	                     || l_payment_id
3953 	                     || ' for payment '
3954 	                     || x_paperSpecialTab(i).payment_id
3955 	                     );
3956 
3957                  END IF;
3958                  /* add payment to PLSQL table of payments */
3959                  x_dummyPaperPmtsTab(x_dummyPaperPmtsTab.COUNT + 1)
3960                      := l_pmt_rec;
3961 
3962                  /*
3963                   * No need to add this payment to the payment instructions
3964                   * PLSQL table 'x_pmtsInPmtInstrTab'. This is because
3965                   * overflow payments are dummy payments that are handled
3966                   * separately.
3967                   */
3968 
3969                  /*
3970                   * We have just created a dummy payment for overflow
3971                   * purposes.
3972                   *
3973                   * Some documents will need to be updated so that their
3974                   * formatting_payment_id is set to the id of the dummy
3975                   * payment that we just created.
3976                   *
3977                   * Originally, all documents will have the same value
3978                   * for payment_id and formatting_payment_id. When there
3979                   * are overflow documents, then the following will happen:
3980                   *
3981                   * a. Documents that will fit into one stub will
3982                   *    contain payment_id same as original document
3983                   *    id.
3984                   *
3985                   * b. All documents that will not fit into the stub (a)
3986                   *    will have to printed on void checks. These will
3987                   *    be identified because for these documents the
3988                   *    formatting_payment_id <> the payment id.
3989                   *
3990                   * So at this point, we have to identify documents
3991                   * for this payment that will not fit into the first
3992                   * stub and change their formatting_payment_id to the one
3993                   * that we generated for the dummy payment. We do this in
3994                   * a loop to finish all excess documents.
3995                   *
3996                   * Example,
3997                   * Payment 102 contains 10 documents.
3998                   * Check stub contains space for 4 document lines.
3999                   *
4000                   * Therefore, number of printed checks will be
4001                   * (4 docs)     +  (4 docs)     + (2 docs)      =  3 checks
4002                   * [Void check]    [Void check]   [Real check]
4003                   *
4004                   * One check will be the real check, 2 checks are overflow.
4005                   * We have already calculated the number of overflow
4006                   * checks by the time we come here.
4007                   *
4008                   * We need to link the documents that will fit into the
4009                   * overflow checks to the dummy payments (void checks)
4010                   * that we just created.
4011                   */
4012 
4013                  /*
4014                   * Change the format_payment_id of 'n' documents of this
4015                   * payment to the dummy payment id, where 'n' = num lines
4016                   * that will fit on the stub.  These 'n' documents
4017                   * will be printed on a voided check.
4018                   */
4019 
4020                  /*
4021                   * Make sure that the end index does not exceed the
4022                   * size of the docs array.
4023                   */
4024 
4025                  /* need to subtract 1 because 'begin index' is 1 based */
4026                  IF (l_begin_doc_index +
4027                      (x_paperSpecialTab(i).num_lines_per_stub - 1)
4028                          > x_overflowDocsTab.COUNT) THEN
4029 
4030                      l_end_doc_index := x_overflowDocsTab.COUNT;
4031 
4032                  ELSE
4033 
4034                      l_end_doc_index := l_begin_doc_index +
4035                                             (x_paperSpecialTab(i).
4036                                                 num_lines_per_stub - 1);
4037 
4038                  END IF;
4039 
4040                  FOR k IN l_begin_doc_index .. l_end_doc_index LOOP
4041 
4042                      x_overflowDocsTab(k).format_payment_id := l_payment_id;
4043 -- Bug 6486816- copying the overfloW record into the out parameter
4044                      x_overflowDocsTab_out(l_begin_doc_index_outrec) :=x_overflowDocsTab(k);
4045                      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4046 	                     print_debuginfo(l_module_name, 'For document '
4047 	                         || x_overflowDocsTab(k).doc_id
4048 	                         || ' with pmt id '
4049 	                         || x_overflowDocsTab(k).payment_id
4050 	                         || ' format pmt id set to '
4051 	                         || x_overflowDocsTab(k).format_payment_id
4052 	                         );
4053 
4054                      END IF;
4055                      l_begin_doc_index := l_begin_doc_index + 1;
4056                      l_begin_doc_index_outrec := l_begin_doc_index_outrec + 1;
4057                  END LOOP;
4058 
4059              END LOOP; -- for num_overflow_docs in payment
4060 
4061          ELSE
4062 
4063              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4064 	             print_debuginfo(l_module_name, 'Not creating any '
4065 	                 || 'overflow payments for payment instruction '
4066 	                 || x_paperSpecialTab(i).instruction_id
4067 	                 || ' because num lines per stub is not specified '
4068 	                 || 'for the associated payment document.'
4069 	                 );
4070 
4071              END IF;
4072          END IF; -- if num overflow docs is not null
4073 
4074          IF (x_paperSpecialTab(i).num_overflow_docs IS NOT NULL AND
4075              x_paperSpecialTab(i).num_overflow_docs > 0) THEN
4076 
4077              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4078 	             print_debuginfo(l_module_name, 'Added '
4079 	                 || x_paperSpecialTab(i).num_overflow_docs
4080 	                 || ' overflow payments to payment instruction '
4081 	                 || x_paperSpecialTab(i).instruction_id
4082 	                 );
4083 
4084              END IF;
4085          END IF;
4086 
4087      END LOOP; -- for each pmt in instruction with process type 'PAPER'
4088 -- Bug 6486816- copy the overflow documents table with all details to
4089 --the variable that is passed to calling function.
4090             x_overflowDocsTab := x_overflowDocsTab_out;
4091      IF (x_overflowDocsTab.COUNT > 0) THEN
4092 
4093          FOR i IN x_overflowDocsTab.FIRST .. x_overflowDocsTab.LAST LOOP
4094 
4095              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4096 	             print_debuginfo(l_module_name, 'Doc id '
4097 	                 || x_overflowDocsTab(i).doc_id
4098 	                 || ', payment id: '
4099 	                 || x_overflowDocsTab(i).payment_id
4100 	                 || ', format payment id: '
4101 	                 || x_overflowDocsTab(i).format_payment_id
4102 	                 );
4103 
4104              END IF;
4105          END LOOP;
4106 
4107      END IF;
4108 
4109      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4110 	     print_debuginfo(l_module_name, 'EXIT');
4111 
4112      END IF;
4113  END performSpecialPaperDocHandling;
4114 
4115 /*--------------------------------------------------------------------
4116  | NAME:
4117  |     updateSetupDocsFlagForInstr
4118  |
4119  | PURPOSE:
4120  |
4121  |
4122  |
4123  | PARAMETERS:
4124  |     IN
4125  |
4126  |
4127  |     OUT
4128  |
4129  |
4130  | RETURNS:
4131  |
4132  | NOTES:
4133  |
4134  *---------------------------------------------------------------------*/
4135  PROCEDURE updateSetupDocsFlagForInstr(
4136      p_instrId         IN IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_id%TYPE,
4137      x_paperSpecialTab IN OUT NOCOPY paperPmtsSpecialDocsTabType
4138      )
4139  IS
4140  BEGIN
4141 
4142      /*
4143       * Loop through all the paper payments table. If we find any
4144       * payment instruction that matches the given payment
4145       * instruction, set the 'set up docs' flag for the payment
4146       * instruction to 'Y' to indicate that setup documents
4147       * have already been generated for this payment instruction.
4148       */
4149      FOR i IN x_paperSpecialTab.FIRST .. x_paperSpecialTab.LAST LOOP
4150 
4151          IF (x_paperSpecialTab(i).instruction_id = p_instrId) THEN
4152              x_paperSpecialTab(i).setup_docs_for_instr_finished := 'Y';
4153          END IF;
4154 
4155      END LOOP;
4156 
4157  END updateSetupDocsFlagForInstr;
4158 
4159 /*--------------------------------------------------------------------
4160  | NAME:
4161  |     updatePmtsWithCheckNumbers
4162  |
4163  | PURPOSE:
4164  |
4165  |
4166  |
4167  | PARAMETERS:
4168  |     IN
4169  |
4170  |     OUT
4171  |
4172  |
4173  | RETURNS:
4174  |
4175  | NOTES:
4176  |
4177  *---------------------------------------------------------------------*/
4178  PROCEDURE updatePmtsWithCheckNumbers(
4179      p_pmtsInPayInstTab  IN IBY_PAYINSTR_PUB.pmtsInpmtInstrTabType
4180      )
4181  IS
4182  l_module_name VARCHAR2(200) := G_PKG_NAME || '.updatePmtsWithCheckNumbers';
4183 
4184  BEGIN
4185 
4186      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4187 	     print_debuginfo(l_module_name, 'ENTER');
4188 
4189      END IF;
4190      /* Normally, this should not happen */
4191      IF (p_pmtsInPayInstTab.COUNT = 0) THEN
4192          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4193 	         print_debuginfo(l_module_name, 'No payments '
4194 	             || 'were provided to update '
4195 	             || 'IBY_PAYMENTS_ALL table. Possible data '
4196 	             || 'corruption issue.');
4197          END IF;
4198          RETURN;
4199      END IF;
4200 
4201      /*
4202       * Update the payments. We cannot use bulk update here
4203       * because the bulk update syntax does not allow us to
4204       * reference individual fields of the PL/SQL record.
4205       *
4206       * TBD: Is there any way to optimize this update?
4207       */
4208      FOR i in p_pmtsInPayInstTab.FIRST..p_pmtsInPayInstTab.LAST LOOP
4209 
4210          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4211 	         print_debuginfo(l_module_name, 'Instruction: '
4212 	             || p_pmtsInPayInstTab(i).pay_instr_id || ', payment: '
4213 	             || p_pmtsInPayInstTab(i).payment_id);
4214 
4215          END IF;
4216          UPDATE
4217              IBY_PAYMENTS_ALL
4218          SET
4219              paper_document_number = p_pmtsInPayInstTab(i).check_number
4220          WHERE
4221              payment_id = p_pmtsInPayInstTab(i).payment_id
4222          AND payment_status = p_pmtsInPayInstTab(i).payment_status;
4223 
4224      END LOOP;
4225 
4226      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4227 	     print_debuginfo(l_module_name, 'EXIT');
4228 
4229      END IF;
4230  END updatePmtsWithCheckNumbers;
4231 
4232 /*--------------------------------------------------------------------
4233  | NAME:
4234  |    isPaperDocNumUsed
4235  |
4236  | PURPOSE:
4237  |
4238  |
4239  |
4240  | PARAMETERS:
4241  |     IN
4242  |
4243  |     OUT
4244  |
4245  |
4246  | RETURNS:
4247  |
4248  | NOTES:
4249  |
4250  *---------------------------------------------------------------------*/
4251  PROCEDURE isPaperDocNumUsed(
4252      p_payment_doc_id IN IBY_USED_PAYMENT_DOCS.payment_document_id%TYPE,
4253      x_paper_doc_num  IN IBY_USED_PAYMENT_DOCS.used_document_number%TYPE,
4254      x_return_status  IN OUT NOCOPY VARCHAR2
4255      )
4256  IS
4257 
4258  l_module_name VARCHAR2(200) := G_PKG_NAME || '.isPaperDocNumUsed';
4259  l_used_paper_doc_number NUMBER := 0;
4260 
4261  BEGIN
4262 
4263      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4264 	     print_debuginfo(l_module_name, 'ENTER');
4265 
4266      END IF;
4267      /*
4268       * Check if this paper document number has already
4269       * been used.
4270       */
4271      BEGIN
4272 
4273          SELECT
4274              used_document_number
4275          INTO
4276              l_used_paper_doc_number
4277          FROM
4278              IBY_USED_PAYMENT_DOCS
4279          WHERE
4280              payment_document_id  = p_payment_doc_id AND
4281              used_document_number = x_paper_doc_num
4282          ;
4283 
4284      EXCEPTION
4285 
4286          WHEN NO_DATA_FOUND THEN
4287 
4288              /* now rows means success */
4289              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4290 	             print_debuginfo(l_module_name, 'Paper document '
4291 	                 || 'number '
4292 	                 || x_paper_doc_num
4293 	                 || ' is unused.'
4294 	                 );
4295 
4296              END IF;
4297          WHEN OTHERS THEN
4298 
4299              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4300 	             print_debuginfo(l_module_name, 'Exception occured when '
4301 	                 || 'attempting to get details of paper document '
4302 	                 || x_paper_doc_num
4303 	                 || ' from IBY_USED_PAYMENT_DOCS table.'
4304 	                 );
4305 
4306 	             print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
4307 	             print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
4308 
4309              END IF;
4310              x_return_status := FND_API.G_RET_STS_ERROR;
4311 
4312              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4313 	             print_debuginfo(l_module_name, 'Returning error response ..');
4314 
4315 	             print_debuginfo(l_module_name, 'EXIT');
4316 
4317              END IF;
4318              RETURN;
4319 
4320      END;
4321 
4322 
4323      x_return_status := FND_API.G_RET_STS_SUCCESS;
4324 
4325      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4326 	     print_debuginfo(l_module_name, 'Returning success response ..');
4327 	     print_debuginfo(l_module_name, 'EXIT');
4328 
4329      END IF;
4330  END isPaperDocNumUsed;
4331 
4332 /*--------------------------------------------------------------------
4333  | NAME:
4334  |    isSinglePayment
4335  |
4336  | PURPOSE:
4337  |    Determines whether the provided list of payments consists of a
4338  |    single payment.
4339  |
4340  |    If the following conditions are satisfied
4341  |
4342  |       a. Only one payment is present in the provided list of payments
4343  |       b. The payment service request of the provided payment
4344  |          has process type 'IMMEDIATE'
4345  |
4346  |    then the payment is considered to be a single payment.
4347  |
4348  | PARAMETERS:
4349  |     IN
4350  |         p_paperPmtsTab - PLSQL table of paper payments. Ensure that
4351  |                          this table only consists of real paper payments
4352  |                          (no dummy payments - setup or overflow payments
4353  |                          - should be included in this list).
4354  |     OUT
4355  |         NONE
4356  |
4357  | RETURNS:
4358  |         BOOLEAN        - TRUE, if the provided payments list consists of
4359  |                                a single payment
4360  |                          FALSE, otherwise
4361  |
4362  | NOTES:
4363  |
4364  *---------------------------------------------------------------------*/
4365  FUNCTION isSinglePayment(
4366      p_paperPmtsTab      IN paperPmtsSpecialDocsTabType
4367      ) RETURN BOOLEAN
4368  IS
4369 
4370  l_module_name       VARCHAR2(200) := G_PKG_NAME || '.isSinglePayment';
4371 
4372  l_retflag      BOOLEAN;
4373  l_process_type IBY_PAY_SERVICE_REQUESTS.process_type%TYPE;
4374  l_pmt_rec      paperPmtsSpecialDocsRecType;
4375 
4376  BEGIN
4377 
4378      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4379 	     print_debuginfo(l_module_name, 'ENTER');
4380 
4381      END IF;
4382      IF (p_paperPmtsTab.COUNT = 0) THEN
4383 
4384          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4385 	         print_debuginfo(l_module_name, 'Paper payments list is empty. '
4386 	             || 'Returning false ..'
4387 	             );
4388 
4389          END IF;
4390          l_retflag := FALSE;
4391          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4392 	         print_debuginfo(l_module_name, 'EXIT');
4393 
4394          END IF;
4395          RETURN l_retflag;
4396 
4397      END IF;
4398 
4399      IF (p_paperPmtsTab.COUNT <> 1) THEN
4400 
4401          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4402 	         print_debuginfo(l_module_name, 'Paper payments count is more '
4403 	             || 'than 1. Returning false ..'
4404 	             );
4405 
4406          END IF;
4407          l_retflag := FALSE;
4408          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4409 	         print_debuginfo(l_module_name, 'EXIT');
4410 
4411          END IF;
4412          RETURN l_retflag;
4413 
4414      END IF;
4415 
4416      /*
4417       * If we reached here, it means that there is only one
4418       * paper payment in the provided payment array.
4419       *
4420       * Look up the process type of the payment service request
4421       * to confirm that the process type is IMMEDIATE.
4422       *
4423       * These two conditions are necessary and sufficient to
4424       * determine whether a payment is a single payment.
4425       */
4426      BEGIN
4427 
4428          l_pmt_rec := p_paperPmtsTab(p_paperPmtsTab.FIRST);
4429 
4430          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4431 	         print_debuginfo(l_module_name, 'Provided payment id is '
4432 	             || l_pmt_rec.payment_id
4433 	             );
4434 
4435          END IF;
4436          SELECT
4437              req.process_type
4438          INTO
4439              l_process_type
4440          FROM
4441              IBY_PAY_SERVICE_REQUESTS req,
4442              IBY_PAYMENTS_ALL pmt
4443          WHERE
4444              req.payment_service_request_id =
4445                  pmt.payment_service_request_id         AND
4446              pmt.payment_id = l_pmt_rec.payment_id
4447          ;
4448 
4449          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4450 	         print_debuginfo(l_module_name, 'Processing type of parent '
4451 	             || 'request is '
4452 	             || l_process_type
4453 	             );
4454 
4455          END IF;
4456          /*
4457           * Set the return flag based on the processing type.
4458           */
4459          IF (l_process_type = 'IMMEDIATE') THEN
4460 
4461              l_retflag := TRUE;
4462 
4463              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4464 	             print_debuginfo(l_module_name, 'Setting return flag '
4465 	                || 'to true.'
4466 	                );
4467 
4468              END IF;
4469          ELSE
4470 
4471              l_retflag := FALSE;
4472 
4473              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4474 	             print_debuginfo(l_module_name, 'Setting return flag '
4475 	                || 'to false because processing type is not IMMEDIATE.'
4476 	                );
4477 
4478              END IF;
4479          END IF;
4480 
4481      EXCEPTION
4482          WHEN OTHERS THEN
4483 
4484 
4485 	             print_debuginfo(l_module_name, 'Fatal: Exception when attempting '
4486 	                 || 'to get processing type for payment '
4487 	                 || l_pmt_rec.payment_id,
4488 	                 FND_LOG.LEVEL_UNEXPECTED
4489 	                 );
4490 
4491 	             print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE,
4492 	                 FND_LOG.LEVEL_UNEXPECTED);
4493 	             print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM,
4494 	                 FND_LOG.LEVEL_UNEXPECTED);
4495 
4496 
4497              /*
4498               * Propogate exception to caller.
4499               */
4500              RAISE;
4501 
4502      END;
4503 
4504      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4505 	     print_debuginfo(l_module_name, 'EXIT');
4506      END IF;
4507      RETURN l_retflag;
4508 
4509  END isSinglePayment;
4510 
4511 /*--------------------------------------------------------------------
4512  | NAME:
4513  |    isContigPaperNumAvlbl
4514  |
4515  |
4516  | PURPOSE:
4517  |    Checks whether the paper document numbers from the given start
4518  |    number to the given end number are available contiguoulsy for
4519  |    printing.
4520  |
4521  |    For the purpose of printing checks, we should always presume
4522  |    the the user is going to print checks on prenumbered check stock
4523  |    on a tractor feed. Therefore, the check numbering should always
4524  |    be contiguous.
4525  |
4526  | PARAMETERS:
4527  |     IN
4528  |
4529  |     OUT
4530  |
4531  |
4532  | RETURNS:
4533  |
4534  | NOTES:
4535  |
4536  *---------------------------------------------------------------------*/
4537  FUNCTION isContigPaperNumAvlbl(
4538      p_payment_doc_id IN CE_PAYMENT_DOCUMENTS.payment_document_id%TYPE,
4539      p_start_number   IN IBY_PAYMENTS_ALL.paper_document_number%TYPE,
4540      p_end_number     IN IBY_PAYMENTS_ALL.paper_document_number%TYPE
4541      ) RETURN BOOLEAN
4542  IS
4543 
4544  l_module_name    VARCHAR2(200) := G_PKG_NAME || '.isContigPaperNumAvlbl';
4545  l_retflag        BOOLEAN;
4546  l_paper_doc_num  IBY_PAYMENTS_ALL.paper_document_number%TYPE;
4547 
4548  l_api_version    CONSTANT NUMBER       := 1.0;
4549  l_return_status  VARCHAR2 (100);
4550 
4551  l_msg_count      NUMBER;
4552  l_msg_data       VARCHAR2(3000);
4553  l_test           VARCHAR2(200) :='TRUE';
4554 
4555  l_last_issued_doc_num NUMBER;
4556  l_last_avail_doc_num NUMBER;
4557 
4558  BEGIN
4559 
4560      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4561 	     print_debuginfo(l_module_name, 'ENTER');
4562 
4563 	     print_debuginfo(l_module_name, 'Start #: '
4564 	         || p_start_number
4565 	         || ', end #: '
4566 	         || p_end_number
4567 	         || ', payment document: '
4568 	         || p_payment_doc_id
4569 	         );
4570 
4571      END IF;
4572      IF (p_start_number   IS NULL OR
4573          p_end_number     IS NULL OR
4574          p_payment_doc_id IS NULL
4575          ) THEN
4576 
4577          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4578 	         print_debuginfo(l_module_name, 'Provided params are invalid. '
4579 	             || 'Returning false.');
4580 
4581          END IF;
4582          l_retflag := FALSE;
4583 
4584          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4585 	         print_debuginfo(l_module_name, 'EXIT');
4586          END IF;
4587          RETURN l_retflag;
4588 
4589      END IF;
4590 
4591      /*
4592       * Validate the entire contiguous range of provided
4593       * paper document numbers. If even a single paper
4594       * document number fails validation, it means that
4595       * we do not have a contiguous rage of paper document
4596       * numbers available.
4597       */
4598      l_retflag := TRUE;
4599 
4600      /*
4601       * Performance Fix:
4602       *
4603       * This method has been re-written so that it does not loop
4604       * through every paper document number within the range validating
4605       * one-by-one.
4606       *
4607       * Now, it simply executes two SQL statements to verify whether
4608       * the given print range is valid.
4609       */
4610 
4611      BEGIN
4612 
4613          /*
4614           * First check against CE_PAYMENT_DOCUMENTS table whether
4615           * the start_number is greater than the last_issued_document_number
4616           * and the end_number is less than / equal to the last_available
4617           * _document_number.
4618           *
4619           * Two, special situations are possible here:
4620           * 1. last_issued_document_number = 0, this means that check has never
4621           *    been used so far. In this case, we should allow any start_number.
4622           *
4623           * 2. last_available_document_number is null, this means that there
4624           *    is no upper limit for the check numbers. In this case, we
4625           *    allow any end_number.
4626 	  *
4627 	  *
4628 	  *  Bug 8968846: Start number need not be validated on the last issued
4629 	  * document number. For the batch flow, start number is generated based
4630 	  * on the last issued document number.
4631 	  * In case of single payment flow, user can choose any unused document
4632 	  * number which is less than last issued document number.
4633 	  *
4634 	  *   So to process the flow smoothly in both cases, validation on the
4635 	  * start number is removed.
4636           */
4637 
4638 
4639              SELECT
4640                  pmt_doc.last_issued_document_number,
4641                  pmt_doc.last_available_document_number
4642              INTO
4643 	         l_last_issued_doc_num,
4644 		 l_last_avail_doc_num
4645              FROM
4646                  CE_PAYMENT_DOCUMENTS pmt_doc
4647              WHERE
4648                  pmt_doc.payment_document_id = p_payment_doc_id ;
4649 
4650 
4651      EXCEPTION
4652          WHEN OTHERS THEN
4653 
4654              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4655 	             print_debuginfo(l_module_name, 'Exception occured when checking for '
4656 	                 || 'provided check range against CE_PAYMENT_DOCUMENTS table.');
4657 	             print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
4658 	             print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
4659 
4660              END IF;
4661              l_retflag := FALSE;
4662 
4663      END;
4664 
4665      /*  Bug 8968846:
4666       *  Logic for validating the start number and end number
4667       *  is moved here
4668       */
4669      IF (nvl(l_last_avail_doc_num, p_end_number) < p_end_number) THEN
4670 
4671             IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4672 		     print_debuginfo(l_module_name, 'Last available '
4673 			 || 'paper document number is '
4674 			 || l_last_avail_doc_num
4675 			 );
4676 
4677 		     print_debuginfo(l_module_name, ' Last paper document number '
4678 			 || p_end_number
4679 			 || ' is above last available document number '
4680 			 || l_last_avail_doc_num
4681 			 );
4682 	     END IF;
4683 
4684              FND_MESSAGE.set_name('IBY', 'IBY_DOC_NUM_ABOVE_ALLOWED');
4685 
4686              FND_MESSAGE.SET_TOKEN('LAST_AVAILABLE_DOC_NUM',
4687                  l_last_avail_doc_num,
4688                  FALSE);
4689 
4690              FND_MSG_PUB.ADD;
4691 
4692              l_retflag := FALSE;
4693 	     l_test := 'FALSE';
4694      END IF;
4695 
4696 
4697 
4698      IF (l_test = 'TRUE') THEN
4699 
4700          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4701 	         print_debuginfo(l_module_name, 'Provided print range is valid in '
4702 	             || 'CE_PAYMENT_DOCUMENTS table. Verifying if any document within '
4703 	             || 'is already USED / SPOILED ..'
4704 	             );
4705 
4706          END IF;
4707          BEGIN
4708 
4709              /*
4710               * Next check if any USED / SPOILED documents already exist
4711               * for this payment document in the provided check
4712               * range.
4713               *
4714               * If such a USED / SPOILED document already exists, then
4715               * we cannot use this range of numbers for printing.
4716               */
4717              SELECT
4718                  'TRUE'
4719              INTO
4720                  l_test
4721              FROM
4722                  DUAL
4723              WHERE EXISTS
4724                  (
4725                  SELECT
4726                      used_document_number
4727                  FROM
4728                      IBY_USED_PAYMENT_DOCS
4729                  WHERE
4730                      payment_document_id = p_payment_doc_id     AND
4731                      document_use <> 'SKIPPED' AND
4732                      used_document_number >= p_start_number AND
4733                      used_document_number <= p_end_number
4734                  )
4735              ;
4736 
4737              IF (l_test = 'TRUE') THEN
4738 
4739                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4740 	                 print_debuginfo(l_module_name, 'Provided print range is not valid because '
4741 	                     || 'some documents with this range are already USED / SPOILED. '
4742 	                     || 'You cannot use this print range.'
4743 	                     );
4744 
4745                  END IF;
4746                  l_retflag := FALSE;
4747 
4748              ELSE
4749 
4750                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4751 	                 print_debuginfo(l_module_name, 'Provided print range is valid because '
4752 	                     || 'no documents with this range are already USED / SPOILED. '
4753 	                     || 'You can use this print range.'
4754 	                     );
4755 
4756                  END IF;
4757                  l_retflag := TRUE;
4758 
4759              END IF;
4760 
4761 
4762          EXCEPTION
4763              WHEN NO_DATA_FOUND THEN
4764                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4765 	                 print_debuginfo(l_module_name, 'No data was found occured when checking if any '
4766 	                     || 'USED / SPOILED documents exist in provided check range.');
4767 	                 print_debuginfo(l_module_name, 'This means no SPOILED / USED checks '
4768 	                     || 'exist for the given check range. Range is valid.');
4769                  END IF;
4770                  l_retflag := TRUE;
4771 
4772              WHEN OTHERS THEN
4773 
4774                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4775 	                 print_debuginfo(l_module_name, 'Exception occured when checking if any '
4776 	                     || 'USED / SPOILED documents exist in provided check range.');
4777 	                 print_debuginfo(l_module_name, 'SQLCODE: ' || SQLCODE);
4778 	                 print_debuginfo(l_module_name, 'SQLERRM: ' || SQLERRM);
4779 
4780                  END IF;
4781                  l_retflag := FALSE;
4782 
4783          END;
4784 
4785      ELSE
4786 
4787          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4788 	         print_debuginfo(l_module_name, 'Provided print range is not valid in '
4789 	             || 'CE_PAYMENT_DOCUMENTS table. You cannot use this print range.'
4790 	             );
4791 
4792          END IF;
4793          l_retflag := FALSE;
4794 
4795      END IF;
4796 
4797 
4798      IF (l_retflag = FALSE) THEN
4799 
4800          /*
4801           * Fix for bug 5327347:
4802           *
4803           * If we reach here, it means that one of the paper documents
4804           * in the supplied range has already been used.
4805           *
4806           * This means that we will need to display to the
4807           * user a message like 'sufficient contiguous payment
4808           * documents are not available to print this instruction.'
4809           *
4810           * However, the message 'paper doc number # has already been
4811           * used' has been set in the FND message stack already
4812           * by the IBY_DISBURSE_UI_API_PUB_PKG.validate_paper_doc_number(..)
4813           * method.
4814           *
4815           * Clear this message from the stack as it is redundant.
4816           */
4817          FND_MSG_PUB.initialize;
4818 
4819          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4820 	         print_debuginfo(l_module_name, 'Returning FALSE');
4821          END IF;
4822      ELSE
4823          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4824 	         print_debuginfo(l_module_name, 'Returning TRUE');
4825          END IF;
4826      END IF;
4827 
4828      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4829 	     print_debuginfo(l_module_name, 'EXIT');
4830      END IF;
4831      RETURN l_retflag;
4832 
4833  END isContigPaperNumAvlbl;
4834 
4835 /*--------------------------------------------------------------------
4836  | NAME:
4837  |    isPaperNosUsedOnExistPmt
4838  |
4839  | PURPOSE:
4840  |    Checks whether the paper document numbers from the given start
4841  |    number to the given end number are already used on any existing
4842  |    payments.
4843  |
4844  | PARAMETERS:
4845  |     IN
4846  |
4847  |     OUT
4848  |
4849  |
4850  | RETURNS:
4851  |
4852  | NOTES:
4853  |
4854  *---------------------------------------------------------------------*/
4855  FUNCTION isPaperNosUsedOnExistPmt(
4856      p_payment_doc_id IN CE_PAYMENT_DOCUMENTS.payment_document_id%TYPE,
4857      p_start_number   IN IBY_PAYMENTS_ALL.paper_document_number%TYPE,
4858      p_end_number     IN IBY_PAYMENTS_ALL.paper_document_number%TYPE
4859      ) RETURN BOOLEAN
4860  IS
4861 
4862  l_module_name    VARCHAR2(200) := G_PKG_NAME || '.isPaperNosUsedOnExistPmt';
4863  l_retflag        BOOLEAN;
4864 
4865  l_paper_doc_num       IBY_PAYMENTS_ALL.paper_document_number%TYPE;
4866  l_test_paper_doc_num  IBY_PAYMENTS_ALL.paper_document_number%TYPE;
4867  l_test_pmt_id         IBY_PAYMENTS_ALL.payment_id%TYPE;
4868 
4869  BEGIN
4870 
4871      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4872 	     print_debuginfo(l_module_name, 'ENTER');
4873 
4874 	     print_debuginfo(l_module_name, 'Start #: '
4875 	         || p_start_number
4876 	         || ', end #: '
4877 	         || p_end_number
4878 	         || ', payment document: '
4879 	         || p_payment_doc_id
4880 	         );
4881 
4882      END IF;
4883      IF (p_start_number   IS NULL OR
4884          p_end_number     IS NULL OR
4885          p_payment_doc_id IS NULL
4886          ) THEN
4887 
4888          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4889 	         print_debuginfo(l_module_name, 'Provided params are invalid. '
4890 	             || 'Returning true.');
4891 
4892          END IF;
4893          l_retflag := TRUE;
4894 
4895          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4896 	         print_debuginfo(l_module_name, 'EXIT');
4897          END IF;
4898          RETURN l_retflag;
4899 
4900      END IF;
4901 
4902      /*
4903       * Validate the entire contiguous range of provided
4904       * paper document numbers. If even a single paper
4905       * document number has already been used on a payment,
4906       * it is an error and we will return TRUE.
4907       */
4908      l_retflag := FALSE;
4909      FOR i IN 1 .. (p_end_number - p_start_number + 1) LOOP    -- Bug 6922269
4910 
4911          l_paper_doc_num := p_start_number + i - 1;
4912 
4913          BEGIN
4914 
4915              SELECT
4916                  pmt.paper_document_number,
4917                  pmt.payment_id
4918              INTO
4919                  l_test_paper_doc_num,
4920                  l_test_pmt_id
4921              FROM
4922                  IBY_PAYMENTS_ALL         pmt,
4923                  IBY_PAY_INSTRUCTIONS_ALL inst
4924              WHERE
4925                  pmt.payment_instruction_id = inst.payment_instruction_id AND
4926                  inst.payment_document_id   = p_payment_doc_id AND
4927                  pmt.paper_document_number  = l_paper_doc_num
4928              ;
4929 
4930              /*
4931               * If we reached here it means that we were able to
4932               * successfully retrieve a payment with the provided
4933               * paper document number. This implies that the
4934               * paper document number has already been used.
4935               */
4936              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4937 	             print_debuginfo(l_module_name, 'Paper document number '
4938 	                 || l_test_paper_doc_num
4939 	                 || ' has already been used for payment id '
4940 	                 || l_test_pmt_id
4941 	                 );
4942 
4943              END IF;
4944              l_retflag := TRUE;
4945 
4946          EXCEPTION
4947              WHEN OTHERS THEN
4948 
4949              /*
4950               * Handle exceptions gracefully. Assume that an
4951               * exception means that no data was found i.e., paper
4952               * document number has not been used.
4953               */
4954              NULL;
4955 
4956          END;
4957 
4958      END LOOP;
4959 
4960 
4961      IF (l_retflag = FALSE) THEN
4962          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4963 	         print_debuginfo(l_module_name, 'Returning FALSE');
4964          END IF;
4965      ELSE
4966          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4967 	         print_debuginfo(l_module_name, 'Returning TRUE');
4968          END IF;
4969      END IF;
4970 
4971      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
4972 	     print_debuginfo(l_module_name, 'EXIT');
4973      END IF;
4974      RETURN l_retflag;
4975 
4976  END isPaperNosUsedOnExistPmt;
4977 
4978 /*--------------------------------------------------------------------
4979  | NAME:
4980  |     print_debuginfo
4981  |
4982  | PURPOSE:
4983  |     This procedure prints the debug message to the concurrent manager
4984  |     log file.
4985  |
4986  | PARAMETERS:
4987  |     IN
4988  |      p_debug_text - The debug message to be printed
4989  |
4990  |     OUT
4991  |
4992  |
4993  | RETURNS:
4994  |
4995  | NOTES:
4996  |
4997  *---------------------------------------------------------------------*/
4998  PROCEDURE print_debuginfo(
4999      p_module      IN VARCHAR2,
5000      p_debug_text  IN VARCHAR2,
5001      p_debug_level IN VARCHAR2 DEFAULT FND_LOG.LEVEL_STATEMENT
5002      )
5003  IS
5004  l_default_debug_level VARCHAR2(200) := FND_LOG.LEVEL_STATEMENT;
5005  BEGIN
5006 
5007      /*
5008       * Set the debug level to the value passed in
5009       * (provided this value is not null).
5010       */
5011      IF (p_debug_level IS NOT NULL) THEN
5012          l_default_debug_level := p_debug_level;
5013      END IF;
5014 
5015      /*
5016       * Write the debug message to the concurrent manager log file.
5017       */
5018     --IF (l_default_debug_level >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5019 
5020 		 iby_debug_pub.log(debug_msg => p_module||':'||p_debug_text,debug_level => p_debug_level, module => p_module);
5021 
5022      --END IF;
5023 
5024  END print_debuginfo;
5025 
5026 /*--------------------------------------------------------------------
5027  | NAME:
5028  |     assignElectronicCheckNumbers
5029  |
5030  | PURPOSE:
5031  |
5032  |
5033  |
5034  | PARAMETERS:
5035  |     IN
5036  |
5037  |
5038  |     OUT
5039  |
5040  |
5041  | RETURNS:
5042  |
5043  |
5044  | NOTES:
5045  |     This method will perform a COMMIT.
5046  |
5047  *---------------------------------------------------------------------*/
5048  PROCEDURE assignElectronicCheckNumbers(
5049      x_pmtInstrRec       IN OUT NOCOPY IBY_PAY_INSTRUCTIONS_ALL%ROWTYPE,
5050      p_payment_doc_id    IN CE_PAYMENT_DOCUMENTS.payment_document_id%TYPE,
5051      p_user_assgn_num    IN IBY_PAYMENTS_ALL.paper_document_number%TYPE,
5052      x_paperPmtsTab      IN OUT NOCOPY paperPmtsSpecialDocsTabType,
5053      x_dummyPaperPmtsTab IN OUT NOCOPY IBY_PAYGROUP_PUB.paymentTabType,
5054      x_instrErrorTab     IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.docErrorTabType,
5055      x_insTokenTab       IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.
5056                                            trxnErrTokenTabType,
5057      x_return_message    IN OUT NOCOPY VARCHAR2,
5058      x_return_status     IN OUT NOCOPY NUMBER,
5059      x_msg_count         IN OUT NOCOPY NUMBER,
5060      x_msg_data          IN OUT NOCOPY VARCHAR2
5061      )
5062  IS
5063 
5064  l_paper_pmts_count     NUMBER := 0;
5065  l_last_used_check_num  NUMBER := 0;
5066  l_last_avail_check_num NUMBER := 0;
5067  l_physical_stock_count NUMBER := 0;
5068  l_anticipated_last_check_num  NUMBER := 0;
5069 
5070  l_pmt_doc_name      VARCHAR2(200) := '';
5071  l_pmt_instr_id      IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_id%TYPE;
5072 
5073  l_error_code        IBY_TRANSACTION_ERRORS.error_code%TYPE;
5074  l_instr_err_rec     IBY_TRANSACTION_ERRORS%ROWTYPE;
5075  l_token_rec         IBY_TRXN_ERROR_TOKENS%ROWTYPE;
5076 
5077  l_send_to_file_flag VARCHAR2(1);
5078  l_instr_status      IBY_PAY_INSTRUCTIONS_ALL.payment_instruction_status%TYPE;
5079 
5080  l_single_pmt_flag   BOOLEAN;
5081  l_nos_avlbl_flag    BOOLEAN;
5082  l_used_flag         BOOLEAN;
5083 
5084  l_module_name       VARCHAR2(200) := G_PKG_NAME || '.assignCheckNumbers';
5085 
5086  BEGIN
5087 
5088      IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5089         print_debuginfo(l_module_name, 'ENTER');
5090      END IF;
5091 
5092      l_paper_pmts_count := x_paperPmtsTab.COUNT;
5093 
5094      /* should never come into if, but just in case */
5095      IF (l_paper_pmts_count = 0) THEN
5096 
5097          /*
5098           * Shouldn't come here. This method was called because there
5099           * was atleast one payment instruction with processing type
5100           * 'PAPER'. This implies that there should be at least one
5101           * payment instruction with processing type 'PAPER'.
5102           *
5103           * If no such payment exists, about the program.
5104           */
5105          --IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5106           print_debuginfo(l_module_name, 'Total # of Electronic payments '
5107              || 'is 0. Possible data corruption. Aborting ..'
5108              );
5109 
5110 		 IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5111          print_debuginfo(l_module_name, 'EXIT');
5112          END IF;
5113          x_return_status := -1;
5114 
5115          l_error_code := 'IBY_INS_PMTS_NOT_FOUND';
5116          FND_MESSAGE.set_name('IBY', l_error_code);
5117 
5118          FND_MESSAGE.SET_TOKEN('INS_ID',
5119              x_pmtInstrRec.payment_instruction_id,
5120              FALSE);
5121 
5122          FND_MSG_PUB.ADD;
5123 
5124          FND_MSG_PUB.COUNT_AND_GET(
5125              p_count => x_msg_count,
5126              p_data  => x_msg_data
5127              );
5128 
5129          x_return_message := FND_MESSAGE.get;
5130 
5131          RETURN;
5132      ELSE
5133          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5134            print_debuginfo(l_module_name, 'Total # of Electronic payments: '
5135              || l_paper_pmts_count
5136              );
5137          END IF;
5138 
5139      END IF;
5140 
5141      /*
5142       * Check whether the provided payments list consists
5143       * of a single payment.
5144       */
5145      l_single_pmt_flag := isSinglePayment(x_paperPmtsTab);
5146 
5147      /*
5148       * For single payments, do not perform any commits because
5149       * single payments API is session based and only the caller
5150       * decides to commit / not commit.
5151       */
5152      IF (l_single_pmt_flag <> TRUE) THEN
5153 
5154          /*
5155           * This commit is needed so that in case of any exceptions
5156           * in this method (e.g., payment document locked), the
5157           * payment instruction status is changed from 'CREATED'
5158           * to the next valid status.
5159           *
5160           * Payments in 'CREATED' status are not visible in the UI,
5161           * this is because 'CREATED' is a transient status.
5162           */
5163          COMMIT;
5164 
5165          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5166            print_debuginfo(l_module_name, 'Payment instruction '
5167              || x_pmtInstrRec.payment_instruction_id
5168              || ' status committed to '
5169              || l_instr_status
5170              || ' before numbering.'
5171              );
5172          END IF;
5173 
5174      END IF;
5175 
5176      /*
5177       * Pull up the details of the paper stock, like the
5178       * last used check number and the last available
5179       * check number.
5180       *
5181       * Note: This SELECT will lock the underlying base
5182       * table IBY_PAYMENT_DOCUMENTS_B. We need to lock this
5183       * table because we need to update the last_document_number.
5184       */
5185     SELECT
5186          payment_document_name,
5187          payment_instruction_id
5188      INTO
5189          l_pmt_doc_name,
5190          l_pmt_instr_id
5191      FROM
5192          CE_PAYMENT_DOCUMENTS
5193      WHERE
5194          payment_document_id = p_payment_doc_id
5195      ;
5196 
5197 
5198       IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5199        print_debuginfo(l_module_name, 'Got the payment document name');
5200       END IF;
5201 
5202      /*
5203       *
5204       * Pull up the details of the paper stock, like the
5205       * last used check number and the last available
5206       * check number.
5207       *
5208       * Note: This SELECT will lock the underlying base
5209       * table IBY_PAYMENT_DOCUMENTS_B. We need to lock this
5210       * table because we need to update the last_document_number.
5211       *
5212       *  If document is already locked for single payment,
5213       * NO_DATA_FOUND exception would be thrown.
5214       * Bug - 7499044
5215       */
5216      BEGIN
5217      SELECT
5218          NVL(last_issued_document_number, 0),
5219          NVL(last_available_document_number, -1),
5220          payment_document_name,
5221          payment_instruction_id
5222      INTO
5223          l_last_used_check_num,
5224          l_last_avail_check_num,
5225          l_pmt_doc_name,
5226          l_pmt_instr_id
5227      FROM
5228          CE_PAYMENT_DOCUMENTS
5229      WHERE
5230          payment_document_id = p_payment_doc_id
5231      FOR UPDATE SKIP LOCKED
5232      ;
5233      EXCEPTION
5234         WHEN NO_DATA_FOUND THEN
5235                      print_debuginfo(l_module_name, 'Payment document '
5236              || ''''
5237              || l_pmt_doc_name
5238              || ''''
5239              || ' with payment doc id '
5240              || p_payment_doc_id
5241              || ' has been locked from payments workbench ',
5242              FND_LOG.LEVEL_UNEXPECTED
5243              );
5244 
5245          --IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5246           print_debuginfo(l_module_name, 'Processing cannot continue '
5247              || 'because payment document is unavailable (locked).',
5248              FND_LOG.LEVEL_UNEXPECTED
5249              );
5250 
5251 
5252           print_debuginfo(l_module_name, 'Changing the status of the '
5253              || 'payment instruction to '
5254              || l_instr_status
5255              );
5256          --END IF;
5257          /*
5258           * Fix for bug 5735030:
5259           *
5260           * Populate error message in output file so that
5261           * the user knows the cause of the failure even
5262           * if logging is turned off.
5263           */
5264          l_error_code := 'IBY_PMT_DOC_SING_LOCKED';
5265          FND_MESSAGE.SET_NAME('IBY', l_error_code);
5266 
5267          FND_MESSAGE.SET_TOKEN('DOC_NAME',
5268              l_pmt_doc_name,
5269              FALSE);
5270 
5271          FND_FILE.PUT_LINE(FND_FILE.OUTPUT, FND_MESSAGE.GET);
5272 
5273          /*
5274           * Return failure status.
5275           */
5276          x_return_status := -1;
5277 
5278          l_error_code := 'IBY_PMT_DOC_SING_LOCKED';
5279          FND_MESSAGE.set_name('IBY', l_error_code);
5280 
5281          FND_MESSAGE.SET_TOKEN('DOC_NAME',
5282              l_pmt_doc_name,
5283              FALSE);
5284 
5285          FND_MSG_PUB.ADD;
5286 
5287          FND_MSG_PUB.COUNT_AND_GET(
5288              p_count => x_msg_count,
5289              p_data  => x_msg_data
5290              );
5291 
5292          x_return_message := FND_MESSAGE.get;
5293 
5294          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5295           print_debuginfo(l_module_name, 'EXIT');
5296          END IF;
5297          RETURN;
5298 
5299 
5300      END;
5301      IF (l_pmt_instr_id IS NOT NULL) THEN
5302          --IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5303           print_debuginfo(l_module_name, 'Payment document '
5304              || ''''
5305              || l_pmt_doc_name
5306              || ''''
5307              || ' with payment doc id '
5308              || p_payment_doc_id
5309              || ' has been locked by payment instruction '
5310              || l_pmt_instr_id,
5311              FND_LOG.LEVEL_UNEXPECTED
5312              );
5313 
5314 
5315           print_debuginfo(l_module_name, 'Processing cannot continue '
5316              || 'because payment document is unavailable (locked).',
5317              FND_LOG.LEVEL_UNEXPECTED
5318              );
5319 
5320           print_debuginfo(l_module_name, 'Changing the status of the '
5321              || 'payment instruction to '
5322              || l_instr_status
5323              );
5324            --END IF;
5325 
5326          /*
5327           * Fix for bug 5735030:
5328           *
5329           * Populate error message in output file so that
5330           * the user knows the cause of the failure even
5331           * if logging is turned off.
5332           */
5333          l_error_code := 'IBY_INS_PMT_DOC_LOCKED_DETAIL';
5334          FND_MESSAGE.SET_NAME('IBY', l_error_code);
5335 
5336          FND_MESSAGE.SET_TOKEN('THIS_INS_NUM',
5337              x_pmtInstrRec.payment_instruction_id,
5338              FALSE);
5339 
5340          FND_MESSAGE.SET_TOKEN('PREV_INS_NUM',
5341              l_pmt_instr_id,
5342              FALSE);
5343 
5344          FND_MESSAGE.SET_TOKEN('DOC_NAME',
5345              l_pmt_doc_name,
5346              FALSE);
5347 
5348          FND_FILE.PUT_LINE(FND_FILE.OUTPUT, FND_MESSAGE.GET);
5349 
5350          /*
5351           * Return failure status.
5352           */
5353          x_return_status := -1;
5354 
5355          l_error_code := 'IBY_INS_PMT_DOC_LOCKED';
5356          FND_MESSAGE.set_name('IBY', l_error_code);
5357 
5358          FND_MESSAGE.SET_TOKEN('INS_ID',
5359              l_pmt_instr_id,
5360              FALSE);
5361 
5362          FND_MSG_PUB.ADD;
5363 
5364          FND_MSG_PUB.COUNT_AND_GET(
5365              p_count => x_msg_count,
5366              p_data  => x_msg_data
5367              );
5368 
5369          x_return_message := FND_MESSAGE.get;
5370 
5371          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5372           print_debuginfo(l_module_name, 'EXIT');
5373          END IF;
5374          RETURN;
5375 
5376      END IF;
5377 
5378      /*
5379       * Log warnings if there is any missing/incomplete information.
5380       */
5381      IF (l_last_avail_check_num = -1) THEN
5382 
5383          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5384           print_debuginfo(l_module_name, 'Warning: payment document id '
5385              || p_payment_doc_id
5386              || ' has no last available document number set. '
5387              || 'Assuming that infinite number of paper documents '
5388              || 'can be printed for this payment document.'
5389              );
5390          END IF;
5391 
5392      END IF;
5393 
5394      IF (l_last_used_check_num = 0) THEN
5395 
5396          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5397           print_debuginfo(l_module_name, 'Warning: payment document id '
5398              || p_payment_doc_id
5399              || ' has last used document number set to zero. '
5400              || 'Assuming that no paper documents have yet '
5401              || 'been printed for this payment document.'
5402              );
5403          END IF;
5404 
5405      END IF;
5406 
5407 
5408      /*
5409       * If user has explicitly provided a start number for check
5410       * numbering, we have to use it in our numbering logic.
5411       * This will only happen for single payments.
5412       *
5413       * For Build Program invoked numbering, we will always start
5414       * from the last issued check number on the payment document + 1.
5415       */
5416      IF (p_user_assgn_num IS NULL) THEN
5417 
5418          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5419           print_debuginfo(l_module_name, 'User has not explicitly '
5420              || 'provided a check number to start numbering from. '
5421              || 'Numbering will start from last issued check number '
5422              || 'on check stock.'
5423              );
5424          END IF;
5425 
5426      ELSE
5427 
5428          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5429           print_debuginfo(l_module_name, 'User has explicitly '
5430              || 'provided start number for numbering: '
5431              || p_user_assgn_num
5432              );
5433          END IF;
5434 
5435          /*
5436           * The code below uses the variable 'l_last_used_check_num'
5437           * as the starting number for check numbering. The numbering
5438           * will begin from l_last_used_check_num + 1.
5439           *
5440           * If the user has explicitly provided a start number for
5441           * numbering, we need to adjust the l_last_used_check_num
5442           * value accordingly.
5443           */
5444          l_last_used_check_num := p_user_assgn_num - 1;
5445 
5446      END IF;
5447 
5448      /*
5449       * Check if enough paper documents are available to complete
5450       * this payment instruction.
5451       *
5452       * Perform this check only if a value has been provided
5453       * for the last available document number. If no value is
5454       * set assume that an infinite number of checks can be
5455       * printed for this paper stock (payment document).
5456       */
5457      IF (l_last_avail_check_num <> -1) THEN
5458 
5459          /*
5460           * Check if enough paper documents are available to complete
5461           * this payment instruction.
5462           */
5463          l_physical_stock_count := l_last_avail_check_num
5464                                        - l_last_used_check_num;
5465 
5466          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5467           print_debuginfo(l_module_name, 'Available paper stock = '
5468              || l_physical_stock_count
5469              || ' for payment document name '
5470              || ''''
5471              || l_pmt_doc_name
5472              || ''''
5473              );
5474          END IF;
5475 
5476          IF (l_physical_stock_count < l_paper_pmts_count) THEN
5477 
5478              /*
5479               * Not enough paper stock is available to print
5480               * the checks for this payment instruction.
5481               *
5482               * Set the status of the payment instruction to
5483               * failed.
5484               */
5485 
5486               print_debuginfo(l_module_name, 'Deferring payment '
5487                  || 'instruction print '
5488                  || x_pmtInstrRec.payment_instruction_id
5489                  || ' because of insufficient paper stock.',
5490                  FND_LOG.LEVEL_UNEXPECTED
5491                  );
5492 
5493 
5494              x_pmtInstrRec.payment_instruction_status := l_instr_status;
5495 
5496              l_error_code := 'IBY_INS_INSUFFICIENT_PAY_DOCS';
5497 
5498              FND_MESSAGE.set_name('IBY', l_error_code);
5499 
5500              FND_MESSAGE.SET_TOKEN('NUM_AVAIL',
5501                  l_physical_stock_count,
5502                  FALSE);
5503 
5504              l_token_rec.token_name  := 'NUM_AVAIL';
5505              l_token_rec.token_value := l_physical_stock_count;
5506              x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
5507 
5508              FND_MESSAGE.SET_TOKEN('NUM_REQD',
5509                  l_paper_pmts_count,
5510                  FALSE);
5511 
5512              l_token_rec.token_name  := 'NUM_REQD';
5513              l_token_rec.token_value := l_paper_pmts_count;
5514              x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
5515 
5516              /*
5517               * Once we fail a pmt instruction, we must add a
5518               * corresponding error message to the errors table.
5519               */
5520              IBY_PAYINSTR_UTILS_PKG.createErrorRecord(
5521                  x_pmtInstrRec.payment_instruction_id,
5522                  x_pmtInstrRec.payment_instruction_status,
5523                  l_error_code,
5524                  FND_MESSAGE.get,
5525                  'N',
5526                  l_instr_err_rec
5527                  );
5528 
5529              IBY_VALIDATIONSETS_PUB.insertIntoErrorTable(
5530                  l_instr_err_rec,
5531                  x_instrErrorTab,
5532                  x_insTokenTab
5533                  );
5534 
5535              /* add error message to msg stack */
5536              FND_MSG_PUB.ADD;
5537 
5538              FND_MSG_PUB.COUNT_AND_GET(
5539                  p_count => x_msg_count,
5540                  p_data  => x_msg_data
5541                  );
5542 
5543              /* set error message to return to caller */
5544              x_return_message := FND_MESSAGE.get;
5545 
5546              /*
5547               * Now, raise an exception. This will be caught
5548               * in the exception handler below and the changes
5549               * made to the DB in this transaction
5550               * will be rolled back.
5551               */
5552              APP_EXCEPTION.RAISE_EXCEPTION;
5553 
5554          ELSE
5555 
5556              IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5557               print_debuginfo(l_module_name, 'Sufficient paper stock '
5558                  || 'is available to print this instruction.'
5559                  );
5560              END IF;
5561 
5562          END IF;
5563 
5564      END IF; -- l_last_avail_check_num <> -1
5565 
5566      /*
5567       * If sufficient paper stock is available, we will be using
5568       * up the paper stock by assigning it to the available
5569       * paper payments. Therefore, update the last used paper
5570       * stock number in CE_PAYMENT_DOCUMENTS.
5571       *
5572       * That way if another instance of the payment instruction
5573       * creation program is operating concurrently, it will
5574       * be blocked by the SELECT .. FOR UPDATE statement in
5575       * this method.
5576       *
5577       */
5578      l_anticipated_last_check_num := l_last_used_check_num
5579                                          + l_paper_pmts_count;
5580 
5581      /*
5582       * We will be printing the checks starting with
5583       * paper doc num 'l_last_used_check_num + 1' and
5584       * ending with paper doc num l_anticipated_last_check_num.
5585       *
5586       * Check whether all the paper doc numbers within this
5587       * range are available. We cannot have any gaps in the
5588       * numbering because checks have to be numbered
5589       * contiguously.
5590       */
5591      l_nos_avlbl_flag := isContigPaperNumAvlbl(
5592                              p_payment_doc_id,
5593                              l_last_used_check_num + 1,
5594                              l_anticipated_last_check_num
5595                              );
5596 
5597      IF (l_nos_avlbl_flag = FALSE) THEN
5598 
5599          --IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5600           print_debuginfo(l_module_name, 'Contiguous paper stock '
5601              || 'is not available for printing payment instruction '
5602              || x_pmtInstrRec.payment_instruction_id
5603              );
5604          --END IF;
5605 
5606          /*
5607           * Return failure status.
5608           */
5609          x_return_status := -1;
5610 
5611          l_error_code := 'IBY_INS_NSF_CONTIG_NUM';
5612          FND_MESSAGE.set_name('IBY', l_error_code);
5613 
5614          FND_MESSAGE.SET_TOKEN('NUM_PMT_DOCS',
5615              l_paper_pmts_count,
5616              FALSE);
5617 
5618          FND_MSG_PUB.ADD;
5619 
5620          FND_MSG_PUB.COUNT_AND_GET(
5621              p_count => x_msg_count,
5622              p_data  => x_msg_data
5623              );
5624 
5625          x_return_message := FND_MESSAGE.get;
5626 
5627          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5628           print_debuginfo(l_module_name, 'EXIT');
5629          END IF;
5630          RETURN;
5631 
5632      END IF;
5633 
5634      /*
5635       * A paper document number (check number) is considered
5636       * unused if it is not present in IBY_USED_PAYMENT_DOCS
5637       * table.
5638       *
5639       * This logic will work when check numbering is invoked
5640       * from the Build Program. In this case, the numbering
5641       * logic always starts with the last issued doc number + 1
5642       * when assigning new check numbers. Therefore, the
5643       * check numbers will always be unique (unused).
5644       *
5645       * However, when check numbering is invoked for single
5646       * payments, the user is allowed to provide the start
5647       * number for check numbering. It is possible that
5648       * a payment has already been numbered with the user
5649       * provided start number, but this paper document may
5650       * not yet have been inserted into the IBY_USED_PAYMENT_DOCS
5651       * table (because the user has not yet confirmed the
5652       * payment).
5653       *
5654       * Therefore, for single payments, when the user provides
5655       * the start number for check numbering, we will have to
5656       * verify that the provided number is unused by checking
5657       * the paper document number on existing payments.
5658       */
5659      IF (p_user_assgn_num IS NOT NULL) THEN
5660 
5661          l_used_flag := isPaperNosUsedOnExistPmt(
5662                             p_payment_doc_id,
5663                             l_last_used_check_num + 1,
5664                             l_anticipated_last_check_num);
5665 
5666          IF (l_used_flag = TRUE) THEN
5667 
5668             -- IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5669               print_debuginfo(l_module_name, 'Paper document number(s) '
5670                  || 'generated after numbering are invalid (already used). '
5671                  || 'User needs to provide a new start number or use '
5672                  || 'the defaulted start number.'
5673                  );
5674             -- END IF;
5675 
5676              /*
5677               * Return failure status.
5678               */
5679              x_return_status := -1;
5680 
5681              l_error_code := 'IBY_INS_ALREADY_USED_NUM';
5682              FND_MESSAGE.set_name('IBY', l_error_code);
5683 
5684              FND_MSG_PUB.ADD;
5685 
5686              FND_MSG_PUB.COUNT_AND_GET(
5687                  p_count => x_msg_count,
5688                  p_data  => x_msg_data
5689                  );
5690 
5691              x_return_message := FND_MESSAGE.get;
5692 
5693              IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5694               print_debuginfo(l_module_name, 'EXIT');
5695              END IF;
5696              RETURN;
5697 
5698          ELSE
5699 
5700              IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5701               print_debuginfo(l_module_name, 'Paper document number(s) '
5702                  || 'generated after numbering are unused. '
5703                  );
5704              END IF;
5705 
5706          END IF;
5707 
5708      END IF;
5709 
5710      /*
5711       * For single payments, the payment document should
5712       * not be locked (see bug 4597718).
5713       */
5714      IF (l_single_pmt_flag = TRUE) THEN
5715 
5716          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5717           print_debuginfo(l_module_name, 'This is a single payment. '
5718              || 'Payment document will not be locked ..'
5719              );
5720          END IF;
5721 
5722          /*
5723           * Update the check stock to reflect the latest used
5724           * check number.
5725           */
5726          UPDATE
5727              CE_PAYMENT_DOCUMENTS
5728          SET
5729              last_issued_document_number = l_anticipated_last_check_num
5730          WHERE
5731              payment_document_id         = p_payment_doc_id
5732          AND
5733 	     last_issued_document_number < l_anticipated_last_check_num
5734          ;
5735 
5736      ELSE
5737 
5738          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5739           print_debuginfo(l_module_name, 'This is not a single payment. '
5740              || 'Payment document will be locked ..'
5741              );
5742          END IF;
5743 
5744          /*
5745           * Update the check stock to reflect the latest used
5746           * check number, and lock the check stock.
5747           */
5748          UPDATE
5749              CE_PAYMENT_DOCUMENTS
5750          SET
5751              last_issued_document_number = l_anticipated_last_check_num,
5752              payment_instruction_id      = x_pmtInstrRec.payment_instruction_id
5753          WHERE
5754              payment_document_id         = p_payment_doc_id
5755          ;
5756 
5757      END IF;
5758 
5759      IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5760       print_debuginfo(l_module_name, 'Finished updating the last '
5761          || 'available check number in CE_PAYMENT_DOCUMENTS. '
5762          || 'Current last check number: '
5763          || l_anticipated_last_check_num
5764          );
5765      END IF;
5766 
5767      /* uncomment for debug purposes */
5768      --print_debuginfo(l_module_name, 'x_dummyPaperPmtsTab.COUNT: '
5769      --    || x_dummyPaperPmtsTab.COUNT);
5770      --print_debuginfo(l_module_name, 'x_paperPmtsTab.COUNT: '
5771      --    || x_paperPmtsTab.COUNT);
5772 
5773 
5774      /*
5775       * Commenting below code as we do not have setup
5776       * or overflow documents for Electronic Processing type
5777       * of payments.
5778       */
5779      /*
5780       * Assign contiguous check numbers to the setup checks.
5781       * These are dummy checks that are printed at the
5782       * beginning of the payment instruction print run.
5783       */
5784      /*IF (x_dummyPaperPmtsTab.COUNT <> 0) THEN
5785 
5786          FOR i in x_dummyPaperPmtsTab.FIRST .. x_dummyPaperPmtsTab.LAST LOOP
5787 
5788              IF (x_dummyPaperPmtsTab(i).payment_status = 'VOID_BY_SETUP') THEN
5789 
5790                  l_last_used_check_num := l_last_used_check_num + 1;
5791                  x_dummyPaperPmtsTab(i).paper_document_number
5792                      := l_last_used_check_num;
5793 
5794              END IF;
5795 
5796          END LOOP; -- for all setup payments in x_dummyPaperPmtsTab
5797 
5798      END IF;*/
5799 
5800      /* assign check number to paper payment */
5801      FOR i in x_paperPmtsTab.FIRST .. x_paperPmtsTab.LAST LOOP
5802 
5803          l_last_used_check_num := l_last_used_check_num + 1;
5804          x_paperPmtsTab(i).check_number := l_last_used_check_num;
5805 
5806      END LOOP; -- for all pmts in x_paperPmtsTab
5807 
5808      /*
5809       * Final check:
5810       *
5811       * If all paper payments (including real payments, setup payments
5812       * and overflow payments) have been assigned check numbers
5813       * correctly, then the number of check numbers used up should
5814       * match the total paper payments count.
5815       *
5816       * If the two don't match, it means that some check numbers were
5817       * unassigned, or multiply assigned. In either case, abort the
5818       * program. This check will reveal any bugs in this method.
5819       */
5820      IF (l_anticipated_last_check_num <> l_last_used_check_num) THEN
5821 
5822 
5823           print_debuginfo(l_module_name, 'Check numbers were not '
5824              || 'properly assigned. '
5825              || 'Anticipated last used check number: '
5826              || l_anticipated_last_check_num
5827              || '. Actual last used check number: '
5828              || l_last_used_check_num
5829              || '. Deferring print for payment instruction '
5830              || x_pmtInstrRec.payment_instruction_id,
5831              FND_LOG.LEVEL_UNEXPECTED
5832              );
5833 
5834 
5835          x_pmtInstrRec.payment_instruction_status := l_instr_status;
5836 
5837          l_error_code := 'IBY_INS_NUMBERING_ERR_1';
5838 
5839          FND_MESSAGE.set_name('IBY', l_error_code);
5840 
5841          FND_MESSAGE.SET_TOKEN('NUM_CALC',
5842              l_anticipated_last_check_num,
5843              FALSE);
5844 
5845          l_token_rec.token_name  := 'NUM_CALC';
5846          l_token_rec.token_value := l_anticipated_last_check_num;
5847          x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
5848 
5849          FND_MESSAGE.SET_TOKEN('NUM_ACTU',
5850              l_last_used_check_num,
5851              FALSE);
5852 
5853          l_token_rec.token_name  := 'NUM_ACTU';
5854          l_token_rec.token_value := l_last_used_check_num;
5855          x_insTokenTab(x_insTokenTab.COUNT + 1) := l_token_rec;
5856 
5857          /*
5858           * Once we fail a pmt instruction, we must add a
5859           * corresponding error message to the errors table.
5860           */
5861          IBY_PAYINSTR_UTILS_PKG.createErrorRecord(
5862              x_pmtInstrRec.payment_instruction_id,
5863              x_pmtInstrRec.payment_instruction_status,
5864              l_error_code,
5865              FND_MESSAGE.get,
5866              'N',
5867              l_instr_err_rec
5868              );
5869 
5870          IBY_VALIDATIONSETS_PUB.insertIntoErrorTable(
5871              l_instr_err_rec,
5872              x_instrErrorTab,
5873              x_insTokenTab
5874              );
5875 
5876          /* add error msg to message stack */
5877          FND_MSG_PUB.ADD;
5878 
5879          FND_MSG_PUB.COUNT_AND_GET(
5880              p_count => x_msg_count,
5881              p_data  => x_msg_data
5882              );
5883 
5884          /* set error message to return to caller */
5885          x_return_message := FND_MESSAGE.get;
5886 
5887          APP_EXCEPTION.RAISE_EXCEPTION;
5888 
5889      END IF;
5890 
5891      /*
5892       * Return success status.
5893       */
5894      x_return_message := 'SUCCESS';
5895      x_return_status  := 0;
5896 
5897      IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5898       print_debuginfo(l_module_name, 'EXIT');
5899      END IF;
5900 
5901      EXCEPTION
5902          WHEN OTHERS THEN
5903 
5904          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5905           print_debuginfo(l_module_name, 'Exception occured when '
5906              || 'performing document numbering. '
5907              );
5908           print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
5909           print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
5910          END IF;
5911          /*
5912           * Rollback any DB changes made in this method.
5913           */
5914          ROLLBACK;
5915 
5916          /*
5917           * Return error status to caller.
5918           * The error message would have already been set.
5919           */
5920          x_return_status := -1;
5921 
5922          IF (G_LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5923           print_debuginfo(l_module_name, 'EXIT');
5924          END IF;
5925 
5926  END assignElectronicCheckNumbers;
5927 
5928 
5929 END IBY_CHECKNUMBER_PUB;