DBA Data[Home] [Help]

PACKAGE BODY: APPS.IBY_BUILD_UTILS_PKG

Source


1 PACKAGE BODY IBY_BUILD_UTILS_PKG AS
2 /*$Header: ibyblutb.pls 120.31.12020000.3 2013/02/25 11:09:14 kchavali ship $*/
3 
4  /*
5   * Declare global variables
6   */
7  G_PKG_NAME CONSTANT VARCHAR2(30) := 'IBY_BUILD_UTILS_PKG';
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 document statuses that are used / set in this
13  -- module.
14  --
15  DOC_STATUS_VALIDATED    CONSTANT VARCHAR2(100) := 'VALIDATED';
16  DOC_STATUS_FAIL_VALID   CONSTANT VARCHAR2(100) := 'FAILED_VALIDATION';
17  DOC_STATUS_PAY_CREATED  CONSTANT VARCHAR2(100) := 'PAYMENT_CREATED';
18  DOC_STATUS_CA_FAILED    CONSTANT VARCHAR2(100) := 'FAILED_BY_CALLING_APP';
19  DOC_STATUS_RELN_FAIL    CONSTANT VARCHAR2(100) := 'FAILED_BY_RELATED_DOCUMENT';
20  DOC_STATUS_PAY_VAL_FAIL CONSTANT VARCHAR2(100) := 'PAYMENT_FAILED_VALIDATION';
21  DOC_STATUS_FAIL_BY_REJLVL CONSTANT VARCHAR2(100)
22                                                 := 'FAILED_BY_REJECTION_LEVEL';
23 
24  --
25  -- List of payment statuses that are used / set in this
26  -- module.
27  --
28  PAY_STATUS_FAIL_VALID     CONSTANT VARCHAR2(100) := 'FAILED_VALIDATION';
29  PAY_STATUS_CREATED        CONSTANT VARCHAR2(100) := 'CREATED';
30  PAY_STATUS_CA_FAILED      CONSTANT VARCHAR2(100) := 'FAILED_BY_CALLING_APP';
31  PAY_STATUS_FAIL_BY_REJLVL CONSTANT VARCHAR2(100)
32                                         := 'FAILED_BY_REJECTION_LEVEL';
33  PAY_STATUS_MODIFIED       CONSTANT VARCHAR2(100) := 'MODIFIED';
34 
35  --
36  -- Lookups for profile applicablility types (from IBY_PMT_PROF_LOV_APL_TYPES)
37  --
38  APL_TYPE_ORG            CONSTANT VARCHAR2(100) := 'PAYER_ORG';
39  APL_TYPE_PMT_METHOD     CONSTANT VARCHAR2(100) := 'PAYMENT_METHOD';
40  APL_TYPE_PMT_CURRENCY   CONSTANT VARCHAR2(100) := 'CURRENCY_CODE';
41  APL_TYPE_INT_BANK_ACCT  CONSTANT VARCHAR2(100) := 'INTERNAL_BANK_ACCOUNT';
42 
43  --
44  -- List of transaction error statuses that are used / set in this
45  -- module.
46  --
47  TRXN_ERROR_ACTIVE         CONSTANT VARCHAR2(100) := 'ACTIVE';
48 
49 TYPE l_prof_der_rec_type IS RECORD(
50      l_profile_id        IBY_DOCS_PAYABLE_ALL.payment_profile_id%TYPE,
51      l_valid_flag       VARCHAR2(1)
52 );
53 
54 TYPE l_prof_der_tbl_type IS TABLE OF l_prof_der_rec_type INDEX BY VARCHAR2(2000);
55 l_prof_der_tbl  l_prof_der_tbl_type;
56 
57 TYPE l_prof_val_tbl_type IS TABLE OF VARCHAR2(2000) INDEX BY VARCHAR2(2000);
58 l_prof_val_tbl  l_prof_val_tbl_type;
59 
60 TYPE profile_cod_tbl_type is table of IBY_PAYMENT_PROFILES.system_profile_code%TYPE index by BINARY_INTEGER;
61       l_profile_cod_tbl       profile_cod_tbl_type;
62 
63 
64 /*--------------------------------------------------------------------
65  | NAME:
66  |     print_debuginfo
67  |
68  | PURPOSE:
69  |
70  |
71  | PARAMETERS:
72  |     IN
73  |
74  |
75  |     OUT
76  |
77  |
78  | RETURNS:
79  |
80  | NOTES:
81  |
82  *---------------------------------------------------------------------*/
83  PROCEDURE print_debuginfo(p_module IN VARCHAR2,
84      p_debug_text  IN VARCHAR2,
85      p_debug_level IN VARCHAR2  DEFAULT FND_LOG.LEVEL_STATEMENT
86      )
87  IS
88  l_default_debug_level VARCHAR2(200) := FND_LOG.LEVEL_STATEMENT;
89  PRAGMA AUTONOMOUS_TRANSACTION;
90 
91  BEGIN
92 
93      /*
94       * Set the debug level to the value passed in
95       * (provided this value is not null).
96       */
97      IF (p_debug_level IS NOT NULL) THEN
98          l_default_debug_level := p_debug_level;
99      END IF;
100 
101      /*
102       * Write immediate validation messages to the common
103       * application logs. Write deferred validation messages
104       * to the concurrent manager log file.
105       *
106       * If FND_GLOBAL.conc_request_id is -1, it implies that
107       * this method has not been invoked via the concurrent
108       * manager (online validation case; write to apps log).
109       */
110      IF (l_default_debug_level >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
111 
112          IF (FND_GLOBAL.conc_request_id = -1) THEN
113 
114              /*
115               * OPTION I:
116               * Write debug text to the common application log file.
117               */
118              --IBY_DEBUG_PUB.add(
119              --    substr(RPAD(p_module,55) || ' : ' || p_debug_text, 0, 150),
120              --    FND_LOG.G_CURRENT_RUNTIME_LEVEL,
121              --    'iby.plsql.IBY_VALIDATIONSETS_PUB'
122              --    );
123 
124              FND_LOG.STRING(
125                  l_default_debug_level,
126                  'iby.plsql.IBY_VALIDATIONSETS_PUB',
127                  substr(RPAD(p_module, 55) || ' : ' || p_debug_text, 0, 150)
128                  );
129 
130              /*
131               * OPTION II:
132               * Write debug text to DBMS output file.
133               */
134              --DBMS_OUTPUT.PUT_LINE(substr(RPAD(p_module,40)||' : '||
135              --    p_debug_text, 0, 150));
136 
137              /*
138               * OPTION III:
139               * Write debug text to temporary table.
140               */
141 
142              /*
143               * Use this script to create a debug table.
144               *
145               * CREATE TABLE TEMP_IBY_LOGS(TEXT VARCHAR2(4000), TIME DATE);
146               */
147 
148              /* uncomment these two lines for debugging */
149              --INSERT INTO TEMP_IBY_LOGS VALUES (p_module || ': '
150              --    || p_debug_text, sysdate);
151              --COMMIT;
152 
153          ELSE
154 
155              /*
156               * OPTION I:
157               * Write debug text to the concurrent manager log file.
158               */
159              FND_FILE.PUT_LINE(FND_FILE.LOG, p_module || ': ' || p_debug_text);
160 
161              /*
162               * OPTION II:
163               * Write debug text to DBMS output file.
164               */
165              --DBMS_OUTPUT.PUT_LINE(substr(RPAD(p_module,40)||' : '||
166              --    p_debug_text, 0, 150));
167 
168              /*
169               * OPTION III:
170               * Write debug text to temporary table.
171               */
172 
173              /*
174               * Use this script to create a debug table.
175               *
176               * CREATE TABLE TEMP_IBY_LOGS(TEXT VARCHAR2(4000), TIME DATE);
177               */
178 
179              /* uncomment these two lines for debugging */
180              --INSERT INTO TEMP_IBY_LOGS VALUES (p_module || ': '
181              --    || p_debug_text, sysdate);
182              --COMMIT;
183 
184          END IF; -- if not a conc request
185 
186      END IF; -- if current debug level greater than runtime debug level
187 
188  EXCEPTION
189      WHEN OTHERS THEN
190 
191      ROLLBACK;
192 
193  END print_debuginfo;
194 
195 /*--------------------------------------------------------------------
196  | NAME:
197  |     printXMLClob
198  |
199  | PURPOSE:
200  |     Prints out the XML data contained within the given clob; to be
201  |     used for testing purposes.
202  |
203  |
204  | PARAMETERS:
205  |     IN
206  |
207  |     OUT
208  |
209  |
210  | RETURNS:
211  |
212  | NOTES:
213  |
214  *---------------------------------------------------------------------*/
215  PROCEDURE printXMLClob(
216      p_xml_clob   IN CLOB)
217  IS
218 
219  l_xmlstr VARCHAR2(32767);
220  l_line   VARCHAR2(2000);
221  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME || '.printXMLClob';
222 
223  BEGIN
224 
225      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
226 	     print_debuginfo(l_module_name, 'ENTER');
227 
228      END IF;
229      /*
230       * Do not attempt to print XML clob unless it contains
231       * CR-LFs.
232       */
233      IF (DBMS_LOB.INSTR(p_xml_clob, fnd_global.local_chr(10)) = 0) THEN
234 
235          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
236 	         print_debuginfo(l_module_name, 'Clob does not contain '
237 	             || 'CR-LFs; cannot print entire XML Clob, '
238 	             || 'printing a snippet ..'
239 	             );
240 
241 	         print_debuginfo(l_module_name, TO_CHAR(p_xml_clob));
242 	         print_debuginfo(l_module_name, 'EXIT');
243 
244          END IF;
245          RETURN;
246 
247      END IF;
248 
249 
250      /*
251       * Print the clob as an XML fragment.
252       */
253      l_xmlstr := dbms_lob.substr(p_xml_clob, 32767);
254      LOOP
255 
256          EXIT WHEN l_xmlstr IS NULL;
257 
258          l_line := SUBSTR(l_xmlstr,1,INSTR(l_xmlstr,
259                        fnd_global.local_chr(10))-1);
260 
261          IF (l_line IS NOT NULL) THEN
262 
263              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
264 	             print_debuginfo('', l_line);
265 
266              END IF;
267              l_xmlstr := SUBSTR(l_xmlstr,INSTR(l_xmlstr,
268                            fnd_global.local_chr(10))+1);
269 
270          ELSE
271 
272              /*
273               * Fix for bug 5550778:
274               *
275               * Print the last chunk and set the
276               * xml string to null so that we do
277               * not go into an infinite loop
278               * in case we cannot find a '\n'
279               * in the XML clob.
280               */
281              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
282 	             print_debuginfo('', l_xmlstr);
283 
284              END IF;
285              l_xmlstr := NULL;
286 
287          END IF;
288 
289      END LOOP;
290 
291      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
292 	     print_debuginfo(l_module_name, 'EXIT');
293 
294      END IF;
295  END printXMLClob;
296 
297 /*--------------------------------------------------------------------
298  | NAME:
299  |     checkForInvalidChars
300  |
301  | PURPOSE:
302  |     Given an input string and a string of invalid characters, this
303  |     procedure checks if any of the invalid characters are present
304  |     in the given input string.
305  |
306  |     If any of the invalid characters are found, an error message is
307  |     inserted into the error table identifying the invalid character.
308  |
309  |     If no invalid characters are found in the input string, this
310  |     procedure simply returns.
311  |
312  | PARAMETERS:
313  |     IN
314  |     p_fieldName  - The name  of the input field (used for logging)
315  |     p_fieldValue - The value of the input field
316  |     p_isComposite - Indidicates that the field is a composite
317  |                     field created by appending multiple individual
318  |                     fields. For composite fields, the field value
319  |                     will not be printed in the error message.
320  |     p_invalid_chars_list - List of invalid characters that
321  |                    should not be present in the field value
322  |     OUT
323  |     x_docErrorRec - Error message record. This should contain the
324  |                     document id when coming into this method.
325  |     x_docErrorTab - Error messages table. An error message will be
326  |                     added to this table if the input field value
327  |                     contains an invalid char.
328  |
329  | RETURNS:
330  |
331  | NOTES:
332  |
333  *---------------------------------------------------------------------*/
334  PROCEDURE checkForInvalidChars(
335          p_fieldName          IN VARCHAR2,
336          p_fieldValue         IN VARCHAR2,
337          p_isComposite        IN BOOLEAN,
338          p_validCharsList     IN VARCHAR2,
339          p_invalidCharsList   IN VARCHAR2,
340          x_docErrorRec        IN OUT NOCOPY IBY_TRANSACTION_ERRORS%ROWTYPE,
341          x_docErrorTab        IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.
342                                                 docErrorTabType
343          )
344  IS
345  l_error_code   VARCHAR2(100);
346  l_error_msg    VARCHAR2(500);
347 
348  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME || '.checkForInvalidChars';
349 
350  /*
351   * This dummy string is used as the third argument to the TRANSLATE()
352   * function. Only used if invalid chars list is provided.
353   *
354   * The value of the string does not matter. It is used as a mask;
355   * translate() will substitute any invalid chars in the field value
356   * with a dummy value from this string. We will diff these two strings
357   * to find the invalid characters.
358   */
359  l_inv_mask VARCHAR2(200) :=
360      'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
361 
362  /*
363   * Dummy string used as mask for checking valid characters. Only used
364   * if valid chars list is provided.
365   */
366  l_val_mask VARCHAR2(20) := ' ';
367 
368  l_translated_value VARCHAR2(200);
369  l_invalid_chars_found VARCHAR2(200);
370  l_error_string  VARCHAR2(1000);
371 
372  BEGIN
373 
374      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
375 	     print_debuginfo(l_module_name, 'ENTER');
376 
377      END IF;
378      /*
379       * Don't do anything if the given value is null.
380       */
381      IF (p_fieldValue IS NULL) THEN
382          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
383 	         print_debuginfo(l_module_name, 'Value provided for field '''
384 	             || p_fieldName
385 	             || ''' is null. Skipping character validation'
386 	             );
387 	         print_debuginfo(l_module_name, 'EXIT');
388          END IF;
389          RETURN;
390      ELSE
391          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
392 	         print_debuginfo(l_module_name, 'Value provided for field '''
393 	             || p_fieldName || ''' is '
394 	             || p_fieldValue
395 	             );
396          END IF;
397      END IF;
398 
399      /*
400       * MAIN CHARACTER VALIDATION LOGIC
401       */
402      /* character validation using valid chars list */
403      IF (p_validCharsList IS NOT NULL) THEN
404 
405          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
406 	         print_debuginfo(l_module_name, 'Checking using valid chars list..');
407 
408          END IF;
409          /*
410           * HOW DOES IT WORK?
411           *
412           * Given a list of valid characters, we call translate like this:
413           *
414           * translate(
415           *     -- given string
416           *     'Oracle 9i',
417           *     -- valid chars list
418           *     'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
419           *     -- mask
420           *     ' '
421           *     );
422           *
423           * This returns '9'. And so we caught the invalid character.
424           */
425 
426          /*
427           * Call translate() to filter out the invalid chars.
428           */
429          SELECT translate(p_fieldValue, p_validCharsList, l_val_mask)
430          INTO l_translated_value
431          FROM DUAL;
432 
433          /* strip spaces */
434          l_translated_value := LTRIM(l_translated_value);
435          l_translated_value := RTRIM(l_translated_value);
436 
437          /*
438           * This means that all characters in the field value were
439           * found in the valid char list. So the value contains
440           * only valid characters. No invalid chars; Exit at this point.
441           */
442          IF (l_translated_value IS NULL) THEN
443              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
444 	             print_debuginfo(l_module_name, 'EXIT');
445              END IF;
446              RETURN;
447          ELSE
448              /*
449               * This means that some characters were present in the
450               * field value that could not be found in the valid char
451               * list. Therefore, invalid characters are present in this
452               * field.
453               */
454              l_invalid_chars_found := l_translated_value;
455          END IF;
456 
457      ELSE
458          /* character validation using invalid chars list */
459          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
460 	         print_debuginfo(l_module_name, 'Checking using invalid chars list..');
461 
462          END IF;
463          /*
464           * HOW DOES IT WORK?
465           *
466           * Given a list of invalid characters, we call translate like this:
467           *
468           * translate(
469           *     -- given string
470           *     '[email protected]',
471           *     -- invalid chars list
472           *     '@#$'
473           *     -- mask
474           *     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
475           *     );
476           *
477           * This returns 'rameshaoracle.com'.
478           *
479           * We diff the input string and the translated string to get '@'
480           * as the invalid character.
481           */
482 
483          /*
484           * Call translate to substitute any invalid chars in
485           * the given string with dummy ones.
486           */
487          SELECT translate(p_fieldValue, p_invalidCharsList, l_inv_mask)
488          INTO l_translated_value
489          FROM DUAL;
490 
491          /*
492           * If the translated value is not equal to the original
493           * field value, it means that there were some invalid
494           * characters in the field value.
495           *
496           * Diff the original and translated values to get the
497           * invalid characters.
498           */
499          IF (p_fieldValue <> l_translated_value) THEN
500              l_invalid_chars_found := diffStrings(p_fieldValue,
501                                           l_translated_value);
502          END IF;
503 
504      END IF; -- valid chars list is not null
505 
506      IF (l_invalid_chars_found IS NOT NULL) THEN
507 
508          /*
509           * Do not show the field value for composite fields.
510           */
511          IF (p_isComposite = true) THEN
512 
513              l_error_string := 'Found invalid char(s) '
514                  || '''' || l_invalid_chars_found  || ''''
515                  || ' in field '
516                  || '''' || p_fieldName || ''''
517                  ;
518 
519              l_error_code := 'IBY_FOUND_INVALID_CHARS';
520              FND_MESSAGE.set_name('IBY', l_error_code);
521 
522              FND_MESSAGE.SET_TOKEN('INV_CHARS',
523                  l_invalid_chars_found,
524                  FALSE);
525 
526              FND_MESSAGE.SET_TOKEN('FIELD_NAME',
527                  p_fieldName,
528                  FALSE);
529 
530          ELSE
531 
532              l_error_string := 'Found invalid char(s) '
533                  || '''' || l_invalid_chars_found  || ''''
534                  || ' in field '
535                  || '''' || p_fieldName || ''''
536                  || ' with value '
537                  || '''' || p_fieldValue || ''''
538                  ;
539 
540              l_error_code := 'IBY_INVALID_CHARS_IN_DATA';
541              FND_MESSAGE.set_name('IBY', l_error_code);
542 
543              FND_MESSAGE.SET_TOKEN('INV_CHARS',
544                  l_invalid_chars_found,
545                  FALSE);
546 
547              FND_MESSAGE.SET_TOKEN('FIELD_NAME',
548                  p_fieldName,
549                  FALSE);
550 
551              FND_MESSAGE.SET_TOKEN('FIELD_VALUE',
552                  p_fieldValue,
553                  FALSE);
554 
555          END IF;
556 
557          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
558 	         print_debuginfo(l_module_name, l_error_string);
559 
560          END IF;
561          /*
562           * Add error code and error message to the
563           * validation errors table
564           */
565          x_docErrorRec.error_code    := l_error_code;
566          x_docErrorRec.error_message := FND_MESSAGE.get;
567 
568          IBY_VALIDATIONSETS_PUB.insertIntoErrorTable(
569              x_docErrorRec, x_docErrorTab);
570 
571      END IF;
572 
573      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
574 	     print_debuginfo(l_module_name, 'EXIT');
575 
576      END IF;
577  END checkForInvalidChars;
578 
579 /*--------------------------------------------------------------------
580  | NAME:
581  |     getChar
582  |
583  | PURPOSE:
584  |     Returns the character at a given position of a given string.
585  |     Similar to ChatAt(index) in Java.
586  |
587  |     Note that in PLSQL indexes are 1 based i.e., the very first
588  |     character in the string has index 1 (as opposed to 0 based
589  |     indexes in C and Java).
590  |
591  |     Therefore, if the given string is 'I am the walrus', then
592  |     getChar(str, 10) will return 'w'.
593  |
594  |     NULL will be returned if the index is out-of-bounds.
595  |
596  | PARAMETERS:
597  |     IN
598  |     p_string - The name  of the input field (used for logging)
599  |     p_index - The value of the input field
600  |
601  |     OUT
602  |
603  | RETURNS:
604  |
605  |     VARCHAR2(1) - the character at the given index on the given string
606  |
607  | NOTES:
608  |
609  *---------------------------------------------------------------------*/
610  FUNCTION getChar(
611          p_string      IN VARCHAR2,
612          p_index       IN VARCHAR2
613          )
614          RETURN VARCHAR2
615  IS
616  l_char VARCHAR2(1);
617  BEGIN
618 
619      l_char := SUBSTR(p_string, p_index, 1);
620      RETURN l_char;
621 
622  END getChar;
623 
624 /*--------------------------------------------------------------------
625  | NAME:
626  |     diffStrings
627  |
628  | PURPOSE:
629  |     Given two strings, this method performs a diff on them
630  |     and returns their differences.
631  |
632  |     The two args are not expected to be completely arbitary;
633  |     instead arg2 is expected to be similar to arg1 with some
634  |     differences. For this reason, both strings are expected to
635  |     be of the same length.
636  |
637  |     Whenever there are differences, the value from arg1 is added
638  |     to the diff list. The value from arg2 is ignored.
639  |
640  | PARAMETERS:
641  |     IN
642  |     p_originalString - The original string
643  |     p_compareString  - The changed string
644  |
645  |     OUT
646  |
647  | RETURNS:
648  |
649  |     VARCHAR2 - the difference between the two strings
650  |     NULL will be returned if both strings are the same
651  |
652  | NOTES:
653  |     Comparison between the two strings will only take place uptil the
654  |     length of the original string.
655  |
656  *---------------------------------------------------------------------*/
657  FUNCTION diffStrings(
658          p_originalString      IN VARCHAR2,
659          p_compareString       IN VARCHAR2
660          )
661          RETURN VARCHAR2
662  IS
663  l_orgChar      VARCHAR2(1);
664  l_compChar     VARCHAR2(1);
665  l_diffString   VARCHAR2(2000);
666  l_length       NUMBER(10);
667  BEGIN
668 
669      IF (p_originalString = p_compareString) THEN
670          RETURN NULL;
671      END IF;
672 
673      /*
674       * Compare the strings char-by-char and store the
675       * differences
676       */
677      l_diffString := '';
678      l_length := LEAST(length(p_originalString), length(p_compareString));
679 
680      FOR i in 1 .. l_length LOOP
681 
682          l_orgChar  := SUBSTR(p_originalString, i, 1);
683          l_compChar := SUBSTR(p_compareString,  i, 1);
684 
685          IF (l_orgChar <> l_compChar) THEN
686              l_diffString := l_diffString || l_orgChar;
687          END IF;
688 
689      END LOOP;
690 
691      /*
692       * Return NULL if we were unable to find
693       * any differences.
694       */
695      IF (l_diffString = '') THEN
696          l_diffString := NULL;
697      END IF;
698 
699      RETURN l_diffString;
700 
701  END diffStrings;
702 
703 /*--------------------------------------------------------------------
704  | NAME:
705  |     createErrorRecord
706  |
707  | PURPOSE:
708  |
709  | PARAMETERS:
710  |     IN
711  |
712  |     OUT
713  |
714  |
715  | RETURNS:
716  |
717  | NOTES:
718  |
719  *---------------------------------------------------------------------*/
720  PROCEDURE createErrorRecord(
721      p_trxn_type    IN IBY_TRANSACTION_ERRORS.transaction_type%TYPE,
722      p_doc_id       IN IBY_DOCS_PAYABLE_ALL.document_payable_id%TYPE,
723      p_doc_status   IN IBY_DOCS_PAYABLE_ALL.document_status%TYPE,
724      p_ca_id        IN IBY_DOCS_PAYABLE_ALL.calling_app_id%TYPE,
725      p_ca_doc_id1   IN IBY_DOCS_PAYABLE_ALL.
726                            calling_app_doc_unique_ref1%TYPE,
727      p_ca_doc_id2   IN IBY_DOCS_PAYABLE_ALL.
728                            calling_app_doc_unique_ref2%TYPE,
729      p_ca_doc_id3   IN IBY_DOCS_PAYABLE_ALL.
730                            calling_app_doc_unique_ref3%TYPE,
731      p_ca_doc_id4   IN IBY_DOCS_PAYABLE_ALL.
732                            calling_app_doc_unique_ref4%TYPE,
733      p_ca_doc_id5   IN IBY_DOCS_PAYABLE_ALL.
734                            calling_app_doc_unique_ref5%TYPE,
735      p_pp_tt_cd     IN IBY_DOCS_PAYABLE_ALL.pay_proc_trxn_type_code%TYPE,
736      x_docErrorRec  IN OUT NOCOPY IBY_TRANSACTION_ERRORS%ROWTYPE,
737      x_docTokenTab  IN OUT NOCOPY IBY_VALIDATIONSETS_PUB.trxnErrTokenTabType,
738      p_rel_doc_id   IN IBY_DOCS_PAYABLE_ALL.calling_app_doc_ref_number%TYPE   -- AWT Enh 16296267
739                            DEFAULT NULL,
740      p_error_code   IN VARCHAR2 DEFAULT NULL
741      )
742  IS
743  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME || '.createErrorRecord';
744  l_error_code   VARCHAR2(100);
745  l_error_msg    VARCHAR2(500);
746 
747  l_token_rec    IBY_TRXN_ERROR_TOKENS%ROWTYPE;
748 
749  BEGIN
750 
751      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
752 	     print_debuginfo(l_module_name, 'ENTER');
753 	     print_debuginfo(l_module_name, 'Transaction type: '   || p_trxn_type);
754 	     print_debuginfo(l_module_name, 'Transaction status: ' || p_doc_status);
755 
756      END IF;
757      x_docErrorRec.validation_set_code := 'CORE_PAYMENT_VALIDATION';
758      x_docErrorRec.transaction_type    := p_trxn_type;
759 
760      /*
761       * Fix for bug 5085226:
762       *
763       * Initialize the transaction error id to null for
764       * the error record, each time we enter this method.
765       *
766       * This prevents the previously set transaction error
767       * id from persisting in the x_docErrorRec for a
768       * new record.
769       */
770      x_docErrorRec.transaction_error_id
771                                        := NULL;
772 
773      x_docErrorRec.transaction_id      := p_doc_id;
774      x_docErrorRec.calling_app_id      := p_ca_id;
775      x_docErrorRec.calling_app_doc_unique_ref1
776                                        := p_ca_doc_id1;
777      x_docErrorRec.calling_app_doc_unique_ref2
778                                        := p_ca_doc_id2;
779      x_docErrorRec.calling_app_doc_unique_ref3
780                                        := p_ca_doc_id3;
781      x_docErrorRec.calling_app_doc_unique_ref4
782                                        := p_ca_doc_id4;
783      x_docErrorRec.calling_app_doc_unique_ref5
784                                        := p_ca_doc_id5;
785      x_docErrorRec.pay_proc_trxn_type_code
786                                        := p_pp_tt_cd;
787      x_docErrorRec.error_date          := sysdate;
788      x_docErrorRec.error_status        := TRXN_ERROR_ACTIVE;
789 
790      /*
791       * Error codes are mapped for certain document/payment
792       * statuses. Get the error code corresponding to the
793       * document/payment status.
794       */
795      IF (p_error_code IS NULL) THEN
796 
797          CASE p_doc_status
798              WHEN DOC_STATUS_CA_FAILED THEN
799                  l_error_code := 'IBY_DOC_FAILED_BY_CALL_APP';
800              WHEN DOC_STATUS_RELN_FAIL THEN
801                  l_error_code := 'IBY_DOC_FAILED_BY_RELATED_DOC';
802              WHEN DOC_STATUS_PAY_VAL_FAIL THEN
803                  l_error_code := 'IBY_DOC_FAILED_BY_PARENT_PMT';
804              WHEN DOC_STATUS_FAIL_BY_REJLVL THEN
805                  l_error_code := 'IBY_DOC_FAILED_BY_REJ_LVL';
806              WHEN PAY_STATUS_FAIL_VALID THEN
807                  l_error_code := 'IBY_PMT_FAILED_VALIDATION';
808              WHEN PAY_STATUS_CA_FAILED THEN
809                  l_error_code := 'IBY_PMT_FAILED_BY_CALL_APP';
810              WHEN PAY_STATUS_FAIL_BY_REJLVL THEN
811                  l_error_code := 'IBY_PMT_FAILED_BY_REJ_LVL';
812              ELSE
813                  /* generic error message */
814                  l_error_code := 'IBY_GENERIC_ERROR_MSG';
815          END CASE;
816 
817          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
818 	         print_debuginfo(l_module_name, 'Error code derived from '
819 	             || 'doc/pmt status: '
820 	             || l_error_code);
821          END IF;
822      ELSE
823 
824          l_error_code := p_error_code;
825 
826          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
827 	         print_debuginfo(l_module_name, 'Error code based on input param: '
828 	             || l_error_code
829 	             );
830 
831          END IF;
832      END IF;
833 
834      FND_MESSAGE.set_name('IBY', l_error_code);
835 
836      /*
837       * Error tokens are mapped for certain error messages.
838       */
839      CASE l_error_code
840          WHEN 'IBY_DOC_FAILED_BY_RELATED_DOC' THEN
841              FND_MESSAGE.SET_TOKEN('RELDOC', p_rel_doc_id, FALSE);
842              l_token_rec.token_name  := 'RELDOC';
843              l_token_rec.token_value := p_rel_doc_id;
844          WHEN 'IBY_DOC_FAILED_BY_REJ_LVL' THEN
845              FND_MESSAGE.SET_TOKEN('TRGDOC', p_rel_doc_id, FALSE);
846              l_token_rec.token_name  := 'TRGDOC';
847              l_token_rec.token_value := p_rel_doc_id;
848          WHEN 'IBY_PMT_FAILED_BY_REJ_LVL' THEN
849              FND_MESSAGE.SET_TOKEN('TRGPMT', p_rel_doc_id, FALSE);
850              l_token_rec.token_name  := 'TRGPMT';
851              l_token_rec.token_value := p_rel_doc_id;
852          ELSE
853              /* do nothing */
854              NULL;
855      END CASE;
856 
857      l_error_msg := FND_MESSAGE.get;
858 
859      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
860 	     print_debuginfo(l_module_name, 'Error message derived from error code: '
861 	         || l_error_msg);
862 
863      END IF;
864      x_docErrorRec.error_code    := l_error_code;
865      x_docErrorRec.error_message := l_error_msg;
866 
867      /*
868       * If we created a token record, add it to the token
869       * records table.
870       */
871      IF (l_token_rec.token_name IS NOT NULL) THEN
872          x_docTokenTab(x_docTokenTab.COUNT + 1) := l_token_rec;
873      END IF;
874 
875      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
876 	     print_debuginfo(l_module_name, 'EXIT');
877 
878      END IF;
879  END createErrorRecord;
880 
881 /*--------------------------------------------------------------------
882  | NAME:
883  |     createPmtErrorRecord
884  |
885  | PURPOSE:
886  |
887  | PARAMETERS:
888  |     IN
889  |
890  |     OUT
891  |
892  |
893  | RETURNS:
894  |
895  | NOTES:
896  |
897  *---------------------------------------------------------------------*/
898  PROCEDURE createPmtErrorRecord(
899      p_pmt_id        IN IBY_PAYMENTS_ALL.payment_id%TYPE,
900      p_pmt_status    IN IBY_PAYMENTS_ALL.
901                             payment_status%TYPE,
902      p_error_code    IN IBY_TRANSACTION_ERRORS.error_code%TYPE
903                            DEFAULT NULL,
904      p_error_msg     IN IBY_TRANSACTION_ERRORS.error_message%TYPE
905                            DEFAULT NULL,
906      x_docErrorRec   IN OUT NOCOPY IBY_TRANSACTION_ERRORS%ROWTYPE
907      )
908  IS
909 
910  l_module_name  VARCHAR2(200) := G_PKG_NAME || '.createPmtErrorRecord';
911 
912  BEGIN
913 
914      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
915 	     print_debuginfo(l_module_name, 'ENTER');
916 
917      END IF;
918      x_docErrorRec.validation_set_code := 'CORE_PAYMENT_VALIDATION';
919      x_docErrorRec.transaction_type    := 'PAYMENT';
920 
921      x_docErrorRec.transaction_id      := p_pmt_id;
922 
923      x_docErrorRec.error_date          := sysdate;
924      x_docErrorRec.error_status        := TRXN_ERROR_ACTIVE;
925 
926      x_docErrorRec.error_code          := p_error_code;
927      x_docErrorRec.error_message       := p_error_msg;
928 
929      x_docErrorRec.override_allowed_on_error_flag
930                                        := 'N';
931 
932      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
933 	     print_debuginfo(l_module_name, 'EXIT');
934 
935      END IF;
936  END createPmtErrorRecord;
937 
938 PROCEDURE getProfListFromProfileDrivers(
939      p_pmt_method_cd     IN IBY_DOCS_PAYABLE_ALL.payment_method_code%TYPE,
940      p_org_id            IN IBY_DOCS_PAYABLE_ALL.org_id%TYPE,
941      p_org_type          IN IBY_DOCS_PAYABLE_ALL.org_type%TYPE,
942      p_pmt_currency      IN IBY_DOCS_PAYABLE_ALL.payment_currency_code%TYPE,
943      p_int_bank_acct_id  IN IBY_DOCS_PAYABLE_ALL.internal_bank_account_id%TYPE,
944      p_profile_id       IN OUT NOCOPY IBY_DOCS_PAYABLE_ALL.payment_profile_id%TYPE,
945      p_valid_flag       OUT NOCOPY VARCHAR2
946      )
947  IS
948  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME ||
949                                              '.getProfListFromProfileDrivers';
950  l_prof_val_indx       VARCHAR2(2000);
951  l_prof_der_indx       VARCHAR2(2000);
952 
953  BEGIN
954 
955      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
956 	     print_debuginfo(l_module_name, 'ENTER');
957 
958 	     print_debuginfo(l_module_name, 'Checking for profiles '
959 	         || 'applicable for given org id '
960 	         || p_org_id
961 	         || ' and org type '
962 	         || p_org_type
963 	         || ' and payment method '
964 	         || p_pmt_method_cd
965 	         || ' and payment currency '
966 	         || p_pmt_currency
967 	         || ' and internal bank account '
968 	         || p_int_bank_acct_id
969 	         || ' combination ...'
970 	         );
971 
972 	     print_debuginfo(l_module_name, 'ENTER');
973 
974 
975      END IF;
976      IF(p_profile_id is not null) THEN
977      l_prof_val_indx := p_profile_id||'$'||p_org_id||'$'||p_org_type||'$'||p_pmt_method_cd||'$'||p_pmt_currency||'$'||p_int_bank_acct_id;
978        IF(l_prof_val_indx is not null) THEN
979            IF(l_prof_val_tbl.EXISTS(l_prof_val_indx)) THEN
980            IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
981 	           print_debuginfo(l_module_name, 'Fetching the value from Cache Structure l_prof_val_tbl' || l_prof_val_indx);
982            END IF;
983            p_valid_flag := l_prof_val_tbl(l_prof_val_indx);
984            ELSE
985            IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
986 	           print_debuginfo(l_module_name, 'Fetching the value from the DB for l_prof_val_tbl' || l_prof_val_indx);
987            END IF;
988              BEGIN
989                SELECT
990                  'Y'
991                  INTO p_valid_flag
992                  FROM
993                      IBY_APPLICABLE_PMT_PROFS app1,
994                      IBY_APPLICABLE_PMT_PROFS app2,
995                      IBY_APPLICABLE_PMT_PROFS app3,
996                      IBY_APPLICABLE_PMT_PROFS app4,
997                      IBY_SYS_PMT_PROFILES_B   sys_prof,
998                      IBY_ACCT_PMT_PROFILES_B  acct_prof
999                  WHERE
1000                      /*
1001                       * org id is a special case; since each org id has meaning
1002                       * only within an org type, we need to always use
1003                       * (org id, org type) as a combination.
1004                       *
1005                       * This means that both org id and org type need to be
1006                       * stored in the same row. In order to simplify matters,
1007                       * the org type field will be stored in the 'applicable
1008                       * value from' column wherever org id is stored.
1009                       *
1010                       * If org id is null, do not check org type - special case.
1011                       */
1012                      (app1.applicable_type_code=APL_TYPE_ORG AND
1013                          (app1.applicable_value_to IS NULL) OR
1014                          (app1.applicable_value_to=TO_CHAR(p_org_id) AND
1015                              app1.applicable_value_from=p_org_type))
1016                  AND (app2.applicable_type_code=APL_TYPE_PMT_METHOD AND
1017                          (app2.applicable_value_to=p_pmt_method_cd OR
1018                              app2.applicable_value_to IS NULL))
1019                  AND (app3.applicable_type_code=APL_TYPE_PMT_CURRENCY AND
1020                          (app3.applicable_value_to=p_pmt_currency OR
1021                              app3.applicable_value_to IS NULL))
1022                  AND (app4.applicable_type_code=APL_TYPE_INT_BANK_ACCT AND
1023                          (app4.applicable_value_to=TO_CHAR(p_int_bank_acct_id) OR
1024                              app4.applicable_value_to IS NULL))
1025                  AND
1026                      app1.system_profile_code=app2.system_profile_code
1027                  AND
1028                      app2.system_profile_code=app3.system_profile_code
1029                  AND
1030                      app3.system_profile_code=app4.system_profile_code
1031                  AND
1032                      app4.system_profile_code=app1.system_profile_code
1033                  AND
1034                      app1.system_profile_code=sys_prof.system_profile_code
1035                  AND
1036                      sys_prof.system_profile_code=acct_prof.system_profile_code(+)
1037                  /*
1038                   * Fix for bug 5929889:
1039                   *
1040                   * Filter profiles by inactive date so that we do not
1041                   * pick up end-dated profiles.
1042                   */
1043                  AND NVL(sys_prof.inactive_date, SYSDATE + 1) > SYSDATE
1044                  AND acct_prof.payment_profile_id = p_profile_id;
1045               EXCEPTION
1046                  WHEN TOO_MANY_ROWS THEN
1047                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1048 	                 print_debuginfo(l_module_name, 'Modifying the value of the p_valid_flag when the Exception is TOO_MANY_ROWS for l_prof_val_tbl');
1049                  END IF;
1050                  p_valid_flag := 'Y';
1051                  WHEN OTHERS THEN
1052                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1053 	                 print_debuginfo(l_module_name, 'Modifying the value of the p_valid_flag when the Exception is OTHERS for l_prof_val_tbl');
1054                  END IF;
1055                  p_valid_flag := 'N';
1056              END;
1057              l_prof_val_tbl(l_prof_val_indx) := p_valid_flag;
1058            END IF;
1059         END IF;
1060      ELSE
1061      l_prof_der_indx := p_org_id||'$'||p_org_type||'$'||p_pmt_method_cd||'$'||p_pmt_currency||'$'||p_int_bank_acct_id;
1062         IF(l_prof_der_indx is not null) THEN
1063            IF(l_prof_der_tbl.EXISTS(l_prof_der_indx)) THEN
1064            IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1065 	           print_debuginfo(l_module_name, 'Fetching the value from Cache Structure l_prof_der_tbl' || l_prof_der_indx);
1066            END IF;
1067            p_profile_id := l_prof_der_tbl(l_prof_der_indx).l_profile_id;
1068            p_valid_flag := l_prof_der_tbl(l_prof_der_indx).l_valid_flag;
1069            ELSE
1070            IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1071 	           print_debuginfo(l_module_name, 'Fetching the value from the DB for l_prof_der_tbl' || l_prof_der_indx);
1072            END IF;
1073              BEGIN
1074                SELECT
1075                  acct_prof.payment_profile_id, 'Y'
1076                  INTO p_profile_id, p_valid_flag
1077                  FROM
1078                      IBY_APPLICABLE_PMT_PROFS app1,
1079                      IBY_APPLICABLE_PMT_PROFS app2,
1080                      IBY_APPLICABLE_PMT_PROFS app3,
1081                      IBY_APPLICABLE_PMT_PROFS app4,
1082                      IBY_SYS_PMT_PROFILES_B   sys_prof,
1083                      IBY_ACCT_PMT_PROFILES_B  acct_prof
1084                  WHERE
1085                      /*
1086                       * org id is a special case; since each org id has meaning
1087                       * only within an org type, we need to always use
1088                       * (org id, org type) as a combination.
1089                       *
1090                       * This means that both org id and org type need to be
1091                       * stored in the same row. In order to simplify matters,
1092                       * the org type field will be stored in the 'applicable
1093                       * value from' column wherever org id is stored.
1094                       *
1095                       * If org id is null, do not check org type - special case.
1096                       */
1097                      (app1.applicable_type_code=APL_TYPE_ORG AND
1098                          (app1.applicable_value_to IS NULL) OR
1099                          (app1.applicable_value_to=TO_CHAR(p_org_id) AND
1100                              app1.applicable_value_from=p_org_type))
1101                  AND (app2.applicable_type_code=APL_TYPE_PMT_METHOD AND
1102                          (app2.applicable_value_to=p_pmt_method_cd OR
1103                              app2.applicable_value_to IS NULL))
1104                  AND (app3.applicable_type_code=APL_TYPE_PMT_CURRENCY AND
1105                          (app3.applicable_value_to=p_pmt_currency OR
1106                              app3.applicable_value_to IS NULL))
1107                  AND (app4.applicable_type_code=APL_TYPE_INT_BANK_ACCT AND
1108                          (app4.applicable_value_to=TO_CHAR(p_int_bank_acct_id) OR
1109                              app4.applicable_value_to IS NULL))
1110                  AND
1111                      app1.system_profile_code=app2.system_profile_code
1112                  AND
1113                      app2.system_profile_code=app3.system_profile_code
1114                  AND
1115                      app3.system_profile_code=app4.system_profile_code
1116                  AND
1117                      app4.system_profile_code=app1.system_profile_code
1118                  AND
1119                      app1.system_profile_code=sys_prof.system_profile_code
1120                  AND
1121                      sys_prof.system_profile_code=acct_prof.system_profile_code(+)
1122                  /*
1123                   * Fix for bug 5929889:
1124                   *
1125                   * Filter profiles by inactive date so that we do not
1126                   * pick up end-dated profiles.
1127                   */
1128                  AND NVL(sys_prof.inactive_date, SYSDATE + 1) > SYSDATE;
1129               EXCEPTION
1130                  WHEN TOO_MANY_ROWS THEN
1131                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1132 	                 print_debuginfo(l_module_name, 'Modifying the value of the p_valid_flag when the Exception is TOO_MANY_ROWS for  l_prof_der_tbl');
1133                  END IF;
1134                  p_valid_flag := 'M';
1135                  p_profile_id := -1;
1136                  WHEN OTHERS THEN
1137                  IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1138 	                 print_debuginfo(l_module_name, 'Modifying the value of the p_valid_flag when the Exception is OTHERS for  l_prof_der_tbl');
1139                  END IF;
1140                  p_valid_flag := 'N';
1141                  p_profile_id := -1;
1142              END;
1143              l_prof_der_tbl(l_prof_der_indx).l_valid_flag := p_valid_flag;
1144              l_prof_der_tbl(l_prof_der_indx).l_profile_id := p_profile_id;
1145            END IF;
1146         END IF;
1147      END IF;
1148 
1149  EXCEPTION
1150      WHEN OTHERS THEN
1151          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1152 	         print_debuginfo(l_module_name, 'Non-Fatal: Exception when '
1153 	             || 'attempting to get payment profile for given (payment '
1154 	             || 'method, org, currency, int bank acct) '
1155 	             || 'combination.'
1156 	             );
1157 	         print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
1158 	         print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
1159 
1160 	         print_debuginfo(l_module_name, 'EXIT');
1161 
1162          END IF;
1163  END getProfListFromProfileDrivers;
1164 
1165 
1166 /*--------------------------------------------------------------------
1167  | NAME:
1168  |     getProfListFromProfileDrivers
1169  |
1170  | PURPOSE:
1171  |     Derives the payment profile for the given (payment method,
1172  |     org, payment currency, internal bank acct)
1173  |     combination.
1174  |
1175  | PARAMETERS:
1176  |     IN
1177  |
1178  |     OUT
1179  |
1180  |
1181  | RETURNS:
1182  |
1183  |
1184  | NOTES:
1185  |
1186  *---------------------------------------------------------------------*/
1187  PROCEDURE getProfListFromProfileDrivers(
1188      p_pmt_method_cd     IN IBY_DOCS_PAYABLE_ALL.payment_method_code%TYPE,
1189      p_org_id            IN IBY_DOCS_PAYABLE_ALL.org_id%TYPE,
1190      p_org_type          IN IBY_DOCS_PAYABLE_ALL.org_type%TYPE,
1191      p_pmt_currency      IN IBY_DOCS_PAYABLE_ALL.payment_currency_code%TYPE,
1192      p_int_bank_acct_id  IN IBY_DOCS_PAYABLE_ALL.internal_bank_account_id%TYPE,
1193      x_profilesTab       IN OUT NOCOPY pmtProfTabType
1194      )
1195  IS
1196  l_module_name CONSTANT VARCHAR2(200) := G_PKG_NAME ||
1197                                              '.getProfListFromProfileDrivers';
1198 
1199  /*
1200   * We need to select payment profiles that are applicable to
1201   * given (payment method, org, currency, int bank account).
1202   *
1203   *
1204   *     |  Profiles      |
1205   *     |  applicable to |
1206   *     |  given pmt     |    Profiles applicable to
1207   *     |  method        |    given payment currency
1208   *     |                |     /
1209   *     |     |          |    /
1210   *     |     V          |  L
1211   *     |                |
1212   *     |----------------|--------------------------
1213   *     |/              \|            Profiles
1214   *     |                |            applicable to
1215   *     |  Intersection  |     <--    given
1216   *     |                |            org id and org type
1217   *     |\              /|
1218   *     |----------------|--------------------------
1219   *     |                |
1220   *     |                |  .__
1221   *     |                |  |\
1222   *     |                |    \
1223   *     |                |
1224   *     |                |   Profiles applicable to
1225   *     |                |   given internal bank
1226   *     |                |   account
1227   *     |                |
1228   *     |                |
1229   *
1230   * We need the intersection of (profiles applicable to
1231   * a given payment method) and (profiles applicable to
1232   * a given org) and (profiles applicable to given payment
1233   * currency) and (profiles applicable to given internal
1234   * bank account) as shown in the graphic.
1235   *
1236   * Therefore, we need to join with the IBY_APPLICABLE_PMT_PROFS
1237   * four times - once to get the profiles for the method, once to get
1238   * the profiles for the org, and once to get the profiles for the
1239   * currency etc. If we are able to get a non-null intersect for these
1240   * five queries, it means that there is a profile that matches the
1241   * (org, method, currency, bank acct) combination.
1242   *
1243   * If the 'applicable_value_to' is set to NULL, it means that the
1244   * profile is applicable to 'all orgs' | 'all methods' |
1245   * 'all formats' etc., depending upon the applicable_type_code.
1246   * Therefore, we need to factor this condition in the join.
1247   */
1248 
1249   /*
1250    * Redundant joins of the form where a=b=c=a execute faster than
1251    * where a=b=c joins. That's why this select has a redundant join.
1252    */
1253   CURSOR c_profiles(
1254              p_pmt_method_cd     IN IBY_DOCS_PAYABLE_ALL.
1255                                         payment_method_code%TYPE,
1256              p_org_id            IN IBY_DOCS_PAYABLE_ALL.org_id%TYPE,
1257              p_org_type          IN IBY_DOCS_PAYABLE_ALL.org_type%TYPE,
1258              p_pmt_currency      IN IBY_DOCS_PAYABLE_ALL.
1259                                         payment_currency_code%TYPE,
1260              p_int_bank_acct_id  IN IBY_DOCS_PAYABLE_ALL.
1261                                         internal_bank_account_id%TYPE
1262              )
1263  IS
1264  SELECT
1265      acct_prof.payment_profile_id
1266  FROM
1267      IBY_APPLICABLE_PMT_PROFS app1,
1268      IBY_APPLICABLE_PMT_PROFS app2,
1269      IBY_APPLICABLE_PMT_PROFS app3,
1270      IBY_APPLICABLE_PMT_PROFS app4,
1271      IBY_SYS_PMT_PROFILES_B   sys_prof,
1272      IBY_ACCT_PMT_PROFILES_B  acct_prof
1273  WHERE
1274      /*
1275       * org id is a special case; since each org id has meaning
1276       * only within an org type, we need to always use
1277       * (org id, org type) as a combination.
1278       *
1279       * This means that both org id and org type need to be
1280       * stored in the same row. In order to simplify matters,
1281       * the org type field will be stored in the 'applicable
1282       * value from' column wherever org id is stored.
1283       *
1284       * If org id is null, do not check org type - special case.
1285       */
1286      (app1.applicable_type_code=APL_TYPE_ORG AND
1287          (app1.applicable_value_to IS NULL) OR
1288          (app1.applicable_value_to=TO_CHAR(p_org_id) AND
1289              app1.applicable_value_from=p_org_type))
1290  AND (app2.applicable_type_code=APL_TYPE_PMT_METHOD AND
1291          (app2.applicable_value_to=p_pmt_method_cd OR
1292              app2.applicable_value_to IS NULL))
1293  AND (app3.applicable_type_code=APL_TYPE_PMT_CURRENCY AND
1294          (app3.applicable_value_to=p_pmt_currency OR
1295              app3.applicable_value_to IS NULL))
1296  AND (app4.applicable_type_code=APL_TYPE_INT_BANK_ACCT AND
1297          (app4.applicable_value_to=TO_CHAR(p_int_bank_acct_id) OR
1298              app4.applicable_value_to IS NULL))
1299  AND
1300      app1.system_profile_code=app2.system_profile_code
1301  AND
1302      app2.system_profile_code=app3.system_profile_code
1303  AND
1304      app3.system_profile_code=app4.system_profile_code
1305  AND
1306      app4.system_profile_code=app1.system_profile_code
1307  AND
1308      app1.system_profile_code=sys_prof.system_profile_code
1309  AND
1310      sys_prof.system_profile_code=acct_prof.system_profile_code(+)
1311  /*
1312   * Fix for bug 5929889:
1313   *
1314   * Filter profiles by inactive date so that we do not
1315   * pick up end-dated profiles.
1316   */
1317  AND NVL(sys_prof.inactive_date, SYSDATE + 1) > SYSDATE
1318  ;
1319 
1320  BEGIN
1321 
1322      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1323 	     print_debuginfo(l_module_name, 'ENTER');
1324 
1325 	     print_debuginfo(l_module_name, 'Checking for profiles '
1326 	         || 'applicable for given org id '
1327 	         || p_org_id
1328 	         || ' and org type '
1329 	         || p_org_type
1330 	         || ' and payment method '
1331 	         || p_pmt_method_cd
1332 	         || ' and payment currency '
1333 	         || p_pmt_currency
1334 	         || ' and internal bank account '
1335 	         || p_int_bank_acct_id
1336 	         || ' combination ...'
1337 	         );
1338 
1339 	     print_debuginfo(l_module_name, 'ENTER');
1340 
1341      END IF;
1342      OPEN  c_profiles(p_pmt_method_cd,
1343                p_org_id,
1344                p_org_type,
1345                p_pmt_currency,
1346                p_int_bank_acct_id
1347                );
1348      FETCH c_profiles BULK COLLECT INTO x_profilesTab;
1349      CLOSE c_profiles;
1350 
1351     IF (x_profilesTab.COUNT = 0) THEN
1352 
1353         IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1354 	        print_debuginfo(l_module_name, 'No applicable payment profiles '
1355 	            || 'were found.');
1356 
1357         END IF;
1358     ELSE
1359 
1360         IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1361 	        print_debuginfo(l_module_name, 'Count of applicable payment profiles: '
1362 	            || x_profilesTab.COUNT);
1363 
1364         END IF;
1365     END IF;
1366 
1367     IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1368 	    print_debuginfo(l_module_name, 'EXIT');
1369 
1370     END IF;
1371  EXCEPTION
1372      WHEN OTHERS THEN
1373          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1374 	         print_debuginfo(l_module_name, 'Non-Fatal: Exception when '
1375 	             || 'attempting to get payment profile for given (payment '
1376 	             || 'method, org, currency, int bank acct) '
1377 	             || 'combination.'
1378 	             );
1379 	         print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
1380 	         print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
1381 
1382 	         print_debuginfo(l_module_name, 'EXIT');
1383 
1384          END IF;
1385  END getProfListFromProfileDrivers;
1386 
1387 /*--------------------------------------------------------------------
1388  | NAME:
1389  |     getProfileMap
1390  |
1391  | PURPOSE:
1392  |
1393  | PARAMETERS:
1394  |     IN
1395  |
1396  |
1397  |     OUT
1398  |
1399  |
1400  | RETURNS:
1401  |
1402  | NOTES:
1403  |
1404  *---------------------------------------------------------------------*/
1405  PROCEDURE getProfileMap(
1406      x_profileMap     IN OUT NOCOPY profileIdToCodeMapTabType
1407      )
1408  IS
1409  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME || '.getProfileMap';
1410 
1411  /*
1412   * Cursor to pick up mapping between a profile id and a
1413   * profile code.
1414   */
1415  CURSOR c_profile_map
1416  IS
1417  SELECT
1418      payment_profile_id,
1419      system_profile_code
1420  FROM
1421      IBY_PAYMENT_PROFILES;
1422 
1423  BEGIN
1424 
1425      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1426 	     print_debuginfo(l_module_name, 'ENTER');
1427 
1428      END IF;
1429      /*
1430       * Pick up profile mapping.
1431       */
1432      OPEN  c_profile_map;
1433      FETCH c_profile_map BULK COLLECT INTO x_profileMap;
1434      CLOSE c_profile_map;
1435 
1436 
1437      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1438 	     print_debuginfo(l_module_name, 'Profile map contains '
1439 	         || x_profileMap.COUNT
1440 	         || ' records.'
1441 	         );
1442 
1443 	     print_debuginfo(l_module_name, 'EXIT');
1444 
1445      END IF;
1446  END getProfileMap;
1447 
1448 
1449 /*--------------------------------------------------------------------
1450  | NAME:
1451  |     getProfileCodeFromId
1452  |
1453  | PURPOSE:
1454  |
1455  | PARAMETERS:
1456  |     IN
1457  |
1458  |
1459  |     OUT
1460  |
1461  |
1462  | RETURNS:
1463  |
1464  | NOTES:
1465  |
1466  *---------------------------------------------------------------------*/
1467  FUNCTION getProfileCodeFromId(
1468      p_profile_id     IN IBY_PAY_INSTRUCTIONS_ALL.payment_profile_id%TYPE,
1469      p_profileMap     IN profileIdToCodeMapTabType
1470      ) RETURN VARCHAR2
1471  IS
1472  l_profile_code IBY_PAYMENT_PROFILES.system_profile_code%TYPE;
1473  l_profil_id_index      NUMBER(20);
1474 
1475  BEGIN
1476 
1477 
1478       /*
1479       * Adding Caching Logic to avoid database hits for the same input
1480       * combination.
1481       *
1482       */
1483       l_profil_id_index := p_profile_id;
1484 
1485       IF (l_profile_cod_tbl.EXISTS(l_profil_id_index)) THEN
1486          RETURN l_profile_cod_tbl(l_profil_id_index);
1487       END IF;
1488 
1489 
1490      IF (p_profileMap.COUNT = 0) THEN
1491          l_profile_code := NULL;
1492          RETURN l_profile_code;
1493      END IF;
1494 
1495      l_profile_code := NULL;
1496      FOR i IN p_profileMap.FIRST .. p_profileMap.LAST LOOP
1497          IF (p_profileMap(i).pmt_profile_id = p_profile_id) THEN
1498              l_profile_code := p_profileMap(i).pmt_profile_cd;
1499 
1500 	     /* Caching before exiting */
1501 	     l_profile_cod_tbl(l_profil_id_index) := l_profile_code;
1502 
1503              EXIT;
1504          END IF;
1505      END LOOP;
1506 
1507      RETURN l_profile_code;
1508 
1509  END getProfileCodeFromId;
1510 
1511 /*--------------------------------------------------------------------
1512  | NAME:
1513  |     printWrappedString
1514  |
1515  | PURPOSE:
1516  |
1517  | PARAMETERS:
1518  |     IN
1519  |
1520  |
1521  |     OUT
1522  |
1523  |
1524  | RETURNS:
1525  |
1526  | NOTES:
1527  |
1528  *---------------------------------------------------------------------*/
1529  PROCEDURE printWrappedString(
1530      p_string     IN VARCHAR2
1531      )
1532  IS
1533 
1534  l_chunk    VARCHAR2(80);
1535  l_length  NUMBER := 1;
1536 
1537  BEGIN
1538 
1539      WHILE(length(p_string) >= l_length) LOOP
1540 
1541          l_chunk := substrb(p_string, l_length, 75);
1542 
1543          l_chunk := ltrim(l_chunk);
1544          l_chunk := rtrim(l_chunk);
1545 
1546          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1547 	         print_debuginfo(' ', l_chunk);
1548 
1549          END IF;
1550          l_length := (l_length + 75);
1551 
1552      END LOOP;
1553 
1554  END printWrappedString;
1555 
1556 /*--------------------------------------------------------------------
1557  | NAME:
1558  |     inactivateOldErrors
1559  |
1560  | PURPOSE:
1561  |
1562  | PARAMETERS:
1563  |     IN
1564  |
1565  |
1566  |     OUT
1567  |
1568  |
1569  | RETURNS:
1570  |
1571  | NOTES:
1572  |
1573  *---------------------------------------------------------------------*/
1574  PROCEDURE inactivateOldErrors(
1575      p_trxn_id    IN IBY_TRANSACTION_ERRORS.transaction_id%TYPE,
1576      p_trxn_type  IN IBY_TRANSACTION_ERRORS.transaction_type%TYPE
1577      )
1578  IS
1579  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME || '.inactivateOldErrors';
1580 
1581  BEGIN
1582 
1583      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1584 	     print_debuginfo(l_module_name, 'ENTER');
1585 
1586 	     print_debuginfo(l_module_name, 'Inactivating old errors for '
1587 	         || p_trxn_type
1588 	         || ' id: '
1589 	         || p_trxn_id
1590 	         );
1591 
1592      END IF;
1593      /*
1594       * Set the error status to inactive in the IBY_TRANSACTION_ERRORS
1595       * table for all rows that contain errors against this
1596       * transaction.
1597       */
1598      UPDATE
1599          IBY_TRANSACTION_ERRORS err
1600      SET
1601          err.error_status     = 'INACTIVE',
1602          err.last_update_date = sysdate,
1603          err.last_updated_by  = fnd_global.user_id
1604      WHERE
1605          err.transaction_id   = p_trxn_id           AND
1606          err.transaction_type = p_trxn_type
1607      ;
1608 
1609      /*
1610       * Fix for bug 5742548:
1611       *
1612       * When inactivating payment errors, remember to
1613       * inactivate errors on underlying documents payable
1614       * as well.
1615       */
1616      IF (p_trxn_type = 'PAYMENT') THEN
1617 
1618          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1619 	         print_debuginfo(l_module_name, 'Inactivating old errors for '
1620 	             || 'child documents of payment id: '
1621 	             || p_trxn_id
1622 	             );
1623 
1624          END IF;
1625          UPDATE
1626              IBY_TRANSACTION_ERRORS err
1627          SET
1628              err.error_status     = 'INACTIVE',
1629              err.last_update_date = sysdate,
1630              err.last_updated_by  = fnd_global.user_id
1631          WHERE
1632              err.transaction_id   IN
1633                  (
1634                  SELECT
1635                      document_payable_id
1636                  FROM
1637                      IBY_DOCS_PAYABLE_ALL
1638                  WHERE
1639                      payment_id = p_trxn_id
1640                  )
1641              AND
1642              err.transaction_type = 'DOCUMENT_PAYABLE'
1643          ;
1644 
1645      END IF;
1646 
1647      /*
1648       * Reset the transaction status to a success / neutral
1649       * status. The transaction status will get updated to a
1650       * failure status in case the transaction fails validation
1651       * later.
1652       */
1653      IF (p_trxn_type = 'DOCUMENT_PAYABLE') THEN
1654 
1655          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1656 	         print_debuginfo(l_module_name, 'Resetting status of doc'
1657 	             || ' id: '
1658 	             || p_trxn_id
1659 	             || ' to '
1660 	             || DOC_STATUS_VALIDATED
1661 	             );
1662 
1663          END IF;
1664          UPDATE
1665              IBY_DOCS_PAYABLE_ALL doc
1666          SET
1667              doc.document_status = DOC_STATUS_VALIDATED
1668          WHERE
1669              doc.document_payable_id = p_trxn_id
1670          ;
1671 
1672      ELSIF (p_trxn_type = 'PAYMENT') THEN
1673 
1674          IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1675 	         print_debuginfo(l_module_name, 'Resetting status of pmt'
1676 	             || ' id: '
1677 	             || p_trxn_id
1678 	             || ' to '
1679 	             || PAY_STATUS_CREATED
1680 	             );
1681 
1682          END IF;
1683          UPDATE
1684              IBY_PAYMENTS_ALL pmt
1685          SET
1686              pmt.payment_status = PAY_STATUS_CREATED
1687          WHERE
1688              pmt.payment_id = p_trxn_id
1689          ;
1690 
1691      END IF;
1692 
1693      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1694 	     print_debuginfo(l_module_name, 'EXIT');
1695 
1696      END IF;
1697      /*
1698       * Any exceptions that occur in this method are non-fatal.
1699       */
1700      EXCEPTION
1701          WHEN OTHERS THEN
1702 
1703              IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1704 	             print_debuginfo(l_module_name, 'Non Fatal: Exception occured '
1705 	                 || 'when attempting to update error status to inactive '
1706 	                 || 'for transaction.'
1707 	                 );
1708 
1709 	             print_debuginfo(l_module_name, 'SQL code: '   || SQLCODE);
1710 	             print_debuginfo(l_module_name, 'SQL err msg: '|| SQLERRM);
1711 
1712 	             print_debuginfo(l_module_name, 'EXIT');
1713 
1714              END IF;
1715  END inactivateOldErrors;
1716 
1717  /*--------------------------------------------------------------------
1718  | NAME:
1719  |     resetPaymentErrors
1720  |
1721  | PURPOSE:
1722  |
1723  | PARAMETERS:
1724  |     IN
1725  |
1726  |
1727  |     OUT
1728  |
1729  |
1730  | RETURNS:
1731  |
1732  | NOTES:
1733  |
1734  *---------------------------------------------------------------------*/
1735  PROCEDURE resetPaymentErrors(
1736      p_payment_request_id  IN IBY_PAY_SERVICE_REQUESTS.
1737                                   payment_service_request_id%TYPE
1738      )
1739  IS
1740  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME || '.resetPaymentErrors';
1741 
1742  BEGIN
1743 
1744      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1745 	     print_debuginfo(l_module_name, 'ENTER');
1746 
1747      END IF;
1748      /*
1749       * STEP 1:
1750       *
1751       * Delete the existing errors stored against the payments
1752       * of the PPR.
1753       *
1754       * We are going to revalidate these payments, so old errors
1755       * need not be persisted at this point.
1756       */
1757      DELETE
1758          IBY_TRANSACTION_ERRORS err
1759      WHERE
1760          err.transaction_type = 'PAYMENT' AND
1761          err.transaction_id IN
1762          (
1763            SELECT
1764                payment_id
1765            FROM
1766                IBY_PAYMENTS_ALL
1767            WHERE
1768                payment_service_request_id = p_payment_request_id AND
1769                payment_status IN
1770                (
1771                PAY_STATUS_CREATED,
1772                PAY_STATUS_MODIFIED,
1773                PAY_STATUS_FAIL_VALID
1774                )
1775          )
1776      ;
1777 
1778      /*
1779       * STEP 2:
1780       *
1781       * Delete existing errors against documents that
1782       * were failed because their parent payment
1783       * failed validation.
1784       *
1785       * Fix for bug 5742548:
1786       *
1787       * When deleting payment errors, remember to
1788       * delete errors on underlying documents payable
1789       * as well.
1790       */
1791      DELETE
1792          IBY_TRANSACTION_ERRORS err
1793      WHERE
1794          err.transaction_type = 'DOCUMENT_PAYABLE' AND
1795          err.transaction_id IN
1796          (
1797            SELECT
1798                docs.document_payable_id
1799            FROM
1800                IBY_DOCS_PAYABLE_ALL docs
1801            WHERE
1802                docs.document_status = DOC_STATUS_PAY_VAL_FAIL AND
1803                docs.payment_service_request_id = p_payment_request_id
1804          )
1805      ;
1806 
1807 
1808      /*
1809       * STEP 3:
1810       *
1811       * Reset the status of payments that are to be re-validated to
1812       * 'CREATED'.
1813       */
1814      UPDATE
1815          IBY_PAYMENTS_ALL
1816      SET
1817          payment_status = PAY_STATUS_CREATED
1818      WHERE
1819          payment_service_request_id = p_payment_request_id AND
1820          payment_status IN
1821          (
1822           PAY_STATUS_MODIFIED,
1823           PAY_STATUS_FAIL_VALID
1824          )
1825      ;
1826 
1827      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1828 	     print_debuginfo(l_module_name, 'EXIT');
1829 
1830      END IF;
1831  END resetPaymentErrors;
1832 
1833 
1834 /*--------------------------------------------------------------------
1835  | NAME:
1836  |     resetDocumentErrors
1837  |
1838  | PURPOSE:
1839  |
1840  | PARAMETERS:
1841  |     IN
1842  |
1843  |
1844  |     OUT
1845  |
1846  |
1847  | RETURNS:
1848  |
1849  | NOTES:
1850  |
1851  *---------------------------------------------------------------------*/
1852  PROCEDURE resetDocumentErrors(
1853      p_payment_request_id  IN IBY_PAY_SERVICE_REQUESTS.
1854                                   payment_service_request_id%TYPE
1855      )
1856  IS
1857  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME || '.resetDocumentErrors';
1858 
1859  BEGIN
1860 
1861      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1862 	     print_debuginfo(l_module_name, 'ENTER');
1863 
1864      END IF;
1865      /*
1866       * STEP 1:
1867       *
1868       * Delete existing errors against documents payable that
1869       * are to be re-validated
1870       */
1871      DELETE
1872          IBY_TRANSACTION_ERRORS err
1873      WHERE
1874          err.transaction_type = 'DOCUMENT_PAYABLE' AND
1875          err.transaction_id IN
1876          (
1877            SELECT
1878                document_payable_id
1879            FROM
1880                IBY_DOCS_PAYABLE_ALL
1881            WHERE
1882                payment_service_request_id = p_payment_request_id AND
1883                document_status = DOC_STATUS_FAIL_VALID
1884          )
1885      ;
1886 
1887      /*
1888       * Reset the status of documents that are to be re-validated to
1889       * 'VALIDATED'.
1890       */
1891      UPDATE
1892          IBY_DOCS_PAYABLE_ALL
1893      SET
1894          document_status = DOC_STATUS_VALIDATED
1895      WHERE
1896          payment_service_request_id = p_payment_request_id AND
1897          document_status = DOC_STATUS_FAIL_VALID
1898      ;
1899 
1900      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1901 	     print_debuginfo(l_module_name, 'EXIT');
1902 
1903      END IF;
1904  END resetDocumentErrors;
1905 
1906 /*--------------------------------------------------------------------
1907  | NAME:
1908  |     resetPaymentInstructionErrors
1909  |
1910  | PURPOSE:
1911  |
1912  | PARAMETERS:
1913  |     IN
1914  |
1915  |
1916  |     OUT
1917  |
1918  |
1919  | RETURNS:
1920  |
1921  | NOTES:
1922  |
1923  *---------------------------------------------------------------------*/
1924  PROCEDURE resetPaymentInstructionErrors(
1925      p_instr_id  IN IBY_PAY_INSTRUCTIONS_ALL.
1926                         payment_instruction_id%TYPE
1927      )
1928  IS
1929  l_module_name  CONSTANT VARCHAR2(200) := G_PKG_NAME || '.resetPaymentInstructionErrors';
1930 
1931  BEGIN
1932 
1933      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1934 	     print_debuginfo(l_module_name, 'ENTER');
1935 
1936      END IF;
1937      /*
1938       * Delete existing errors against the payment instruction
1939       * that is to be re-validated
1940       *
1941       * There is no need to delete the errors against any
1942       * child elements (like payments) etc. because these
1943       * are untouched by the PICP.
1944       */
1945      DELETE
1946          IBY_TRANSACTION_ERRORS err
1947      WHERE
1948          err.transaction_type = 'PAYMENT_INSTRUCTION' AND
1949          err.transaction_id = p_instr_id
1950      ;
1951 
1952      IF ( G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1953 	     print_debuginfo(l_module_name, 'EXIT');
1954 
1955      END IF;
1956  END resetPaymentInstructionErrors;
1957 
1958 END IBY_BUILD_UTILS_PKG;