DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_ENCUMBRANCE_PREPROCESSING

Source


1 PACKAGE BODY PO_ENCUMBRANCE_PREPROCESSING AS
2 -- $Header: POXENC1B.pls 120.15.12010000.3 2008/11/24 11:41:47 rojain ship $
3 
4 
5 -------------------------------------------------------------------------------
6 -- Private package exceptions
7 -------------------------------------------------------------------------------
8 
9 -- encumbrance validation exceptions:
10 
11 g_INVALID_CALL_EXC_CODE          CONSTANT
12    NUMBER
13    := 1
14    ;
15 
16 g_ENC_VALIDATION_EXC_CODE        CONSTANT
17    NUMBER
18    := 2
19    ;
20 
21 g_SUBMISSION_CHECK_EXC_CODE      CONSTANT
22    NUMBER
23    := 3
24    ;
25 
26 g_POPULATE_ENC_GT_EXC            EXCEPTION;
27 
28 -------------------------------------------------------------------------------
29 -- Private package constants
30 -------------------------------------------------------------------------------
31 
32 -- Logging / debugging
33 g_pkg_name                       CONSTANT
34    VARCHAR2(30)
35    := 'PO_ENCUMBRANCE_PREPROCESSING'
36    ;
37 g_log_head                       CONSTANT
38    VARCHAR2(50)
39    := 'po.plsql.' || g_pkg_name || '.'
40    ;
41 
42 -- Read the profile option that enables/disables the debug log
43 g_fnd_debug  VARCHAR2(1) := NVL(FND_PROFILE.VALUE('AFLOG_ENABLED'),'N');
44 g_debug_stmt BOOLEAN := PO_DEBUG.is_debug_stmt_on;
45 g_debug_unexp BOOLEAN := PO_DEBUG.is_debug_unexp_on;
46 
47 
48 -- encumbrance actions
49 g_action_RESERVE       CONSTANT   VARCHAR2(30)
50    := PO_DOCUMENT_FUNDS_PVT.g_action_RESERVE;
51 
52 g_action_UNRESERVE     CONSTANT   VARCHAR2(30)
53    := PO_DOCUMENT_FUNDS_PVT.g_action_UNRESERVE;
54 
55 g_action_ADJUST        CONSTANT   VARCHAR2(30)
56    := PO_DOCUMENT_FUNDS_PVT.g_action_ADJUST;
57 
58 g_action_REQ_SPLIT               CONSTANT
59    VARCHAR2(30)
60    := PO_DOCUMENT_FUNDS_PVT.g_action_REQ_SPLIT
61    ;
62 g_action_CANCEL        CONSTANT   VARCHAR2(30)
63    := PO_DOCUMENT_FUNDS_PVT.g_action_CANCEL;
64 
65 g_action_FINAL_CLOSE   CONSTANT   VARCHAR2(30)
66    := PO_DOCUMENT_FUNDS_PVT.g_action_FINAL_CLOSE;
67 
68 g_action_UNDO_FINAL_CLOSE CONSTANT VARCHAR2(30)
69    := PO_DOCUMENT_FUNDS_PVT.g_action_UNDO_FINAL_CLOSE;
70 
71 g_action_REJECT        CONSTANT   VARCHAR2(30)
72    := PO_DOCUMENT_FUNDS_PVT.g_action_REJECT;
73 
74 g_action_RETURN        CONSTANT   VARCHAR2(30)
75    := PO_DOCUMENT_FUNDS_PVT.g_action_RETURN;
76 
77 g_action_CBC_RESERVE   CONSTANT   VARCHAR2(30)
78    := PO_DOCUMENT_FUNDS_PVT.g_action_CBC_RESERVE;
79 
80 g_action_CBC_UNRESERVE CONSTANT   VARCHAR2(30)
81    := PO_DOCUMENT_FUNDS_PVT.g_action_CBC_UNRESERVE;
82 
83 g_action_INVOICE_CANCEL CONSTANT  VARCHAR2(30)
84    := PO_DOCUMENT_FUNDS_PVT.g_action_INVOICE_CANCEL;
85 
86 g_action_CR_MEMO_CANCEL CONSTANT  VARCHAR2(30)
87    := PO_DOCUMENT_FUNDS_PVT.g_action_CR_MEMO_CANCEL;
88 
89 
90 -- doc types
91 g_doc_type_REQUISITION           CONSTANT
92    PO_DOCUMENT_TYPES.document_type_code%TYPE
93    := PO_DOCUMENT_FUNDS_PVT.g_doc_type_REQUISITION
94    ;
95 g_doc_type_PO                    CONSTANT
96    PO_DOCUMENT_TYPES.document_type_code%TYPE
97    := PO_DOCUMENT_FUNDS_PVT.g_doc_type_PO
98    ;
99 g_doc_type_PA                    CONSTANT
100    PO_DOCUMENT_TYPES.document_type_code%TYPE
101    := PO_DOCUMENT_FUNDS_PVT.g_doc_type_PA
102    ;
103 g_doc_type_RELEASE               CONSTANT
104    PO_DOCUMENT_TYPES.document_type_code%TYPE
105    := PO_DOCUMENT_FUNDS_PVT.g_doc_type_RELEASE
106    ;
107 g_doc_type_MIXED_PO_RELEASE      CONSTANT
108    PO_DOCUMENT_TYPES.document_type_code%TYPE
109    := PO_DOCUMENT_FUNDS_PVT.g_doc_type_MIXED_PO_RELEASE
110    ;
111 
112 
113 -- doc subtypes
114 g_doc_subtype_STANDARD           CONSTANT
115    PO_HEADERS_ALL.type_lookup_code%TYPE
116    := PO_DOCUMENT_FUNDS_PVT.g_doc_subtype_STANDARD
117    ;
118 g_doc_subtype_PLANNED            CONSTANT
119    PO_HEADERS_ALL.type_lookup_code%TYPE
120    := PO_DOCUMENT_FUNDS_PVT.g_doc_subtype_PLANNED
121    ;
122 g_doc_subtype_BLANKET            CONSTANT
123    PO_RELEASES_ALL.release_type%TYPE
124    := PO_DOCUMENT_FUNDS_PVT.g_doc_subtype_BLANKET
125    ;
126 g_doc_subtype_SCHEDULED          CONSTANT
127    PO_RELEASES_ALL.release_type%TYPE
128    := PO_DOCUMENT_FUNDS_PVT.g_doc_subtype_SCHEDULED
129    ;
130 g_doc_subtype_MIXED_PO_RELEASE   CONSTANT
131    PO_HEADERS_ALL.type_lookup_code%TYPE
132    := PO_DOCUMENT_FUNDS_PVT.g_doc_subtype_MIXED_PO_RELEASE
133    ;
134 
135 
136 -- doc levels
137 g_doc_level_HEADER               CONSTANT
138    VARCHAR2(25)
139    := PO_DOCUMENT_FUNDS_PVT.g_doc_level_HEADER
140    ;
141 g_doc_level_LINE                 CONSTANT
142    VARCHAR2(25)
143    := PO_DOCUMENT_FUNDS_PVT.g_doc_level_LINE
144    ;
145 g_doc_level_SHIPMENT             CONSTANT
146    VARCHAR2(25)
147    := PO_DOCUMENT_FUNDS_PVT.g_doc_level_SHIPMENT
148    ;
149 g_doc_level_DISTRIBUTION         CONSTANT
150    VARCHAR2(25)
151    := PO_DOCUMENT_FUNDS_PVT.g_doc_level_DISTRIBUTION
152    ;
153 
154 
155 -- distribution types
156 g_dist_type_STANDARD             CONSTANT
157    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
158    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_STANDARD
159    ;
160 g_dist_type_PLANNED              CONSTANT
161    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
162    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_PLANNED
163    ;
164 g_dist_type_SCHEDULED            CONSTANT
165    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
166    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_SCHEDULED
167    ;
168 g_dist_type_BLANKET              CONSTANT
169    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
170    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_BLANKET
171    ;
172 g_dist_type_AGREEMENT            CONSTANT
173    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
174    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_AGREEMENT
175    ;
176 g_dist_type_REQUISITION          CONSTANT
177    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
178    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_REQUISITION
179    ;
180 g_dist_type_MIXED_PO_RELEASE     CONSTANT
181    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
182    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_MIXED_PO_RELEASE
183    ;
184 g_dist_type_PREPAYMENT           CONSTANT
185    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
186    := PO_DOCUMENT_FUNDS_PVT.g_dist_type_PREPAYMENT
187    ;
188 
189 -- parameter values
190 g_parameter_YES                  CONSTANT
191    VARCHAR2(1)
192    := PO_DOCUMENT_FUNDS_PVT.g_parameter_YES
193    ;
194 g_parameter_NO                   CONSTANT
195    VARCHAR2(1)
196    := PO_DOCUMENT_FUNDS_PVT.g_parameter_NO
197    ;
198 g_parameter_USE_PROFILE          CONSTANT
199    VARCHAR2(1)
200    := PO_DOCUMENT_FUNDS_PVT.g_parameter_USE_PROFILE
201    ;
202 
203 
204 -- closed codes
205 g_clsd_FINALLY_CLOSED            CONSTANT
206    PO_HEADERS_ALL.closed_code%TYPE
207    := 'FINALLY CLOSED'
208    ;
209 g_clsd_OPEN                      CONSTANT
210    PO_HEADERS_ALL.closed_code%TYPE
211    := 'OPEN'
212    ;
213 
214 
215 -- source type codes
216 g_src_INVENTORY                  CONSTANT
217    PO_REQUISITION_LINES_ALL.source_type_code%TYPE
218    := 'INVENTORY'
219    ;
220 
221 
222 -- order type lookup codes
223 g_order_type_FIXED_PRICE         CONSTANT
224    PO_LINE_TYPES_B.order_type_lookup_code%TYPE
225    := 'FIXED PRICE'
226    ;
227 g_order_type_RATE                CONSTANT
228    PO_LINE_TYPES_B.order_type_lookup_code%TYPE
229    := 'RATE'
230    ;
231 
232 
233 -- p_main_or_backing
234 g_MAIN                           CONSTANT
235    VARCHAR2(10)
236    := 'MAIN'
237    ;
238 g_BACKING                        CONSTANT
239    VARCHAR2(10)
240    := 'BACKING'
241    ;
242 
243 
244 g_adj_status_OLD	CONSTANT varchar2(10):= 'OLD';
245 g_adj_status_NEW	CONSTANT varchar2(10):= 'NEW';
246 
247 g_je_category_Requisitions CONSTANT varchar2(30):= 'Requisitions';
248 g_je_category_Purchases    CONSTANT varchar2(30):= 'Purchases';
249 
250 g_reference1_REQ    CONSTANT varchar2(5):= 'REQ';
251 g_reference1_PA     CONSTANT varchar2(5):= 'PA';
252 g_reference1_PO     CONSTANT varchar2(5):= 'PO';
253 g_reference1_REL    CONSTANT varchar2(5):= 'PO'; --bug 3426101
254 
255 g_reference6_GMSIP  CONSTANT varchar2(10):= 'GMSIP';
256 g_reference6_SRCDOC CONSTANT varchar2(10):= 'SRCDOC';
257 
258 g_roll_logic_NONE     CONSTANT varchar2(10):= 'NONE';
259 g_roll_logic_FORWARD  CONSTANT varchar2(10):= 'FORWARD';
260 g_roll_logic_BACKWARD CONSTANT varchar2(10):= 'BACKWARD';
261 
262 g_column_AMOUNT_TO_ENCUMBER CONSTANT varchar2(30):= 'AMOUNT_TO_ENCUMBER';
263 g_column_AMT_CLOSED	    CONSTANT varchar2(30):= 'AMT_CLOSED';
264 g_column_PRE_ROUND_AMT	    CONSTANT varchar2(30):= 'PRE_ROUND_AMT';
265 
266 g_date_format   CONSTANT varchar2(25) := 'YYYY/MM/DD';
267 
268 -- result classifications
269 g_result_SUCCESS  CONSTANT PO_ENCUMBRANCE_GT.result_type%TYPE
270 	:= PO_DOCUMENT_FUNDS_PVT.g_result_SUCCESS;
271 
272 g_result_WARNING  CONSTANT PO_ENCUMBRANCE_GT.result_type%TYPE
273 	:= PO_DOCUMENT_FUNDS_PVT.g_result_WARNING;
274 
275 g_result_ERROR    CONSTANT PO_ENCUMBRANCE_GT.result_type%TYPE
276 	:= PO_DOCUMENT_FUNDS_PVT.g_result_ERROR;
277 
278 --note: this classification currently maps to Warning, but is
279 --given a seperate label so as to easily identify this condition
280 g_result_NOT_PROCESSED  CONSTANT PO_ENCUMBRANCE_GT.result_type%TYPE
281 	:= PO_DOCUMENT_FUNDS_PVT.g_result_WARNING;
282 
283 
284 -- doc state check results
285 g_doc_state_valid_YES            CONSTANT
286    VARCHAR2(1)
287    := 'Y'
288    ;
289 g_doc_state_valid_NO             CONSTANT
290    VARCHAR2(1)
291    := 'N'
292    ;
293 
294 
295 -------------------------------------------------------------------------------
296 -- Forward procedure declarations
297 -------------------------------------------------------------------------------
298 
299 PROCEDURE initialize_encumbrance_gt(
300    p_use_enc_gt_flag                IN             VARCHAR2
301 );
302 
303 PROCEDURE get_distributions(
304    p_action                         IN             VARCHAR2
305 ,  p_check_only_flag                IN             VARCHAR2
306 ,  p_distribution_type              IN             VARCHAR2
307 ,  p_main_or_backing                IN             VARCHAR2
308 ,  p_doc_level                      IN             VARCHAR2
309 ,  p_doc_level_id                   IN             NUMBER
310 ,  p_use_enc_gt_flag                IN             VARCHAR2
311 ,  p_ap_budget_account_id           IN             NUMBER
312 ,  p_possibility_check_flag         IN             VARCHAR2
313 ,  p_cbc_flag                       IN             VARCHAR2
314 ,  x_count                          OUT NOCOPY     NUMBER
315 );
316 
317 PROCEDURE remove_unnecessary_dists(
318    p_action                         IN             VARCHAR2
319 ,  p_cbc_flag                       IN             VARCHAR2
320 );
321 
322 PROCEDURE update_encumbrance_gt(
323    p_action                         IN             VARCHAR2
324 ,  p_distribution_type              IN             VARCHAR2
325 ,  p_main_or_backing                IN             VARCHAR2
326 ,  p_origin_seq_num_tbl             IN             po_tbl_number
327 ,  p_backing_dist_id_tbl            IN             po_tbl_number
328 ,  p_ap_budget_account_id           IN             NUMBER
329 ,  x_count                          OUT NOCOPY     NUMBER
330 );
331 
332 PROCEDURE lock_backing_distributions(
333    p_distribution_type              IN             VARCHAR2
334 );
335 
336 PROCEDURE filter_backing_distributions(
337    p_action                         IN             VARCHAR2
338 ,  p_distribution_type              IN             VARCHAR2
339 ,  x_dist_id_tbl                    OUT NOCOPY     po_tbl_number
340 ,  x_origin_seq_num_tbl             OUT NOCOPY     po_tbl_number
341 );
342 
343 PROCEDURE check_doc_state(
344    p_action                         IN             VARCHAR2
345 ,  p_doc_type                       IN             VARCHAR2
346 ,  p_doc_subtype                    IN             VARCHAR2
347 ,  p_doc_level                      IN             VARCHAR2
348 ,  p_doc_level_id_tbl               IN             po_tbl_number
349 ,  x_valid_state_flag               OUT NOCOPY     VARCHAR2
350 );
351 
352 PROCEDURE get_period_info(
353    p_action              IN VARCHAR2
354 ,  p_set_of_books_id     IN NUMBER
355 ,  p_override_date       IN DATE
356 ,  p_try_dist_date_flag  IN VARCHAR2
357 ,  p_partial_flag        IN VARCHAR2
358 );
359 
360 PROCEDURE find_open_period(
361    p_set_of_books_id    IN  NUMBER
362 ,  p_try_dist_date_flag IN  VARCHAR2
363 ,  p_override_date      IN  DATE
364 ,  p_override_attempt   IN  VARCHAR2
365 ,  p_roll_logic_used    IN  VARCHAR2
366 ,  x_missing_date_flag  OUT NOCOPY VARCHAR2
367 );
368 
369 PROCEDURE get_amounts(
370    p_action                IN   VARCHAR2
371 ,  p_doc_type              IN   VARCHAR2
372 ,  p_doc_subtype           IN   VARCHAR2
373 ,  p_currency_code_func    IN   VARCHAR2
374 ,  p_ap_reinstated_enc_amt IN   NUMBER
375 ,  p_ap_cancelled_qty      IN   NUMBER
376 );
377 
378 PROCEDURE get_initial_amounts(
379    p_action               IN  VARCHAR2
380 ,  p_doc_type             IN  VARCHAR2
381 ,  p_doc_subtype          IN  VARCHAR2
382 ,  p_currency_code_func   IN  VARCHAR2
383 ,  p_min_acct_unit_func   IN  NUMBER
384 ,  p_cur_precision_func   IN  NUMBER
385 );
386 
387 PROCEDURE get_main_doc_amts(
388    p_action                 IN  VARCHAR2
389 ,  p_doc_type               IN  VARCHAR2
390 ,  p_doc_subtype            IN  VARCHAR2
391 ,  p_ap_reinstated_enc_amt  IN  NUMBER
392 ,  p_ap_cancelled_qty       IN  NUMBER
393 );
394 
395 PROCEDURE get_backing_doc_amts(
396    p_action               IN  VARCHAR2
397 ,  p_doc_type             IN  VARCHAR2
398 ,  p_doc_subtype          IN  VARCHAR2
399 ,  p_currency_code_func   IN  VARCHAR2
400 ,  p_min_acct_unit_func   IN  NUMBER
401 ,  p_cur_precision_func   IN  NUMBER
402 ,  p_ap_cancelled_qty     IN  NUMBER
403 ,  p_ap_amt_billed_change IN  NUMBER
404 );
405 
406 PROCEDURE get_final_amounts(
407    p_action                IN  VARCHAR2
408 ,  p_doc_type              IN  VARCHAR2
409 ,  p_doc_subtype           IN  VARCHAR2
410 ,  p_currency_code_func    IN  VARCHAR2
411 ,  p_min_acct_unit_func    IN  NUMBER
412 ,  p_cur_precision_func    IN  NUMBER
413 ,  p_ap_reinstated_enc_amt IN  NUMBER
414 ,  p_is_complex_work_po    IN  BOOLEAN --<Complex Work R12>
415 );
416 
417 PROCEDURE round_and_convert_amounts(
418    p_action              IN  VARCHAR2
419 ,  p_currency_code_func  IN  VARCHAR2
420 ,  p_min_acct_unit_func  IN  NUMBER
421 ,  p_cur_precision_func  IN  NUMBER
422 ,  p_column_to_use       IN  VARCHAR2
423 );
424 
425 PROCEDURE check_backing_pa_amounts(
426    p_action        IN   VARCHAR2
427 );
428 
429 PROCEDURE correct_backing_pa_amounts(
430    p_current_pa_dist_id   IN  NUMBER
431 ,  p_start_row            IN  NUMBER
432 ,  p_end_row              IN  NUMBER
433 ,  p_running_total        IN  NUMBER
434 ,  p_amt_to_enc_func      IN  NUMBER
435 ,  p_unencumbered_amt     IN  NUMBER
436 ,  p_pa_sequence_num_tbl  IN  po_tbl_number
437 ,  p_pa_multiplier_tbl    IN  po_tbl_number
438 ,  x_pa_amount_tbl        IN OUT NOCOPY po_tbl_number
439 ,  x_changed_amounts_flag OUT NOCOPY VARCHAR2
440 );
441 
442 --<Complex Work R12 START>
443 PROCEDURE set_complex_work_req_amounts(
444    p_action        IN   VARCHAR2
445 );
446 
447 PROCEDURE correct_backing_req_amounts(
448   p_req_dist_id           IN NUMBER
449 , p_max_total_amount      IN NUMBER
450 , p_current_total_amount  IN NUMBER
451 );
452 --<Complex Work R12 END>
453 
454 PROCEDURE get_gl_references(
455    p_action                IN VARCHAR2
456 ,  p_cbc_flag              IN VARCHAR2
457 ,  p_req_encumb_type_id    IN NUMBER
458 ,  p_po_encumb_type_id     IN NUMBER
459 ,  p_invoice_id            IN NUMBER
460 );
461 
462 --<SLA R12 added new procedure>
463 PROCEDURE update_amounts(
464   p_action        IN   VARCHAR2,
465   p_currency_code_func IN VARCHAR2
466 );
467 
468 -------------------------------------------------------------------------------
469 -- Procedure definitions
470 -------------------------------------------------------------------------------
471 
472 --------------------------------------------------------------------------------
473 --Start of Comments
474 --Name: get_all_distributions
475 --Pre-reqs:
476 --  The correct encumbrance should be on for the document type that is
477 --    being passed.
478 --  For a non-check only action, if the data has already been populated
479 --    in the encumbrance table, the headers and distributions should have
480 --    been locked before the data was loaded into the encumbrance table.
481 --  For POs with backing GAs, the org context of the PO must be set
482 --    in order to correctly determine whether or not there needs to
483 --    be a backing entry for the GA.
484 --Modifies:
485 --  PO_ENCUMBRANCE_GT
486 --Locks:
487 --  PO_REQUISITION_HEADERS_ALL
488 --  PO_REQ_DISTRIBUTIONS_ALL
489 --  PO_HEADERS_ALL
490 --  PO_RELEASES_ALL
491 --  PO_DISTRIBUTIONS_ALL
492 --Function:
493 --  This procedure populates the global temp table PO_ENCUMBRANCE_GT
494 --  with all of the information required for each distribution that has any
495 --  encumbrance impact.
496 --  It will either retrieve the information from the document tables for
497 --  the given doc ids or use what has already been populated in the
498 --  encumbrance table for the main doc.
499 --  It retrieves backing doc distributions from the transaction tables.
500 --Parameters:
501 --IN:
502 --p_action
503 --  Specifies the action that is being taken on the document.
504 --  Use the g_<action> variables (<action> = RESERVE, UNRESERVE, ADJUST, etc.).
505 --p_check_only_flag
506 --  Indicates whether or not to lock the main document
507 --  headers and distributions if given a doc id for the main document,
508 --  and indicates whether or not to lock the backing distributions
509 --    g_parameter_NO    lock them
510 --    g_parameter_YES   don't lock them
511 --p_doc_type
512 --  Document type.  Use the g_doc_type_<> variables, where <> is:
513 --    REQUISITION
514 --    PA
515 --    PO
516 --    RELEASE
517 --    MIXED_PO_RELEASE  - supported only for Adjust
518 --p_doc_subtype
519 --  The document subtype.  Use the g_doc_subtype_<> variables:
520 --    STANDARD          Standard PO
521 --    PLANNED           Planned PO
522 --    BLANKET           Blanket Release, Blanket Agreement, Global Agreement
523 --    SCHEDULED         Scheduled Release
524 --    MIXED_PO_RELEASE  supported only for Adjust
525 --  This parameter is not checked for requisitions.
526 --p_doc_level
527 --  The type of ids that are being passed.  Use g_doc_level_<>
528 --    HEADER
529 --    LINE
530 --    SHIPMENT
531 --    DISTRIBUTION
532 --  If the encumbrance table has already been populated (Adjust), use NULL.
533 --p_doc_level_id
534 --  Id of the doc level type on which the action is being taken.
535 --  If the encumbrance table has already been populated, use NULL.
536 --p_use_enc_gt_flag
537 --  Indicates whether or not the data has already been populated
538 --  in the encumbrance table.
539 --    g_parameter_NO    remove whatever was in the encumbrance table,
540 --                         and retrieve the data via the doc ids
541 --    g_parameter_YES   the main document data has already been populated
542 --                         in the encumbrance table, so trust that
543 --p_get_backing_docs_flag
544 --  Indicates whether to even check if eligible backing docs exist.
545 --  Certain actions/conditions require that we never operate on backing docs
546 --  VALUES: g_parameter_YES, g_parameter_NO
547 --p_ap_budget_account_id
548 --  Used by the invoice/credit memo cancel actions.  The budget account
549 --  id we use must be the same as the budget account passed in by AP
550 --p_possibility_check_flag
551 --  Used to indicate whether or not this procedure is being used to determine
552 --  the ability to take an action on the document.
553 --    g_parameter_NO    not simply a possibility check
554 --    g_parameter_YES   possibility check only, do not bother
555 --                         to polish the encumbrance table
556 --p_cbc_flag
557 --  Indicates whether or not to process approved rows of a PO/Release
558 --  during a RESERVE.
559 --    g_parameter_YES - process the approved rows
560 --    g_parameter_NO  - ignore approved rows
561 --OUT:
562 --x_count
563 --  The number of rows that were added (or cleaned up, if
564 --  p_use_enc_gt_flag = YES) to the encumbrance table due to this call.
565 --Testing:
566 --
567 --End of Comments
568 -------------------------------------------------------------------------------
569 PROCEDURE get_all_distributions(
570    p_action                         IN             VARCHAR2
571 ,  p_check_only_flag                IN             VARCHAR2
572 ,  p_doc_type                       IN             VARCHAR2
573 ,  p_doc_subtype                    IN             VARCHAR2
574 ,  p_doc_level                      IN             VARCHAR2
575 ,  p_doc_level_id                   IN             NUMBER
576 ,  p_use_enc_gt_flag                IN             VARCHAR2
577 ,  p_get_backing_docs_flag          IN             VARCHAR2
578 ,  p_ap_budget_account_id           IN             NUMBER
579 ,  p_possibility_check_flag         IN             VARCHAR2
580 ,  p_cbc_flag                       IN             VARCHAR2
581 ,  x_count                          OUT NOCOPY     NUMBER
582 )
583 IS
584 
585 l_api_name     CONSTANT VARCHAR2(30) := 'GET_ALL_DISTRIBUTIONS';
586 l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
587 l_progress     VARCHAR2(3) := '000';
588 
589 l_dist_type    PO_DISTRIBUTIONS_ALL.distribution_type%TYPE;
590 
591 l_count     NUMBER;
592 
593 BEGIN
594 
595 IF g_debug_stmt THEN
596    PO_DEBUG.debug_begin(l_log_head);
597    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
598    PO_DEBUG.debug_var(l_log_head,l_progress,'p_check_only_flag',
599                       p_check_only_flag);
600    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
601    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
602    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level', p_doc_level);
603    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level_id', p_doc_level_id);
604    PO_DEBUG.debug_var(l_log_head,l_progress,'p_use_enc_gt_flag',
605                       p_use_enc_gt_flag);
606    PO_DEBUG.debug_var(l_log_head,l_progress,'p_get_backing_docs_flag',
607                       p_get_backing_docs_flag);
608 END IF;
609 
610 l_progress := '010';
611 
612 -----------------------------------------------------------------
613 --Algorithm:
614 --
615 -- 1. Make sure the GTT is clean.
616 -- 2. Fill it with entries for the main doc.
617 -- 3. Fill in the entries for the backing docs.
618 --
619 -- Example code flow for Reserve of a Std. PO (header level):
620 --
621 -- BEGIN get_all_distributions ->
622 --
623 --    initialize_encumbrance_gt
624 --
625 --    get_distributions ( main doc ) ->
626 --
627 --       populate_encumbrance_gt ( main doc ) ->
628 --          lock_headers
629 --          lock_distributions
630 --          <INSERT INTO PO_ENCUMBRANCE_GT>
631 --
632 --       remove_unnecessary_dists
633 --
634 --       update_encumbrance_gt ( main doc )
635 --
636 --    get_distributions ( backing Reqs ) ->
637 --
638 --       lock_backing_distributions ( backing Reqs ) ->
639 --          lock_distributions
640 --
641 --       filter_backing_distributions ( backing Reqs )
642 --
643 --       populate_encumbrance_gt ( backing Reqs )
644 --          <INSERT INTO PO_ENCUMBRANCE_GT>
645 --
646 --       update_encumbrance_gt ( backing Reqs )
647 --
648 --    get_distributions ( backing GAs ) ->
649 --
650 --       lock_backing_distributions ( backing GAs ) ->
651 --          lock_distributions
652 --
653 --       filter_backing_distributions ( backing GAs )
654 --
655 --       populate_encumbrance_gt ( backing GAs )
656 --          <INSERT INTO PO_ENCUMBRANCE_GT>
657 --
658 --       update_encumbrance_gt ( backing GAs )
659 --
660 -- END get_all_distributions
661 --
662 -----------------------------------------------------------------
663 
664 initialize_encumbrance_gt( p_use_enc_gt_flag => p_use_enc_gt_flag );
665 
666 l_progress := '020';
667 
668 derive_dist_from_doc_types(
669    p_doc_type => p_doc_type
670 ,  p_doc_subtype => p_doc_subtype
671 ,  x_distribution_type => l_dist_type
672 );
673 
674 l_progress := '030';
675 
676 x_count := 0;
677 
678 -- Get the main doc distributions.
679 
680 get_distributions(
681    p_action => p_action
682 ,  p_check_only_flag => p_check_only_flag
683 ,  p_distribution_type => l_dist_type
684 ,  p_main_or_backing => g_MAIN
685 ,  p_doc_level => p_doc_level
686 ,  p_doc_level_id => p_doc_level_id
687 ,  p_use_enc_gt_flag => p_use_enc_gt_flag
688 ,  p_ap_budget_account_id => p_ap_budget_account_id
689 ,  p_possibility_check_flag => p_possibility_check_flag
690 ,  p_cbc_flag => p_cbc_flag
691 ,  x_count => l_count
692 );
693 
694 l_progress := '040';
695 
696 x_count := x_count + l_count;
697 
698 -- Now get the backing distributions.
699 
700 IF (p_get_backing_docs_flag = g_parameter_YES
701    AND l_count > 0)
702 THEN
703 
704    l_progress := '100';
705 
706    IF (p_doc_subtype = g_doc_subtype_SCHEDULED) THEN
707 
708       -- Scheduled Releases have backing PPOs
709       -- The MIXED_PO_RELEASE case is only for Blanket Releases.
710 
711       l_progress := '110';
712 
713       get_distributions(
714          p_action => p_action
715       ,  p_check_only_flag => p_check_only_flag
716       ,  p_distribution_type => g_dist_type_PLANNED
717       ,  p_main_or_backing => g_BACKING
718       ,  p_doc_level => NULL
719       ,  p_doc_level_id => NULL
720       ,  p_use_enc_gt_flag => NULL
721       ,  p_ap_budget_account_id => p_ap_budget_account_id
722       ,  p_possibility_check_flag => g_parameter_NO
723       ,  p_cbc_flag => p_cbc_flag
724       ,  x_count => l_count
725       );
726 
727       l_progress := '120';
728 
729       x_count := x_count + l_count;
730 
731    ELSE
732       l_progress := '130';
733       IF g_debug_stmt THEN
734          PO_DEBUG.debug_stmt(l_log_head,l_progress,'No backing PPOs');
735       END IF;
736    END IF;
737 
738    l_progress := '140';
739    IF g_debug_stmt THEN
740       PO_DEBUG.debug_var(l_log_head,l_progress,'req encumbrance'
741                ,  PO_DOCUMENT_FUNDS_PVT.g_req_encumbrance_on);
742    END IF;
743 
744    IF ((p_doc_type IN (g_doc_type_PO , g_doc_type_MIXED_PO_RELEASE)
745    --<bug#5079182 START>
746         OR  (p_doc_type = g_doc_type_RELEASE and p_doc_subtype = g_doc_subtype_BLANKET)
747    --<bug#5079182 END>
748        )AND PO_DOCUMENT_FUNDS_PVT.g_req_encumbrance_on)
749    THEN
750 
751       -- POs, PPOs, and Blanket Releases can have backing Reqs
752 
753       l_progress := '150';
754 
755       get_distributions(
756          p_action => p_action
757       ,  p_check_only_flag => p_check_only_flag
758       ,  p_distribution_type => g_dist_type_REQUISITION
759       ,  p_main_or_backing => g_BACKING
760       ,  p_doc_level => NULL
761       ,  p_doc_level_id => NULL
762       ,  p_use_enc_gt_flag => NULL
763       ,  p_ap_budget_account_id => p_ap_budget_account_id
764       ,  p_possibility_check_flag => g_parameter_NO
765       ,  p_cbc_flag => p_cbc_flag
766       ,  x_count => l_count
767       );
768 
769       l_progress := '160';
770 
771       x_count := x_count + l_count;
772 
773    ELSE
774       l_progress := '170';
775       IF g_debug_stmt THEN
776          PO_DEBUG.debug_stmt(l_log_head,l_progress,'No backing Reqs');
777       END IF;
778    END IF;
779 
780    l_progress := '200';
781    IF g_debug_stmt THEN
782       PO_DEBUG.debug_var(l_log_head,l_progress,'pa encumbrance'
783                ,  PO_DOCUMENT_FUNDS_PVT.g_pa_encumbrance_on);
784    END IF;
785 
786    IF (  p_doc_subtype IN (  g_doc_subtype_STANDARD,g_doc_subtype_BLANKET
787                            ,  g_doc_subtype_MIXED_PO_RELEASE)
788          AND PO_DOCUMENT_FUNDS_PVT.g_pa_encumbrance_on
789       )
790    THEN
791 
792       -- POs and Blanket Releases can have backing GAs/BPAs
793 
794       l_progress := '210';
795 
796       get_distributions(
797          p_action => p_action
798       ,  p_check_only_flag => p_check_only_flag
799       ,  p_distribution_type => g_dist_type_AGREEMENT
800       ,  p_main_or_backing => g_BACKING
801       ,  p_doc_level => NULL
802       ,  p_doc_level_id => NULL
803       ,  p_use_enc_gt_flag => NULL
804       ,  p_ap_budget_account_id => p_ap_budget_account_id
805       ,  p_possibility_check_flag => g_parameter_NO
806       ,  p_cbc_flag => p_cbc_flag
807       ,  x_count => l_count
808       );
809 
810       l_progress := '220';
811 
812       x_count := x_count + l_count;
813 
814    ELSE
815       l_progress := '230';
816       IF g_debug_stmt THEN
817          PO_DEBUG.debug_stmt(l_log_head,l_progress,'No backing BPAs/GAs');
818       END IF;
819    END IF;
820 
821    l_progress := '270';
822 
823 ELSE
824    l_progress := '290';
825    IF g_debug_stmt THEN
826       PO_DEBUG.debug_stmt(l_log_head,l_progress,'Do not get backing docs');
827    END IF;
828 END IF; -- if backing doc flag is Yes
829 
830 l_progress := '990';
831 IF g_debug_stmt THEN
832    PO_DEBUG.debug_var(l_log_head,l_progress,'x_count',x_count);
833    PO_DEBUG.debug_end(l_log_head);
834 END IF;
835 
836 
837 EXCEPTION
838 WHEN OTHERS THEN
839    --add message to the stack and log a debug msg if necessary
840    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
841    fnd_msg_pub.add;
842    RAISE;
843 
844 END get_all_distributions;
845 
846 
847 
848 
849 -------------------------------------------------------------------------------
850 --Start of Comments
851 --Name: initialize_encumbrance_gt
852 --Pre-reqs:
853 --  None.
854 --Modifies:
855 --  PO_ENCUMBRANCE_GT
856 --Locks:
857 --  None.
858 --Function:
859 --  Cleans the encumbrance table for use.
860 --Parameters:
861 --IN:
862 --p_use_enc_gt_flag
863 --  Indicates whether or not data has already been populated
864 --  in the encumbrance table for the main doc.
865 --    g_parameter_NO    delete everything from the encumbrance table
866 --    g_parameter_YES   main doc data has already been populated
867 --Testing:
868 --
869 --End of Comments
870 -------------------------------------------------------------------------------
871 PROCEDURE initialize_encumbrance_gt(
872    p_use_enc_gt_flag                IN             VARCHAR2
873 )
874 IS
875 
876 l_api_name  CONSTANT VARCHAR2(30) := 'INITIALIZE_ENCUMBRANCE_GT';
877 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
878 l_progress  VARCHAR2(3) := '000';
879 
880 BEGIN
881 
882 IF g_debug_stmt THEN
883    PO_DEBUG.debug_begin(l_log_head);
884    PO_DEBUG.debug_var(l_log_head,l_progress,'p_use_enc_gt_flag', p_use_enc_gt_flag);
885 END IF;
886 
887 l_progress := '010';
888 
889 IF (p_use_enc_gt_flag = g_parameter_NO) THEN
890 
891    l_progress := '020';
892    IF g_debug_stmt THEN
893       PO_DEBUG.debug_stmt(l_log_head,l_progress,'Truncating PO_ENCUMBRANCE_GT');
894    END IF;
895 
896    -- If we shouldn't be using whatever was in the encumbrance table,
897    -- get rid of all of it.
898 
899    delete_encumbrance_gt();
900 
901    l_progress := '030';
902 
903 ELSIF (p_use_enc_gt_flag = g_parameter_YES) THEN
904 
905    l_progress := '040';
906    IF g_debug_stmt THEN
907       PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows,NULL,'PO');
908       PO_DEBUG.debug_stmt(l_log_head,l_progress,'Cleaning PO_ENCUMBRANCE_GT');
909    END IF;
910 
911    -- If we are trusting the data in the encumbrance table,
912    -- we need to make sure that we have our own keys into it.
913 
914    UPDATE PO_ENCUMBRANCE_GT
915    SET
916       sequence_num = NULL
917    ,  origin_sequence_num = NULL
918    ;
919 
920    l_progress := '050';
921 
922 ELSE
923    l_progress := '060';
924    RAISE PO_CORE_S.g_INVALID_CALL_EXC;
925 END IF;
926 
927 l_progress := '070';
928 
929 IF g_debug_stmt THEN
930    PO_DEBUG.debug_end(l_log_head);
931 END IF;
932 
933 EXCEPTION
934 
935 WHEN PO_CORE_S.G_INVALID_CALL_EXC THEN
936    IF g_debug_unexp THEN
937       PO_DEBUG.debug_exc(l_log_head,l_progress);
938    END IF;
939    FND_MESSAGE.set_name('PO', 'PO_ALL_INVALID_PARAMETER');
940    FND_MESSAGE.set_token('PROCEDURE', l_api_name);
941    FND_MESSAGE.set_token('PACKAGE', g_pkg_name);
942    fnd_msg_pub.add;
943    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
944 
945 WHEN OTHERS THEN
946    --add message to the stack and log a debug msg if necessary
947    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
948    fnd_msg_pub.add;
949    RAISE;
950 
951 END initialize_encumbrance_gt;
952 
953 
954 
955 
956 -------------------------------------------------------------------------------
957 --Start of Comments
958 --Name: get_distributions
959 --Pre-reqs:
960 --  This procedure assumes that the appropriate encumbrance is on for
961 --    the document type.
962 --  For POs with backing GAs, the org context of the PO must be set
963 --    in order to correctly determine whether or not there needs to
964 --    be a backing entry for the GA.
965 --Modifies:
966 --  PO_ENCUMBRANCE_GT
967 --Locks:
968 --  PO_REQUISITION_HEADERS_ALL
969 --  PO_REQ_DISTRIBUTIONS_ALL
970 --  PO_HEADERS_ALL
971 --  PO_RELEASES_ALL
972 --  PO_DISTRIBUTIONS_ALL
973 --Function:
974 --  Populate the encumbrance table with whatever data is necessary for
975 --  main or backing documents.  This procedure retrieves distributions
976 --  that should be acted upon, and retrieves prevent encumbrance
977 --  distributions for main documents for error reporting.
978 --  It polishes the data in the encumbrance table, even if the
979 --  data was already populated for the main document,
980 --  to prepare it for the rest of the encumbrance flow.
981 --Parameters:
982 --IN:
983 --p_action
984 --  Specifies the action that is being taken on the document.
985 --  Use the g_<action> variables (<action> = RESERVE, UNRESERVE, ADJUST, etc.).
986 --p_check_only_flag
987 --  Indicates whether or not to lock the main document
988 --  headers and distributions if given a doc id for the main document,
989 --  and indicates whether or not to lock the backing distributions
990 --    g_parameter_NO    lock them
991 --    g_parameter_YES   don't lock them
992 --p_distribution_type
993 --  Indicates the type of document to be retrieving data about.
994 --  Use the g_dist_type_<> variables, which map to the distribution_type
995 --  column, except for the following:
996 --    REQUISITION       for requisitions
997 --    MIXED_PO_RELEASE  supported only for Adjust
998 --p_main_or_backing
999 --  Indicates whether this is being called to retrieve the main
1000 --  doc distributions or backing doc distributions of the distribution type
1001 --    g_MAIN / g_BACKING
1002 --p_doc_level
1003 --  The type of ids for the main doc that are being passed. Use g_doc_level_<>
1004 --    HEADER
1005 --    LINE
1006 --    SHIPMENT
1007 --    DISTRIBUTION
1008 --  If the encumbrance table has already been populated
1009 --    for the main doc, use NULL.
1010 --  For backing docs, use NULL.
1011 --p_doc_level_id
1012 --  Id of the main doc level type on which the action is being taken.
1013 --  If the encumbrance table has already been populated
1014 --    for the main doc, use NULL.
1015 --  For backing docs, use NULL.
1016 --p_use_enc_gt_flag
1017 --  Indicates whether or not the data has already been populated
1018 --  in the encumbrance table for the main doc.
1019 --    g_parameter_NO    retrieve the data via the doc ids
1020 --    g_parameter_YES   trust the data that has already been populated
1021 --p_ap_budget_account_id
1022 --  Used by the invoice/credit memo cancel actions.  The budget account
1023 --  id we use must be the same as the budget account passed in by AP
1024 --  For backing docs, use NULL.
1025 --p_possibility_check_flag
1026 --  Used to indicate whether or not this procedure is being used to determine
1027 --  the ability to take an action on the document.
1028 --    g_parameter_NO    not simply a possibility check
1029 --    g_parameter_YES   possibility check only, do not bother
1030 --                         to polish the encumbrance table
1031 --p_cbc_flag
1032 --  Indicates whether or not to process approved rows of a PO/Release
1033 --  during a RESERVE.
1034 --    g_parameter_YES - process the approved rows
1035 --    g_parameter_NO  - ignore approved rows
1036 --OUT:
1037 --x_count
1038 --  The number of rows that were added (or cleaned up, if
1039 --  p_use_enc_gt_flag = YES) to the encumbrance table due to this call.
1040 --Testing:
1041 --
1042 --End of Comments
1043 -------------------------------------------------------------------------------
1044 PROCEDURE get_distributions(
1045    p_action                         IN             VARCHAR2
1046 ,  p_check_only_flag                IN             VARCHAR2
1047 ,  p_distribution_type              IN             VARCHAR2
1048 ,  p_main_or_backing                IN             VARCHAR2
1049 ,  p_doc_level                      IN             VARCHAR2
1050 ,  p_doc_level_id                   IN             NUMBER
1051 ,  p_use_enc_gt_flag                IN             VARCHAR2
1052 ,  p_ap_budget_account_id           IN             NUMBER
1053 ,  p_possibility_check_flag         IN             VARCHAR2
1054 ,  p_cbc_flag                       IN             VARCHAR2
1055 ,  x_count                          OUT NOCOPY     NUMBER
1056 )
1057 IS
1058 
1059 l_api_name     CONSTANT VARCHAR2(30) := 'GET_DISTRIBUTIONS';
1060 l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
1061 l_progress     VARCHAR2(3) := '000';
1062 
1063 l_doc_level_id_tbl    po_tbl_number;
1064 l_origin_seq_num_tbl    po_tbl_number;
1065 
1066 l_return_status   VARCHAR2(1);
1067 l_doc_type     PO_DOCUMENT_TYPES_ALL.document_type_code%TYPE;
1068 l_doc_subtype  PO_HEADERS_ALL.type_lookup_code%TYPE;
1069 l_doc_level    VARCHAR2(25);
1070 l_check_only_flag    VARCHAR2(1);
1071 
1072 BEGIN
1073 
1074 IF g_debug_stmt THEN
1075    PO_DEBUG.debug_begin(l_log_head);
1076    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
1077    PO_DEBUG.debug_var(l_log_head,l_progress,'p_check_only_flag', p_check_only_flag);
1078    PO_DEBUG.debug_var(l_log_head,l_progress,'p_distribution_type',p_distribution_type);
1079    PO_DEBUG.debug_var(l_log_head,l_progress,'p_main_or_backing',p_main_or_backing);
1080    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level', p_doc_level);
1081    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level_id', p_doc_level_id);
1082    PO_DEBUG.debug_var(l_log_head,l_progress,'p_use_enc_gt_flag', p_use_enc_gt_flag);
1083 END IF;
1084 
1085 l_progress := '010';
1086 
1087 -----------------------------------------------------------------
1088 --Algorithm:
1089 --
1090 -- For Main documents:
1091 --
1092 --    IF the GTT is being used for the main doc then
1093 --       0- assume that the documents in the GTT have already been
1094 --             locked if necessary
1095 --       1- delete rows that we don't care about
1096 --             (cancelled, finally closed, etc.)
1097 --       2- fix all of the data that we need
1098 --             (sequence_num, agreement_dist_id, ...)
1099 --
1100 --    ELSE a doc_level_id is passed in for us to act on, so
1101 --       -  fill the GTT with the distributions of the doc
1102 --             using populate(), which will also lock them if necessary
1103 --       -  continue with 1- and 2- from above
1104 --
1105 -- For Backing documents:
1106 --    -  Lock all of the distributions referenced by the main doc
1107 --          in the GTT (if necessary)
1108 --    -  Pick out the ones we care about
1109 --    -  Fill the GTT with these backing distributions
1110 --    -  fix all of the data that we need adjusted
1111 --          (sequence_num, origin_sequence_num, ...)
1112 --
1113 -----------------------------------------------------------------
1114 
1115 IF (p_main_or_backing = g_BACKING
1116    OR p_use_enc_gt_flag = g_parameter_NO)
1117 THEN
1118 
1119    -- Callers may populate the table with data for the main document(s).
1120    -- For backing documents, we always retrieve the data.
1121 
1122    l_progress := '020';
1123 
1124    derive_doc_types_from_dist(
1125       p_distribution_type => p_distribution_type
1126    ,  x_doc_type => l_doc_type
1127    ,  x_doc_subtype => l_doc_subtype
1128    );
1129 
1130    l_progress := '030';
1131 
1132    IF (p_main_or_backing = g_BACKING) THEN
1133 
1134       l_progress := '100';
1135       IF g_debug_stmt THEN
1136          PO_DEBUG.debug_stmt(l_log_head,l_progress,'backing call');
1137       END IF;
1138 
1139       IF (p_check_only_flag = g_parameter_NO) THEN
1140 
1141          l_progress := '110';
1142 
1143          lock_backing_distributions(p_distribution_type => p_distribution_type);
1144 
1145          -- For new req distributions of Cancel with recreate demand,
1146          -- the recreated req distributions don't get locked.
1147          -- But this is okay, as the caller has these rows locked, as
1148          -- they have just been created.
1149 
1150          l_progress := '120';
1151 
1152       ELSE
1153          l_progress := '130';
1154          IF g_debug_stmt THEN
1155             PO_DEBUG.debug_stmt(l_log_head,l_progress,'check only');
1156          END IF;
1157       END IF;
1158 
1159       -- We have already locked the backing distributions,
1160       -- and we don't want populate_encumbrance_gt to lock
1161       -- the backing headers.
1162 
1163       l_progress := '140';
1164 
1165       l_check_only_flag := g_parameter_YES;
1166 
1167       -- Retrieve the dist ids of the rows you want to do something with.
1168 
1169       filter_backing_distributions(
1170          p_action => p_action
1171       ,  p_distribution_type => p_distribution_type
1172       ,  x_dist_id_tbl => l_doc_level_id_tbl
1173       ,  x_origin_seq_num_tbl => l_origin_seq_num_tbl
1174       );
1175 
1176       l_progress := '150';
1177 
1178       l_doc_level := g_doc_level_DISTRIBUTION;
1179 
1180    ELSIF (p_main_or_backing = g_MAIN) THEN
1181 
1182       -- Main doc distributions are locked in populate_encumbrance_gt,
1183       -- so no need to lock here.
1184 
1185       l_progress := '170';
1186       IF g_debug_stmt THEN
1187          PO_DEBUG.debug_stmt(l_log_head,l_progress,'main call');
1188       END IF;
1189 
1190       l_check_only_flag := p_check_only_flag;
1191 
1192       l_doc_level_id_tbl := po_tbl_number( p_doc_level_id );
1193 
1194       l_doc_level := p_doc_level;
1195 
1196    ELSE
1197       l_progress := '190';
1198       RAISE PO_CORE_S.g_INVALID_CALL_EXC;
1199    END IF;
1200 
1201    l_progress := '200';
1202 
1203    -- Fill the GTT with the data from the doc tables.
1204 
1205    PO_DOCUMENT_FUNDS_PVT.populate_encumbrance_gt(
1206       x_return_status => l_return_status
1207    ,  p_doc_type => l_doc_type
1208    ,  p_doc_level => l_doc_level
1209    ,  p_doc_level_id_tbl => l_doc_level_id_tbl
1210    ,  p_adjustment_status_tbl => po_tbl_varchar5( NULL )
1211    ,  p_check_only_flag => l_check_only_flag
1212    );
1213 
1214    l_progress := '250';
1215 
1216    IF l_return_status IN (FND_API.G_RET_STS_UNEXP_ERROR,
1217                           FND_API.G_RET_STS_ERROR) THEN
1218       RAISE G_POPULATE_ENC_GT_EXC;
1219    END IF;
1220 
1221 ELSE
1222    l_progress := '290';
1223    IF g_debug_stmt THEN
1224       PO_DEBUG.debug_stmt(l_log_head,l_progress,'using table data');
1225    END IF;
1226 END IF;
1227 
1228 l_progress := '300';
1229 
1230 IF (p_main_or_backing = g_MAIN) THEN
1231 
1232    l_progress := '310';
1233 
1234    -- Delete the unwanted dists (cancelled, finally closed, etc.).
1235 
1236    remove_unnecessary_dists(
1237       p_action    => p_action
1238    ,  p_cbc_flag  => p_cbc_flag
1239    );
1240 
1241    l_progress := '350';
1242 
1243 ELSE
1244    l_progress := '370';
1245    IF g_debug_stmt THEN
1246       PO_DEBUG.debug_stmt(l_log_head,l_progress,'backing');
1247    END IF;
1248 END IF;
1249 
1250 l_progress := '400';
1251 
1252 -- Finish preparing the GTT by populating sequence_num, etc.
1253 -- If this is only a possibility check, we can skip this step,
1254 -- and instead just return the number of rows we would have updated.
1255 
1256 IF (p_possibility_check_flag = g_parameter_YES) THEN
1257 
1258    l_progress := '410';
1259 
1260    SELECT COUNT(*)
1261    INTO x_count
1262    FROM PO_ENCUMBRANCE_GT ENC
1263    WHERE ENC.sequence_num IS NULL
1264    ;
1265 
1266    l_progress := '420';
1267 
1268 ELSE
1269 
1270    l_progress := '450';
1271 
1272    update_encumbrance_gt(
1273       p_action => p_action
1274    ,  p_distribution_type => p_distribution_type
1275    ,  p_main_or_backing => p_main_or_backing
1276    ,  p_origin_seq_num_tbl => l_origin_seq_num_tbl
1277    ,  p_backing_dist_id_tbl => l_doc_level_id_tbl
1278    ,  p_ap_budget_account_id => p_ap_budget_account_id
1279    ,  x_count => x_count
1280    );
1281 
1282    l_progress := '460';
1283 
1284 END IF;
1285 
1286 l_progress := '990';
1287 
1288 IF g_debug_stmt THEN
1289    PO_DEBUG.debug_var(l_log_head,l_progress,'x_count',x_count);
1290    PO_DEBUG.debug_end(l_log_head);
1291 END IF;
1292 
1293 EXCEPTION
1294 
1295 WHEN G_POPULATE_ENC_GT_EXC THEN
1296    IF g_debug_unexp THEN
1297       PO_DEBUG.debug_exc(l_log_head,l_progress);
1298    END IF;
1299    -- populate_enc_gt should have left its error msg on the stack
1300    -- no further action required
1301    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1302 
1303 WHEN PO_CORE_S.G_INVALID_CALL_EXC THEN
1304    IF g_debug_unexp THEN
1305       PO_DEBUG.debug_exc(l_log_head,l_progress);
1306    END IF;
1307    FND_MESSAGE.set_name('PO', 'PO_ALL_INVALID_PARAMETER');
1308    FND_MESSAGE.set_token('PROCEDURE', l_api_name);
1309    FND_MESSAGE.set_token('PACKAGE', g_pkg_name);
1310    fnd_msg_pub.add;
1311    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1312 
1313 WHEN OTHERS THEN
1314    --add message to the stack and log a debug msg if necessary
1315    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
1316    fnd_msg_pub.add;
1317    RAISE;
1318 
1319 END get_distributions;
1320 
1321 
1322 
1323 -------------------------------------------------------------------------------
1324 --Start of Comments
1325 --Name: remove_unnecessary_dists
1326 --Pre-reqs:
1327 --  The encumbrance table has been populated only with main doc data.
1328 --Modifies:
1329 --  PO_ENCUMBRANCE_GT
1330 --Locks:
1331 --  None.
1332 --Function:
1333 --  For the given action, removes any rows that aren't relevant to the
1334 --  encumbrance activity on a main document.
1335 --Parameters:
1336 --IN:
1337 --p_action
1338 --  Specifies the action that is being taken on the main document.
1339 --  Use the g_<action> variables (<action> = RESERVE, UNRESERVE, ADJUST, etc.).
1340 --p_cbc_flag
1341 --  Indicates whether or not to keep approved rows of a PO/Release
1342 --  during a RESERVE
1343 --    g_parameter_YES - do not remove approved rows
1344 --    g_parameter_NO  - remove approved rows
1345 --Testing:
1346 --
1347 --End of Comments
1348 -------------------------------------------------------------------------------
1349 PROCEDURE remove_unnecessary_dists(
1350    p_action                         IN             VARCHAR2
1351 ,  p_cbc_flag                       IN             VARCHAR2
1352 )
1353 IS
1354 
1355 l_api_name  CONSTANT VARCHAR2(30) := 'REMOVE_UNNECESSARY_DISTS';
1356 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
1357 l_progress  VARCHAR2(3) := '000';
1358 
1359 BEGIN
1360 
1361 IF g_debug_stmt THEN
1362    PO_DEBUG.debug_begin(l_log_head);
1363    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
1364 END IF;
1365 
1366 l_progress := '010';
1367 
1368 -- Remove any entries that have no encumbrance impact.
1369 -- Keep the other prevent encumbrance rows, as they need to be reported.
1370 
1371 DELETE FROM PO_ENCUMBRANCE_GT ENC
1372 WHERE
1373    -- Delete already encumbered rows for Reserve, FC
1374    -- Bug 3364450: also delete enc rows for INV Cancel
1375    ( p_action IN ( g_action_RESERVE
1376                  , g_action_UNDO_FINAL_CLOSE
1377                  , g_action_INVOICE_CANCEL
1378                  , g_action_CR_MEMO_CANCEL)
1379      AND NVL(ENC.encumbered_flag,'N') = 'Y' )
1380 
1381    -- Delete already unencumbered rows for reversal actions
1382    -- Bug 3402031: Allow all unencumbered rows for FINAL CLOSE action
1383    -- Later, only rows unenc due to cancellation are kept for FINAL CLOSE.
1384 OR (  p_action NOT IN ( g_action_RESERVE
1385                       , g_action_UNDO_FINAL_CLOSE
1386                       , g_action_ADJUST
1387                       , g_action_INVOICE_CANCEL
1388                       , g_action_CR_MEMO_CANCEL
1389                       , g_action_FINAL_CLOSE)
1390       AND NVL(ENC.encumbered_flag,'N') = 'N' )
1391 
1392    -- Delete all cancelled rows unless action is Final Close
1393    -- But 3477327: also keep cancelled rows for INV CANCEL
1394 OR ( p_action NOT IN ( g_action_FINAL_CLOSE
1395                      , g_action_INVOICE_CANCEL
1396                      , g_action_CR_MEMO_CANCEL)
1397      AND  NVL(ENC.cancel_flag,'N') = 'Y'
1398    )
1399 
1400    -- Bug 3477327: For Inv/Cr Memo Cancel, now delete cancelled
1401    -- rows unless they are ALSO finally closed rows
1402 OR ( p_action IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL)
1403      AND NVL(ENC.cancel_flag, 'N') = 'Y'
1404      AND NVL(ENC.closed_code, g_clsd_OPEN) <> g_clsd_FINALLY_CLOSED
1405    )
1406 
1407    -- Delete all FC'ed rows unless action is INV Cancel, Undo FC
1408 OR ( NVL(ENC.closed_code, g_clsd_OPEN) = g_clsd_FINALLY_CLOSED
1409      AND p_action NOT IN ( g_action_INVOICE_CANCEL
1410                          , g_action_CR_MEMO_CANCEL
1411                          , g_action_UNDO_FINAL_CLOSE)
1412    )
1413 
1414    -- Bug 3402031: Delete unencumbered rows during FINAL CLOSE if
1415    -- a CANCEL action has not been taken.
1416    -- Bug 5115105: only keep Cancelled rows for POs/Releases
1417    -- If the cancelled row belongs to a requisition then delete it.
1418 
1419 OR (  p_action = g_action_FINAL_CLOSE
1420       AND (
1421              (ENC.distribution_type=g_dist_type_REQUISITION
1422                 AND NVL(ENC.cancel_flag, 'N') = 'Y')
1423              OR
1424                NVL(ENC.cancel_flag, 'N') = 'N'
1425           )
1426       and NVL(ENC.encumbered_flag, 'N') = 'N')
1427 
1428    --Exclude certain Req distributions
1429 OR (  ENC.distribution_type = g_dist_type_REQUISITION
1430    AND   (  ENC.line_location_id IS NOT NULL
1431       OR (  p_action IN (  g_action_RESERVE, g_action_UNRESERVE
1432                         ,  g_action_REJECT  --, g_action_ADJUST  Donot delete for Adjust action since will be used for IR ISO ER
1433                         )
1434          AND   ENC.transferred_to_oe_flag = 'Y'
1435          AND   ENC.source_type_code = g_src_INVENTORY
1436          )
1437       OR (  p_action = g_action_RETURN
1438          AND   ENC.source_type_code = g_src_INVENTORY
1439          )
1440       --bug 3537764: exclude parent Req dists that have already
1441       --been split in Req Split from any further Enc action
1442       OR ( ENC.prevent_encumbrance_flag = 'Y'
1443            AND ENC.modified_by_agent_flag = 'Y'
1444          )
1445       )
1446    )
1447 
1448    --Exclude BPAs that are not encumbered
1449 OR (  ENC.distribution_type = g_dist_type_AGREEMENT
1450    AND   NVL(ENC.encumbrance_required_flag,'N') = 'N'
1451    )
1452 
1453    --Exclude certain PO/Rel distributions
1454    -- Bug 3391282: We cannot drop distributions that come from
1455    -- shipments with approved_flag = 'Y' for the reserve action,
1456    -- as we were previously doing to avoid some user warnings.
1457    -- That is because PDOI and CBC both expect that they can
1458    -- call reserve with approved_flag already set to 'Y'.
1459    -- A workaround for the warnings, as explained in the bug,
1460    -- is to drop only those distributions that are both approved
1461    -- and have prevent encumbrance flag = 'Y'.
1462 OR (  ENC.distribution_type IN
1463       (  g_dist_type_STANDARD, g_dist_type_PLANNED,
1464          g_dist_type_SCHEDULED, g_dist_type_BLANKET )
1465    AND ENC.approved_flag = 'Y'
1466    AND ( p_action = g_action_REJECT
1467 	 or
1468          (p_action = g_action_RESERVE
1469      and p_cbc_flag = g_parameter_NO
1470 	  and ENC.prevent_encumbrance_flag = 'Y'
1471          )
1472        )
1473    )
1474 ;
1475 
1476 l_progress := '900';
1477 
1478 IF g_debug_stmt THEN
1479    PO_DEBUG.debug_end(l_log_head);
1480 END IF;
1481 
1482 EXCEPTION
1483 
1484 WHEN OTHERS THEN
1485    --add message to the stack and log a debug msg if necessary
1486    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
1487    fnd_msg_pub.add;
1488    RAISE;
1489 
1490 END remove_unnecessary_dists;
1491 
1492 
1493 
1494 -------------------------------------------------------------------------------
1495 --Start of Comments
1496 --Name: update_encumbrance_gt
1497 --Pre-reqs:
1498 --  For POs with backing GAs, the org context of the PO must be set
1499 --    in order to correctly determine whether or not there needs to
1500 --    be a backing entry for the GA.
1501 --Modifies:
1502 --  PO_ENCUMBRANCE_GT
1503 --Locks:
1504 --  None.
1505 --Function:
1506 --  Polishes the data in the encumbrance table.
1507 --  Prepares the data in the table for use by the rest of the encumbrance
1508 --  flow.
1509 --Parameters:
1510 --IN:
1511 --p_distribution_type
1512 --  Indicates the type rows to update in the encumbrance table.
1513 --  Use the g_dist_type_<> variables, which map to the distribution_type
1514 --  column, except for the following:
1515 --    REQUISITION       for requisitions
1516 --    MIXED_PO_RELEASE  supported only for Adjust
1517 --p_main_or_backing
1518 --  Indicates whether this is being called to polish main doc data
1519 --  or backing doc data.
1520 --    g_MAIN / g_BACKING
1521 --p_origin_seq_num_tbl
1522 --  For backing distributions, the sequence_num of the main distribution.
1523 --  NULL for main doc use.
1524 --p_backing_dist_id_tbl
1525 --  The distribution id of the backing distribution that corresponds to
1526 --  the origin_seq_num entry.
1527 --  NULL for main doc use.
1528 --p_ap_budget_account_id
1529 --  Used by the invoice/credit memo cancel actions.  The budget account
1530 --  id we use must be the same as the budget account passed in by AP
1531 --
1532 --OUT:
1533 --x_count
1534 --  The number of rows that were updated by this procedure.
1535 --Testing:
1536 --
1537 --End of Comments
1538 -------------------------------------------------------------------------------
1539 PROCEDURE update_encumbrance_gt(
1540    p_action                         IN             VARCHAR2
1541 ,  p_distribution_type              IN             VARCHAR2
1542 ,  p_main_or_backing                IN             VARCHAR2
1543 ,  p_origin_seq_num_tbl             IN             po_tbl_number
1544 ,  p_backing_dist_id_tbl            IN             po_tbl_number
1545 ,  p_ap_budget_account_id           IN             NUMBER
1546 ,  x_count                          OUT NOCOPY     NUMBER
1547 )
1548 IS
1549 
1550 l_api_name  CONSTANT VARCHAR2(30) := 'UPDATE_ENCUMBRANCE_GT';
1551 l_log_head  CONSTANT VARCHAR2(100) := g_log_head|| l_api_name;
1552 l_progress  VARCHAR2(3) := '000';
1553 
1554 BEGIN
1555 
1556 IF g_debug_stmt THEN
1557    PO_DEBUG.debug_begin(l_log_head);
1558    PO_DEBUG.debug_var(l_log_head,l_progress,'p_distribution_type',p_distribution_type);
1559    PO_DEBUG.debug_var(l_log_head,l_progress,'p_main_or_backing',p_main_or_backing);
1560    PO_DEBUG.debug_var(l_log_head,l_progress,'p_origin_seq_num_tbl'
1561             ,p_origin_seq_num_tbl);
1562    PO_DEBUG.debug_var(l_log_head,l_progress,'p_backing_dist_id_tbl'
1563             ,p_backing_dist_id_tbl);
1564    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_budget_account_id'
1565             ,p_ap_budget_account_id);
1566 END IF;
1567 
1568 l_progress := '010';
1569 
1570 
1571 -- Clean up the inputs columns to make future calculations easier,
1572 -- and derive other column values needed for calculations.
1573 
1574 UPDATE PO_ENCUMBRANCE_GT ENC
1575 SET
1576 
1577 -- input columns
1578    ENC.unencumbered_amount = NVL(ENC.unencumbered_amount,0)
1579 ,  ENC.encumbered_amount = NVL(ENC.encumbered_amount,0)
1580 ,  ENC.amount_delivered = NVL(ENC.amount_delivered,0)
1581 ,  ENC.amount_billed = NVL(ENC.amount_billed,0)
1582 ,  ENC.amount_cancelled = NVL(ENC.amount_cancelled,0)
1583 ,  ENC.unencumbered_quantity = NVL(ENC.unencumbered_quantity,0)
1584 ,  ENC.quantity_delivered = NVL(ENC.quantity_delivered,0)
1585 ,  ENC.quantity_billed = NVL(ENC.quantity_billed,0)
1586 ,  ENC.quantity_cancelled = NVL(ENC.quantity_cancelled,0)
1587 ,  ENC.nonrecoverable_tax = NVL(ENC.nonrecoverable_tax,0)
1588 ,  ENC.rate = NVL(ENC.rate,1)
1589 ,  ENC.prevent_encumbrance_flag = NVL(ENC.prevent_encumbrance_flag,'N')
1590 -- bug 3537764: add modified_by_agent_flag to temp table
1591 ,  ENC.modified_by_agent_flag = NVL(ENC.modified_by_agent_flag, 'N')
1592 
1593 -- calculation columns
1594 ,  ENC.amount_based_flag =
1595      DECODE( ENC.value_basis  --<Complex Work R12>: use POLL value basis
1596            , g_order_type_FIXED_PRICE, 'Y'
1597            , g_order_type_RATE, 'Y'
1598            , 'N'
1599      )
1600    --bug 356812: no prevent enc lines are sent to GL
1601 ,  ENC.send_to_gl_flag = DECODE( ENC.prevent_encumbrance_flag
1602                                , 'Y', 'N'
1603                                ,      'Y'
1604                          )
1605 WHERE ENC.sequence_num IS NULL
1606 ;
1607 
1608 l_progress := '100';
1609 
1610 -- Fill in the minimum accountable unit and precision for foreign currencies.
1611 -- We probably don't need to do this for the functional currency rows.
1612 
1613 UPDATE PO_ENCUMBRANCE_GT ENC
1614 SET
1615 (  ENC.min_acct_unit_foreign
1616 ,  ENC.cur_precision_foreign
1617 )
1618 =
1619 (  SELECT
1620       CUR.minimum_accountable_unit
1621    ,  CUR.precision
1622    FROM
1623       FND_CURRENCIES CUR
1624    WHERE CUR.currency_code = ENC.currency_code
1625 )
1626 WHERE ENC.sequence_num IS NULL
1627 AND   ENC.prevent_encumbrance_flag = 'N'
1628 ;
1629 
1630 l_progress := '180';
1631 
1632 -- Fill in the sequence_num.
1633 -- Do this for prevent rows as well, for error reporting.
1634 
1635 UPDATE PO_ENCUMBRANCE_GT ENC
1636 SET   ENC.sequence_num = PO_ENCUMBRANCE_GT_S.nextval
1637 WHERE ENC.sequence_num IS NULL
1638 ;
1639 
1640 l_progress := '190';
1641 
1642 -- Count the number of rows that had a NULL sequence_num before this
1643 -- procedure, as that is how many rows would have been updated by
1644 -- this call.
1645 
1646 x_count := SQL%ROWCOUNT;
1647 
1648 -- Since we do not have source_distribution_id of POs/Blanket Releases
1649 -- point to the GA/BPA distribution, we need to fix this.
1650 
1651 -- Retrieve the backing GA distribution reference.
1652 --
1653 -- Currently, POs have encumbrance effect on a GA only if they
1654 -- are in the same org.
1655 -- We are assuming here that the org context has been set to
1656 -- the org of the document that is being acted upon
1657 -- (i.e., the org of the PO).
1658 
1659 IF (p_main_or_backing = g_MAIN
1660    AND p_distribution_type IN
1661          (g_dist_type_STANDARD, g_dist_type_MIXED_PO_RELEASE))
1662 THEN
1663 
1664    l_progress := '200';
1665    IF g_debug_stmt THEN
1666       PO_DEBUG.debug_stmt(l_log_head,l_progress,'updating GA dist_id');
1667    END IF;
1668 
1669    UPDATE PO_ENCUMBRANCE_GT PO_DIST
1670    SET PO_DIST.agreement_dist_id =
1671    (  SELECT GA_DIST.po_distribution_id
1672       FROM PO_DISTRIBUTIONS GA_DIST
1673       WHERE GA_DIST.po_header_id = PO_DIST.from_header_id
1674    )
1675    WHERE PO_DIST.distribution_type = g_dist_type_STANDARD
1676    AND PO_DIST.prevent_encumbrance_flag = 'N'
1677    ;
1678 
1679    l_progress := '210';
1680 
1681 ELSE
1682    l_progress := '250';
1683    IF g_debug_stmt THEN
1684       PO_DEBUG.debug_stmt(l_log_head,l_progress,'no GAs');
1685    END IF;
1686 END IF;
1687 
1688 l_progress := '290';
1689 
1690 -- Retrieve the backing BPA distribution reference.
1691 
1692 IF (p_main_or_backing = g_MAIN
1693    AND p_distribution_type IN
1694          (g_dist_type_BLANKET, g_dist_type_MIXED_PO_RELEASE))
1695 THEN
1696 
1697    l_progress := '300';
1698    IF g_debug_stmt THEN
1699       PO_DEBUG.debug_stmt(l_log_head,l_progress,'updating BPA dist ids');
1700    END IF;
1701 
1702    UPDATE PO_ENCUMBRANCE_GT REL_DIST
1703    SET REL_DIST.agreement_dist_id =
1704    (  SELECT BPA_DIST.po_distribution_id
1705       FROM PO_DISTRIBUTIONS_ALL BPA_DIST
1706       WHERE BPA_DIST.po_header_id = REL_DIST.header_id
1707       AND BPA_DIST.distribution_type = g_dist_type_AGREEMENT
1708       -- we don't want release distributions here.
1709    )
1710    WHERE REL_DIST.distribution_type = g_dist_type_BLANKET
1711    AND REL_DIST.prevent_encumbrance_flag = 'N'
1712    ;
1713 
1714    l_progress := '310';
1715 
1716 ELSE
1717    l_progress := '350';
1718    IF g_debug_stmt THEN
1719       PO_DEBUG.debug_stmt(l_log_head,l_progress,'no BPAs');
1720    END IF;
1721 END IF;
1722 
1723 l_progress := '400';
1724 
1725 -- For backing docs, we need to put in the reference to the main doc row.
1726 
1727 IF (p_main_or_backing = g_BACKING) THEN
1728 
1729    l_progress := '410';
1730    IF g_debug_stmt THEN
1731       PO_DEBUG.debug_stmt(l_log_head,l_progress,'updating backing link');
1732    END IF;
1733 
1734    FORALL i IN 1 .. p_origin_seq_num_tbl.COUNT
1735    UPDATE PO_ENCUMBRANCE_GT BACKING
1736    SET BACKING.origin_sequence_num = p_origin_seq_num_tbl(i)
1737    WHERE BACKING.distribution_id = p_backing_dist_id_tbl(i)
1738    AND BACKING.distribution_type = p_distribution_type
1739    AND BACKING.origin_sequence_num IS NULL
1740    AND rownum = 1
1741    ;
1742    -- the rownum = 1 is required so that each backing dist
1743    -- with the same id (think backing BPA) gets a different
1744    -- origin_sequence_num.
1745 
1746    IF p_action NOT IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL) THEN
1747 
1748       l_progress := '420';
1749       IF g_debug_stmt THEN
1750          PO_DEBUG.debug_stmt(l_log_head,l_progress,'updating send to GL flag');
1751       END IF;
1752 
1753       --bug 3568512: do not send Unreserved backing BPA/PPO lines to GL; we
1754       --only keep them in the GTT to maintain the unencumbered_amount column
1755       --Invoice Cancel is excluded b/c it has a different set of conditions
1756       --for backing docs in the filter_backing_distributions code
1757       UPDATE PO_ENCUMBRANCE_GT BACKING
1758       SET BACKING.send_to_gl_flag = 'N'
1759       ,   BACKING.update_encumbered_amount_flag = 'N'
1760       WHERE BACKING.origin_sequence_num IS NOT NULL  --backing doc
1761       AND BACKING.encumbered_flag = 'N'
1762       AND BACKING.distribution_type IN
1763           (g_dist_type_AGREEMENT, g_dist_type_PLANNED)
1764       ;
1765    END IF; -- action is Invoice Cancel
1766 
1767    l_progress := '430';
1768 
1769 ELSE
1770    l_progress := '450';
1771    IF g_debug_stmt THEN
1772       PO_DEBUG.debug_stmt(l_log_head,l_progress,'not backing');
1773    END IF;
1774 END IF;
1775 
1776 l_progress := '500';
1777 
1778 
1779 -- For AP Invoice/Credit memo Cancel, we use the budget account
1780 -- passed in by AP for the main document
1781 IF (p_action IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL)
1782    AND p_main_or_backing = g_MAIN) THEN
1783 
1784    UPDATE PO_ENCUMBRANCE_GT MAINDOC
1785    SET MAINDOC.budget_account_id = p_ap_budget_account_id
1786    WHERE MAINDOC.origin_sequence_num IS NULL;
1787 
1788 END IF;
1789 
1790 l_progress := '600';
1791 
1792 IF g_debug_stmt THEN
1793    PO_DEBUG.debug_var(l_log_head,l_progress,'x_count',x_count);
1794    PO_DEBUG.debug_end(l_log_head);
1795 END IF;
1796 
1797 EXCEPTION
1798 
1799 WHEN OTHERS THEN
1800    --add message to the stack and log a debug msg if necessary
1801    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
1802    fnd_msg_pub.add;
1803    RAISE;
1804 
1805 END update_encumbrance_gt;
1806 
1807 
1808 
1809 -------------------------------------------------------------------------------
1810 --Start of Comments
1811 --Name: lock_backing_distributions
1812 --Pre-reqs:
1813 --  The backing distribution references have been populated
1814 --  in the encumbrance table.
1815 --Modifies:
1816 --  None.
1817 --Locks:
1818 --  PO_DISTRIBUTIONS_ALL
1819 --  PO_REQ_DISTRIBUTIONS_ALL
1820 --Function:
1821 --  Locks all of the backing distributions of the given type that are
1822 --  referenced by main doc rows in the encumbrance table.
1823 --Parameters:
1824 --IN:
1825 --p_distribution_type
1826 --  The type of distribution to be locking.  Use g_dist_type_<>:
1827 --    PLANNED        PPOs
1828 --    AGREEMENT      BPAs/GAs
1829 --    REQUISITION    Reqs
1830 --Testing:
1831 --
1832 --End of Comments
1833 -------------------------------------------------------------------------------
1834 PROCEDURE lock_backing_distributions(
1835    p_distribution_type              IN             VARCHAR2
1836 )
1837 IS
1838 
1839 l_api_name  CONSTANT VARCHAR2(30) := 'LOCK_BACKING_DISTRIBUTIONS';
1840 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
1841 l_progress  VARCHAR2(3) := '000';
1842 
1843 l_distribution_id_tbl     po_tbl_number;
1844 
1845 l_doc_type     PO_DOCUMENT_TYPES_ALL.document_type_code%TYPE;
1846 l_doc_subtype  PO_HEADERS_ALL.type_lookup_code%TYPE;
1847 
1848 BEGIN
1849 
1850 IF g_debug_stmt THEN
1851    PO_DEBUG.debug_begin(l_log_head);
1852    PO_DEBUG.debug_var(l_log_head,l_progress,'p_distribution_type',p_distribution_type);
1853 END IF;
1854 
1855 l_progress := '010';
1856 
1857 -- Get the backing distribution ids from the main docs in the GTT.
1858 
1859 IF (p_distribution_type = g_dist_type_REQUISITION) THEN
1860 
1861    l_progress := '020';
1862    IF g_debug_stmt THEN
1863       PO_DEBUG.debug_stmt(l_log_head,l_progress,'requisitions');
1864    END IF;
1865 
1866    SELECT DISTS.req_distribution_id
1867    BULK COLLECT INTO l_distribution_id_tbl
1868    FROM PO_ENCUMBRANCE_GT DISTS
1869    WHERE DISTS.req_distribution_id IS NOT NULL
1870    AND DISTS.origin_sequence_num IS NULL
1871    AND DISTS.prevent_encumbrance_flag = 'N'
1872    ;
1873 
1874    l_progress := '030';
1875 
1876 ELSIF (p_distribution_type = g_dist_type_PLANNED) THEN
1877 
1878    l_progress := '040';
1879    IF g_debug_stmt THEN
1880       PO_DEBUG.debug_stmt(l_log_head,l_progress,'PPOs');
1881    END IF;
1882 
1883    SELECT DISTS.source_distribution_id
1884    BULK COLLECT INTO l_distribution_id_tbl
1885    FROM PO_ENCUMBRANCE_GT DISTS
1886    WHERE DISTS.source_distribution_id IS NOT NULL
1887    AND DISTS.origin_sequence_num IS NULL
1888    AND DISTS.prevent_encumbrance_flag = 'N'
1889    ;
1890 
1891    l_progress := '050';
1892 
1893 ELSIF (p_distribution_type = g_dist_type_AGREEMENT) THEN
1894 
1895    l_progress := '060';
1896    IF g_debug_stmt THEN
1897       PO_DEBUG.debug_stmt(l_log_head,l_progress,'agreements');
1898    END IF;
1899 
1900    SELECT DISTS.agreement_dist_id
1901    BULK COLLECT INTO l_distribution_id_tbl
1902    FROM PO_ENCUMBRANCE_GT DISTS
1903    WHERE DISTS.agreement_dist_id IS NOT NULL
1904    AND DISTS.origin_sequence_num IS NULL
1905    AND DISTS.prevent_encumbrance_flag = 'N'
1906    ;
1907 
1908    l_progress := '070';
1909 
1910 ELSE
1911    l_progress := '090';
1912    RAISE PO_CORE_S.g_INVALID_CALL_EXC;
1913 END IF;
1914 
1915 l_progress := '100';
1916 
1917 derive_doc_types_from_dist(
1918    p_distribution_type => p_distribution_type
1919 ,  x_doc_type => l_doc_type
1920 ,  x_doc_subtype => l_doc_subtype
1921 );
1922 
1923 l_progress := '110';
1924 
1925 -- Lock those distribution ids.
1926 
1927 PO_LOCKS.lock_distributions(
1928    p_doc_type => l_doc_type
1929 ,  p_doc_level => g_doc_level_DISTRIBUTION
1930 ,  p_doc_level_id_tbl => l_distribution_id_tbl
1931 );
1932 
1933 l_progress := '120';
1934 
1935 IF g_debug_stmt THEN
1936    PO_DEBUG.debug_end(l_log_head);
1937 END IF;
1938 
1939 EXCEPTION
1940 
1941 WHEN PO_CORE_S.G_INVALID_CALL_EXC THEN
1942    IF g_debug_unexp THEN
1943       PO_DEBUG.debug_exc(l_log_head,l_progress);
1944    END IF;
1945    FND_MESSAGE.set_name('PO', 'PO_ALL_INVALID_PARAMETER');
1946    FND_MESSAGE.set_token('PROCEDURE', l_api_name);
1947    FND_MESSAGE.set_token('PACKAGE', g_pkg_name);
1948    fnd_msg_pub.add;
1949    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1950 
1951 WHEN OTHERS THEN
1952    --add message to the stack and log a debug msg if necessary
1953    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
1954    fnd_msg_pub.add;
1955    RAISE;
1956 
1957 END lock_backing_distributions;
1958 
1959 
1960 
1961 -------------------------------------------------------------------------------
1962 --Start of Comments
1963 --Name: filter_backing_distributions
1964 --Pre-reqs:
1965 --  The encumbrance table has the appropriate references to the backing
1966 --  distributions.
1967 --Modifies:
1968 --  None.
1969 --Locks:
1970 --  None.
1971 --Function:
1972 --  Retrieves the ids of the distributions that require backing entries
1973 --  due to the action being taken on the main doc, along with the
1974 --  main doc's sequence_num in the encumbrance table in order to provide
1975 --  a mapping.
1976 --Parameters:
1977 --IN:
1978 --p_action
1979 --  Specifies the action that is being taken on the main document.
1980 --  Use the g_<action> variables (<action> = RESERVE, UNRESERVE, ADJUST, etc.).
1981 --p_distribution_type
1982 --  The type of relevant backing distributions to find.  Use g_dist_type_<>:
1983 --    PLANNED        PPOs
1984 --    AGREEMENT      BPAs/GAs
1985 --    REQUISITION    Reqs
1986 --OUT:
1987 --x_dist_id_tbl
1988 --  The ids of distributions that require backing encumbrance entries.
1989 --x_origin_seq_num_tbl
1990 --  The sequence_num of the main doc row for which the distribution is
1991 --  a backing document.
1992 --Testing:
1993 --
1994 --End of Comments
1995 -------------------------------------------------------------------------------
1996 PROCEDURE filter_backing_distributions(
1997    p_action                         IN             VARCHAR2
1998 ,  p_distribution_type              IN             VARCHAR2
1999 ,  x_dist_id_tbl                    OUT NOCOPY     po_tbl_number
2000 ,  x_origin_seq_num_tbl             OUT NOCOPY     po_tbl_number
2001 )
2002 IS
2003 
2004 l_api_name CONSTANT VARCHAR2(30) := 'FILTER_BACKING_DISTRIBUTIONS';
2005 l_log_head CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
2006 l_progress  VARCHAR2(3) := '000';
2007 
2008 l_backing_req_key    NUMBER;
2009 
2010 BEGIN
2011 
2012 IF g_debug_stmt THEN
2013    PO_DEBUG.debug_begin(l_log_head);
2014    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
2015    PO_DEBUG.debug_var(l_log_head,l_progress,'p_distribution_type',p_distribution_type);
2016 END IF;
2017 
2018 l_progress := '010';
2019 
2020 IF (p_distribution_type = g_dist_type_REQUISITION) THEN
2021 
2022    l_progress := '020';
2023    IF g_debug_stmt THEN
2024       PO_DEBUG.debug_stmt(l_log_head,l_progress,'requisitions');
2025    END IF;
2026 
2027    ----------------------------------------------------------------
2028    -- PO_SESSION_GT column mapping
2029    --
2030    -- num1     sequence num of original (main) distribution
2031    -- num2     distribution_id of backing req
2032    -- num3     recreated req's distribution_id
2033    ----------------------------------------------------------------
2034 
2035    l_backing_req_key := PO_CORE_S.get_session_gt_nextval();
2036 
2037    l_progress := '030';
2038 
2039    -- Get the encumbrance-impacted req distributions.
2040 
2041    INSERT INTO PO_SESSION_GT
2042    (  key
2043    ,  num1  -- main dist's sequence_num
2044    ,  num2  -- backing req's distribution_id
2045    )
2046    SELECT
2047       l_backing_req_key
2048    ,  ENC.sequence_num
2049    ,  PRD.distribution_id
2050    FROM
2051       PO_ENCUMBRANCE_GT ENC
2052    ,  PO_REQUISITION_LINES_ALL PRL
2053    ,  PO_REQ_DISTRIBUTIONS_ALL PRD
2054    WHERE PRD.distribution_id = ENC.req_distribution_id  --JOIN
2055    AND PRL.requisition_line_id = PRD.requisition_line_id  --JOIN
2056    AND NVL(PRD.prevent_encumbrance_flag,'N') = 'N'
2057    AND NVL(PRL.closed_code,g_clsd_OPEN) <> g_clsd_FINALLY_CLOSED
2058    AND NVL(PRL.cancel_flag,'N') = 'N'
2059    --bug 3401937: backing docs for Invoice Cancel
2060    AND ( (p_action IN (g_action_RESERVE, g_action_INVOICE_CANCEL,
2061                        g_action_CR_MEMO_CANCEL)
2062           AND PRD.encumbered_flag = 'Y')
2063           -- picks up backing Req for case of PO Unres when Invoice Cancel
2064        OR
2065          (p_action NOT IN (g_action_RESERVE, g_action_INVOICE_CANCEL,
2066                            g_action_CR_MEMO_CANCEL)
2067           AND NVL(PRD.encumbered_flag,'N') = 'N' )
2068           -- for Invoice Cancel, if PO is FC'ed, then backing Req is not
2069           -- encumbered, but we don't act on the backing Req for this case
2070    )
2071    AND ENC.origin_sequence_num IS NULL
2072    AND ENC.prevent_encumbrance_flag = 'N'
2073    ;
2074 
2075    l_progress := '040';
2076 
2077    IF (p_action = g_action_CANCEL) THEN
2078 
2079       l_progress := '050';
2080       IF g_debug_stmt THEN
2081          PO_DEBUG.debug_stmt(l_log_head,l_progress,'cancel w/ recreate demand');
2082       END IF;
2083 
2084       -- The cancel code operates as follows:
2085       --
2086       -- If recreate demand is set to No (i.e., the backing Req is also being
2087       -- cancelled, so do not re-encumber it), then the backing Req's
2088       -- PRL.cancel_flag will have been set to 'I' before the encumbrance
2089       -- code is called, and 'Y' after the encumbrance code is called.
2090       -- (This happens in poccamodify_req.)
2091       -- Will have ignored these distributions by the filter on
2092       -- PRL.cancel_flag above.
2093       --
2094       -- If recreate demand is on, then there are 3 possibilities for
2095       -- the backing Req distribution:
2096       --
2097       --    1. The quantity that is being cancelled on the PO is
2098       --       equal to the quantity that was ordered on the PO.
2099       --       (i.e., nothing on the PO has been delivered or billed.)
2100       --       This is the "qty_zero" case of poccamodify_req.
2101       --       In this case, the old Req is re-used.
2102       --       We want to re-encumber this old Req.
2103       --
2104       --    2. The quantity that has been delivered/billed on the PO is
2105       --       less than the quantity ordered on the Req.
2106       --       This is the "qty_cancelled != 0" case of poccamodify_req.
2107       --       In this case, a new Req line and distribution are created.
2108       --       The new Req has
2109       --       NEW_PRD.source_req_distribution_id = OLD_PRD.distribution_id
2110       --       We want to encumber the new Req.
2111       --
2112       --    3. The quantity that has been delivered/billed on the PO is
2113       --       greater than or equal to the quantity ordered on the Req.
2114       --       We should treat this case identically to the
2115       --       case when recreate demand is off.
2116       --       We do not want to encumber anything in this situation.
2117       --       Modifications will be made to the cancel code to set the
2118       --       PRL.cancel_flag = 'Y' for this case, so that we avoid
2119       --       picking it up in the filter above.
2120       --
2121       -- Given the above, the Req distributions we want to encumber are:
2122       --    a. The Req pointed to by the PO, so long as the Req
2123       --       does not have the cancel_flag set.
2124       --       These were gathered above.
2125       --    b. If the Req distribution from a. has a descendent, then
2126       --       we should use that distribution instead.
2127       --
2128 
2129       -- bug 3426141
2130       -- changed this statement to update num3 instead of updating num2,
2131       -- as there were difficulties in doing this correctly on 8i.
2132 
2133       UPDATE PO_SESSION_GT SCRATCH
2134       SET SCRATCH.num3 =
2135            (  SELECT PRD.distribution_id
2136               FROM PO_REQ_DISTRIBUTIONS_ALL PRD
2137               WHERE PRD.source_req_distribution_id = SCRATCH.num2
2138            )
2139       WHERE SCRATCH.key = l_backing_req_key
2140       ;
2141 
2142       l_progress := '060';
2143 
2144    ELSE
2145       l_progress := '070';
2146       IF g_debug_stmt THEN
2147          PO_DEBUG.debug_stmt(l_log_head,l_progress,'not cancel');
2148       END IF;
2149    END IF;
2150 
2151    l_progress := '080';
2152 
2153    IF g_debug_stmt THEN
2154       SELECT rowid BULK COLLECT INTO PO_DEBUG.g_rowid_tbl
2155       FROM PO_SESSION_GT WHERE key = l_backing_req_key ;
2156 
2157       PO_DEBUG.debug_table(l_log_head,l_progress,'PO_SESSION_GT',
2158             PO_DEBUG.g_rowid_tbl,
2159             po_tbl_varchar30('key','num1','num2','num3')
2160             );
2161    END IF;
2162 
2163    -- Now that we have the correct references in the scratchpad,
2164    -- get them back into PL/SQL for output.
2165 
2166    -- bug 3426141 -- added the NVL to get recreated Reqs from Cancel
2167 
2168    SELECT
2169       SCRATCH.num1
2170    ,  NVL(SCRATCH.num3, SCRATCH.num2)
2171    BULK COLLECT INTO
2172       x_origin_seq_num_tbl
2173    ,  x_dist_id_tbl
2174    FROM PO_SESSION_GT SCRATCH
2175    WHERE SCRATCH.key = l_backing_req_key
2176    ;
2177 
2178    l_progress := '090';
2179 
2180 ELSIF (p_distribution_type = g_dist_type_PLANNED) THEN
2181 
2182    l_progress := '100';
2183    IF g_debug_stmt THEN
2184       PO_DEBUG.debug_stmt(l_log_head,l_progress,'PPOs');
2185    END IF;
2186 
2187    -- Get the relevant backing PPO distributions of Scheduled Releases.
2188 
2189    SELECT
2190       POD.po_distribution_id
2191    ,  SR_DIST.sequence_num
2192    BULK COLLECT INTO
2193       x_dist_id_tbl
2194    ,  x_origin_seq_num_tbl
2195    FROM
2196       PO_DISTRIBUTIONS_ALL POD
2197    ,  PO_LINE_LOCATIONS_ALL POLL
2198    ,  PO_ENCUMBRANCE_GT SR_DIST
2199    WHERE POLL.line_location_id = POD.line_location_id   --JOIN
2200    AND POD.po_distribution_id = SR_DIST.source_distribution_id --JOIN
2201    AND NVL(POD.prevent_encumbrance_flag,'N') = 'N'
2202    AND NVL(POLL.closed_code,g_clsd_OPEN) <> g_clsd_FINALLY_CLOSED
2203    AND NVL(POLL.cancel_flag,'N') = 'N'
2204    --bug 3401937: backing docs for Invoice Cancel
2205    AND ( (p_action IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL)
2206             AND NVL(SR_DIST.closed_code, g_clsd_OPEN) <> g_clsd_FINALLY_CLOSED
2207             AND POD.encumbered_flag = 'Y'
2208             --bug 3568512: filter on enc_flag = 'Y' only for Invoice Cancel case
2209             --for other unreserved backing PPO actions, maitain unencumbered_amount
2210           )
2211       OR (p_action NOT IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL))
2212       )
2213    AND SR_DIST.origin_sequence_num IS NULL
2214    AND SR_DIST.prevent_encumbrance_flag = 'N'
2215    ;
2216 
2217    l_progress := '150';
2218 
2219 ELSIF (p_distribution_type = g_dist_type_AGREEMENT) THEN
2220 
2221    l_progress := '200';
2222    IF g_debug_stmt THEN
2223       PO_DEBUG.debug_stmt(l_log_head,l_progress,'agreements');
2224    END IF;
2225 
2226    -- Get the backing BPA/GA distributions of Blanket Releases/POs.
2227 
2228    SELECT
2229       POD.po_distribution_id
2230    ,  REL_DIST.sequence_num
2231    BULK COLLECT INTO
2232       x_dist_id_tbl
2233    ,  x_origin_seq_num_tbl
2234    FROM
2235       PO_DISTRIBUTIONS_ALL POD
2236    ,  PO_HEADERS_ALL POH
2237    ,  PO_ENCUMBRANCE_GT REL_DIST
2238    WHERE POH.po_header_id = POD.po_header_id       --JOIN
2239    AND POD.po_distribution_id = REL_DIST.agreement_dist_id  --JOIN
2240    AND NVL(POD.prevent_encumbrance_flag,'N') = 'N'
2241    AND NVL(POH.closed_code,g_clsd_OPEN) <> g_clsd_FINALLY_CLOSED
2242    AND NVL(POH.cancel_flag,'N') = 'N'
2243    AND POH.encumbrance_required_flag = 'Y'
2244    --bug 3401937: backing docs for Invoice Cancel
2245    AND ( (p_action IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL)
2246             AND NVL(REL_DIST.closed_code, g_clsd_OPEN) <> g_clsd_FINALLY_CLOSED
2247             AND POD.encumbered_flag = 'Y'
2248             --bug 3568512: filter on enc_flag = 'Y' only for Invoice Cancel case
2249             --for other unreserved backing PPO actions, maitain unencumbered_amount
2250           )
2251       OR (p_action NOT IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL))
2252       )
2253    AND REL_DIST.origin_sequence_num IS NULL
2254    AND REL_DIST.prevent_encumbrance_flag = 'N'
2255    ;
2256 
2257    l_progress := '250';
2258 
2259 ELSE
2260    l_progress := '300';
2261    RAISE PO_CORE_S.g_INVALID_CALL_EXC;
2262 END IF;
2263 
2264 l_progress := '400';
2265 
2266 IF g_debug_stmt THEN
2267    PO_DEBUG.debug_var(l_log_head,l_progress,'x_dist_id_tbl',x_dist_id_tbl);
2268    PO_DEBUG.debug_var(l_log_head,l_progress,'x_origin_seq_num_tbl',x_origin_seq_num_tbl);
2269    PO_DEBUG.debug_end(l_log_head);
2270 END IF;
2271 
2272 EXCEPTION
2273 
2274 WHEN PO_CORE_S.G_INVALID_CALL_EXC THEN
2275    IF g_debug_unexp THEN
2276       PO_DEBUG.debug_exc(l_log_head,l_progress);
2277    END IF;
2278    FND_MESSAGE.set_name('PO', 'PO_ALL_INVALID_PARAMETER');
2279    FND_MESSAGE.set_token('PROCEDURE', l_api_name);
2280    FND_MESSAGE.set_token('PACKAGE', g_pkg_name);
2281    fnd_msg_pub.add;
2282    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2283 
2284 WHEN OTHERS THEN
2285    --add message to the stack and log a debug msg if necessary
2286    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
2287    fnd_msg_pub.add;
2288    RAISE;
2289 
2290 END filter_backing_distributions;
2291 
2292 
2293 
2294 -------------------------------------------------------------------------------
2295 --Start of Comments
2296 --Name: derive_doc_types_from_dist
2297 --Pre-reqs:
2298 --  None.
2299 --Modifies:
2300 --  None.
2301 --Locks:
2302 --  None.
2303 --Function:
2304 --  Derives the document type/subtype given the distribution type.
2305 --Parameters:
2306 --IN:
2307 --p_distribution_type
2308 --  Use the g_dist_type_<> variables, which map to the distribution_type
2309 --  column, except for the following:
2310 --    REQUISITION       for requisitions
2311 --OUT:
2312 --x_doc_type
2313 --  PO_DOCUMENT_TYPES.document_type_code%TYPE
2314 --  Document type.  g_doc_type_<>
2315 --    REQUISITION
2316 --    PA
2317 --    PO
2318 --    RELEASE
2319 --p_doc_subtype
2320 --  PO_HEADERS_ALL.type_lookup_code%TYPE
2321 --  PO_RELEASES_ALL.release_type%TYPE
2322 --  The document subtype.  g_doc_subtype_<>
2323 --    STANDARD          Standard PO
2324 --    PLANNED           Planned PO
2325 --    BLANKET           Blanket Release, Blanket Agreement, Global Agreement
2326 --    SCHEDULED         Scheduled Release
2327 --Testing:
2328 --
2329 --End of Comments
2330 -------------------------------------------------------------------------------
2331 PROCEDURE derive_doc_types_from_dist(
2332    p_distribution_type              IN             VARCHAR2
2333 ,  x_doc_type                       OUT NOCOPY     VARCHAR2
2334 ,  x_doc_subtype                    OUT NOCOPY     VARCHAR2
2335 )
2336 IS
2337 
2338 l_api_name  CONSTANT VARCHAR2(30) := 'DERIVE_DOC_TYPES_FROM_DIST';
2339 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
2340 l_progress  VARCHAR2(3) := '000';
2341 
2342 BEGIN
2343 
2344 IF g_debug_stmt THEN
2345    PO_DEBUG.debug_begin(l_log_head);
2346    PO_DEBUG.debug_var(l_log_head,l_progress,'p_distribution_type',p_distribution_type);
2347 END IF;
2348 
2349 l_progress := '010';
2350 
2351 -- Convert the distribution type into document type and subtype.
2352 
2353 IF (p_distribution_type = g_dist_type_REQUISITION) THEN
2354    x_doc_type := g_doc_type_REQUISITION;
2355    x_doc_subtype := NULL;
2356 ELSIF (p_distribution_type = g_dist_type_AGREEMENT) THEN
2357    x_doc_type := g_doc_type_PA;
2358    x_doc_subtype := g_doc_subtype_BLANKET;
2359 ELSIF (p_distribution_type IN (g_dist_type_BLANKET, g_dist_type_SCHEDULED)) THEN
2360    x_doc_type := g_doc_type_RELEASE;
2361    x_doc_subtype := p_distribution_type;
2362 ELSIF (p_distribution_type IN (g_dist_type_STANDARD, g_dist_type_PLANNED)) THEN
2363    x_doc_type := g_doc_type_PO;
2364    x_doc_subtype := p_distribution_type;
2365 --<Complex Work R12 START>
2366 ELSIF (p_distribution_type = g_dist_type_PREPAYMENT) THEN
2367    x_doc_type := g_doc_type_PO;
2368    x_doc_subtype := g_doc_subtype_STANDARD;
2369 --<Complex Work R12 START>
2370 ELSIF (p_distribution_type = g_dist_type_MIXED_PO_RELEASE) THEN
2371    x_doc_type := g_doc_type_MIXED_PO_RELEASE;
2372    x_doc_subtype := g_doc_subtype_MIXED_PO_RELEASE;
2373 ELSE
2374    RAISE PO_CORE_S.g_INVALID_CALL_EXC;
2375 END IF;
2376 
2377 l_progress := '900';
2378 
2379 IF g_debug_stmt THEN
2380    PO_DEBUG.debug_var(l_log_head,l_progress,'x_doc_type',x_doc_type);
2381    PO_DEBUG.debug_var(l_log_head,l_progress,'x_doc_subtype',x_doc_subtype);
2382    PO_DEBUG.debug_end(l_log_head);
2383 END IF;
2384 
2385 EXCEPTION
2386 
2387 WHEN PO_CORE_S.G_INVALID_CALL_EXC THEN
2388    IF g_debug_unexp THEN
2389       PO_DEBUG.debug_exc(l_log_head,l_progress);
2390    END IF;
2391    FND_MESSAGE.set_name('PO', 'PO_ALL_INVALID_PARAMETER');
2392    FND_MESSAGE.set_token('PROCEDURE', l_api_name);
2393    FND_MESSAGE.set_token('PACKAGE', g_pkg_name);
2394    fnd_msg_pub.add;
2395    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2396 
2397 WHEN OTHERS THEN
2398    --add message to the stack and log a debug msg if necessary
2399    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
2400    fnd_msg_pub.add;
2401    RAISE;
2402 
2403 END derive_doc_types_from_dist;
2404 
2405 
2406 
2407 -------------------------------------------------------------------------------
2408 --Start of Comments
2409 --Name: derive_dist_from_doc_types
2410 --Pre-reqs:
2411 --  None.
2412 --Modifies:
2413 --  None.
2414 --Locks:
2415 --  None.
2416 --Function:
2417 --  Derives the distribution type from the given document type/subtype.
2418 --Parameters:
2419 --IN:
2420 --p_doc_type
2421 --  Document type.  Use g_doc_type_<>
2422 --    REQUISITION
2423 --    PA
2424 --    PO
2425 --    RELEASE
2426 --p_doc_subtype
2427 --  The document subtype.  g_doc_subtype_<>
2428 --    STANDARD          Standard PO
2429 --    PLANNED           Planned PO
2430 --    BLANKET           Blanket Release, Blanket Agreement, Global Agreement
2431 --    SCHEDULED         Scheduled Release
2432 --  This parameter is not checked for requisitions.
2433 --OUT:
2434 --x_distribution_type
2435 --  PO_DISTRIBUTIONS_ALL.distribution_type%TYPE
2436 --  Use the g_dist_type_<> variables, which map to the distribution_type
2437 --  column, except for the following:
2438 --    REQUISITION       for requisitions
2439 --Testing:
2440 --
2441 --End of Comments
2442 -------------------------------------------------------------------------------
2443 PROCEDURE derive_dist_from_doc_types(
2444    p_doc_type                       IN             VARCHAR2
2445 ,  p_doc_subtype                    IN             VARCHAR2
2446 ,  x_distribution_type              OUT NOCOPY     VARCHAR2
2447 )
2448 IS
2449 
2450 l_api_name  CONSTANT VARCHAR2(30) := 'DERIVE_DIST_FROM_DOC_TYPES';
2451 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
2452 l_progress  VARCHAR2(3) := '000';
2453 
2454 BEGIN
2455 
2456 IF g_debug_stmt THEN
2457    PO_DEBUG.debug_begin(l_log_head);
2458    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
2459    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
2460 END IF;
2461 
2462 l_progress := '010';
2463 
2464 -- Convert the document type, subtype into distribution type.
2465 
2466 IF (p_doc_type = g_doc_type_REQUISITION) THEN
2467    x_distribution_type := g_dist_type_REQUISITION;
2468 ELSIF (p_doc_type = g_doc_type_PA) THEN
2469    x_distribution_type := g_dist_type_AGREEMENT;
2470 ELSE
2471    x_distribution_type := p_doc_subtype;
2472 END IF;
2473 
2474 l_progress := '900';
2475 
2476 IF g_debug_stmt THEN
2477    PO_DEBUG.debug_var(l_log_head,l_progress,'x_distribution_type',x_distribution_type);
2478    PO_DEBUG.debug_end(l_log_head);
2479 END IF;
2480 
2481 EXCEPTION
2482 
2483 WHEN OTHERS THEN
2484    --add message to the stack and log a debug msg if necessary
2485    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
2486    fnd_msg_pub.add;
2487    RAISE;
2488 
2489 END derive_dist_from_doc_types;
2490 
2491 
2492 
2493 
2494 --------------------------------------------------------------------------------
2495 --Start of Comments
2496 --Name: do_encumbrance_validations
2497 --Pre-reqs:
2498 --  The encumbrance table may need to be populated with
2499 --  the appropriate data.
2500 --Modifies:
2501 --  PO_ENCUMBRANCE_GT
2502 --  Submission check tables, online report table
2503 --Locks:
2504 --  PO_HEADERS_ALL
2505 --  PO_RELEASES_ALL
2506 --  PO_REQUISITION_HEADERS_ALL
2507 --Function:
2508 --  Performs the validations necessary in order for an encumbrance
2509 --  action to be taken.
2510 --  Most validation failures will raise an exception from this procedure.
2511 --
2512 --  If PO_ENCUMBRANCE_GT contains ids for this encumbrance action
2513 --  (p_check_only_flag = NO and p_use_enc_gt_flag = YES),
2514 --  the table will be replaced with the data for these ids.
2515 --Parameters:
2516 --IN:
2517 --p_action
2518 --  Specifies the action that is being taken on the document.
2519 --  Use the g_action_<> variables (<> = RESERVE, UNRESERVE, ADJUST, etc.).
2520 --p_check_only_flag
2521 --  Indicates whether or not to lock the document header.
2522 --    g_parameter_NO    lock them
2523 --    g_parameter_YES   don't lock them
2524 --  This flag also controls whether or not to do some validations.
2525 --p_doc_type
2526 --  Document type.  Use the g_doc_type_<> variables, where <> is:
2527 --    REQUISITION
2528 --    PA
2529 --    PO
2530 --    RELEASE
2531 --    MIXED_PO_RELEASE  - supported only for Adjust
2532 --p_doc_subtype
2533 --  The document subtype.  Use the g_doc_subtype_<> variables:
2534 --    STANDARD          Standard PO
2535 --    PLANNED           Planned PO
2536 --    BLANKET           Blanket Release, Blanket Agreement, Global Agreement
2537 --    SCHEDULED         Scheduled Release
2538 --    MIXED_PO_RELEASE  supported only for Adjust
2539 --  This parameter is not checked for requisitions.
2540 --p_doc_level
2541 --  The type of ids that are being passed.  Use g_doc_level_<>
2542 --    HEADER
2543 --    LINE
2544 --    SHIPMENT
2545 --    DISTRIBUTION
2546 --  If the encumbrance table has already been populated (Adjust, multiple ids),
2547 --    use NULL.
2548 --p_doc_level_id
2549 --  Id of the doc level type on which the action is being taken.
2550 --  If the encumbrance table has already been populated, use NULL.
2551 --p_use_enc_gt_flag
2552 --  Indicates whether or not the data/ids have already been populated
2553 --  in the encumbrance table.
2554 --    g_parameter_NO    validate the doc_level, doc_level_id
2555 --    g_parameter_YES   validate the data already in the table
2556 --p_validate_document
2557 --  Indicates whether or not to perform the submission checks
2558 --  and particularly useful if the caller already did these checks.
2559 --    g_parameter_NO    skip the checks
2560 --    g_parameter_YES   perform the checks
2561 --p_do_state_check_flag  : Added Bug 3280496
2562 --  Indicates whether or not to permorm the document state checks
2563 --    g_parameter_NO    skip the checks
2564 --    g_parameter_YES   perform the checks
2565 --OUT:
2566 --x_validation_successful_flag
2567 --  Indicates whether or not the encumbrance validations were successful,
2568 --  and the encumbrance action may proceed.
2569 --    g_parameter_NO    validations failed
2570 --    g_parameter_YES   validations succeeded
2571 --x_sub_check_report_id
2572 --  If submission checks were performed, contains the
2573 --  online_report_id for those checks.
2574 --
2575 --Notes:
2576 --
2577 --  bug 3435714:
2578 --
2579 --  The combination of p_check_only_flag and p_use_enc_gt_flag
2580 --  are used to determine if this action is being conducted on multiple ids.
2581 --  e.g., unreserve 2 req lines -- resource finalization/assign contractor.
2582 --
2583 --  There are some bottlenecks in the multiple id scenario,
2584 --  and many things are not supported.
2585 --  What IS supported is do_unreserve for multiple Req lines (same header),
2586 --  and do_reserve for multiple Req lines (same header).
2587 --  The submission checks for Reserve operate at the header level, regardless.
2588 --
2589 --  The action history routine also introduces some limitations,
2590 --  particularly that of everything must belong to the same header.
2591 --    bug 3518116:
2592 --    Req Split is supported for multiple Reqs concurrently (via Sourcing).
2593 --
2594 --Testing:
2595 --
2596 --End of Comments
2597 --------------------------------------------------------------------------------
2598 PROCEDURE do_encumbrance_validations(
2599    p_action                         IN             VARCHAR2
2600 ,  p_check_only_flag                IN             VARCHAR2
2601 ,  p_doc_type                       IN             VARCHAR2
2602 ,  p_doc_subtype                    IN             VARCHAR2
2603 ,  p_doc_level                      IN             VARCHAR2
2604 ,  p_doc_level_id                   IN             NUMBER
2605 ,  p_use_enc_gt_flag                IN             VARCHAR2
2606 ,  p_validate_document              IN             VARCHAR2
2607 ,  p_do_state_check_flag            IN             VARCHAR2 -- Bug 3280496
2608 ,  x_validation_successful_flag     OUT NOCOPY     VARCHAR2
2609 ,  x_sub_check_report_id            OUT NOCOPY     NUMBER
2610 )
2611 IS
2612 
2613 l_api_name  CONSTANT VARCHAR2(30) := 'DO_ENCUMBRANCE_VALIDATIONS';
2614 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
2615 l_progress  VARCHAR2(3) := '000';
2616 
2617 l_enc_on    BOOLEAN;
2618 
2619 -- bug 3435714
2620 l_doc_level             VARCHAR2(30);
2621 l_doc_level_tbl         po_tbl_varchar30;
2622 l_dist_type_tbl         po_tbl_varchar30;
2623 l_count_tbl             po_tbl_number;
2624 l_doc_type              PO_DOCUMENT_TYPES.document_type_code%TYPE;
2625 l_doc_subtype           PO_HEADERS_ALL.type_lookup_code%TYPE;
2626 l_doc_level_id_tbl      po_tbl_number;
2627 l_id_tbl                po_tbl_number;
2628 l_doc_id                NUMBER;
2629 l_multiple_docs_flag    VARCHAR2(1);
2630 
2631 l_sub_check_action      VARCHAR2(4000);
2632 l_msg_data              VARCHAR2(4000);
2633 l_return_status         VARCHAR2(1);
2634 l_sub_check_status      VARCHAR2(1);
2635 
2636 l_doc_check_error_record doc_check_Return_Type;
2637 
2638 l_doc_state_valid    VARCHAR2(1);
2639 
2640 l_exc_code           NUMBER;
2641 l_exc_message_name   FND_NEW_MESSAGES.message_name%TYPE;
2642 l_exc_message_text   FND_NEW_MESSAGES.message_text%TYPE;
2643 
2644 BEGIN
2645 
2646 IF g_debug_stmt THEN
2647    PO_DEBUG.debug_begin(l_log_head);
2648    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
2649    PO_DEBUG.debug_var(l_log_head,l_progress,'p_check_only_flag', p_check_only_flag);
2650    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
2651    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
2652    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level', p_doc_level);
2653    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level_id', p_doc_level_id);
2654    PO_DEBUG.debug_var(l_log_head,l_progress,'p_use_enc_gt_flag', p_use_enc_gt_flag);
2655    PO_DEBUG.debug_var(l_log_head,l_progress,'p_validate_document',p_validate_document);
2656    PO_DEBUG.debug_var(l_log_head,l_progress,'p_do_state_check_flag', p_do_state_check_flag);
2657 END IF;
2658 
2659 l_progress := '010';
2660 
2661 -----------------------------------------------------------------------------
2662 -----------------------------------------------------------------------------
2663 -- Check : Is encumbrance on?
2664 -----------------------------------------------------------------------------
2665 -----------------------------------------------------------------------------
2666 
2667 -- Set up the global variables
2668 -- for the rest of the encumbrance flow.
2669 
2670 PO_DOCUMENT_FUNDS_PVT.g_req_encumbrance_on
2671    := PO_CORE_S.is_encumbrance_on(
2672          p_doc_type => g_doc_type_REQUISITION
2673       ,  p_org_id => NULL
2674       );
2675 
2676 l_progress := '020';
2677 
2678 PO_DOCUMENT_FUNDS_PVT.g_po_encumbrance_on
2679    := PO_CORE_S.is_encumbrance_on(
2680          p_doc_type => g_doc_type_PO
2681       ,  p_org_id => NULL
2682       );
2683 
2684 l_progress := '030';
2685 
2686 PO_DOCUMENT_FUNDS_PVT.g_pa_encumbrance_on
2687    := PO_CORE_S.is_encumbrance_on(
2688          p_doc_type => g_doc_type_PA
2689       ,  p_org_id => NULL
2690       );
2691 
2692 l_progress := '040';
2693 
2694 IF g_debug_stmt THEN
2695    PO_DEBUG.debug_var(l_log_head,l_progress,'req encumbrance'
2696             ,  PO_DOCUMENT_FUNDS_PVT.g_req_encumbrance_on);
2697    PO_DEBUG.debug_var(l_log_head,l_progress,'po encumbrance'
2698             ,  PO_DOCUMENT_FUNDS_PVT.g_po_encumbrance_on);
2699    PO_DEBUG.debug_var(l_log_head,l_progress,'pa encumbrance'
2700             ,  PO_DOCUMENT_FUNDS_PVT.g_pa_encumbrance_on);
2701 END IF;
2702 
2703 IF (p_doc_type = g_doc_type_REQUISITION) THEN
2704 
2705    l_progress := '050';
2706 
2707    l_enc_on := PO_DOCUMENT_FUNDS_PVT.g_req_encumbrance_on;
2708 
2709 ELSIF (p_doc_type = g_doc_type_PA) THEN
2710 
2711    l_progress := '060';
2712 
2713    l_enc_on := PO_DOCUMENT_FUNDS_PVT.g_pa_encumbrance_on;
2714 
2715 ELSE
2716 
2717    l_progress := '070';
2718 
2719    l_enc_on := PO_DOCUMENT_FUNDS_PVT.g_po_encumbrance_on;
2720 
2721 END IF;
2722 
2723 IF g_debug_stmt THEN
2724    PO_DEBUG.debug_var(l_log_head,l_progress,'l_enc_on',l_enc_on);
2725 END IF;
2726 
2727 l_progress := '080';
2728 
2729 IF (NOT l_enc_on) THEN
2730 
2731    l_progress := '090';
2732 
2733    l_exc_message_name := 'PO_ENC_NA_OU';
2734    l_exc_code := g_ENC_VALIDATION_EXC_CODE;
2735    RAISE FND_API.G_EXC_ERROR;
2736 
2737 ELSE
2738    l_progress := '095';
2739    IF g_debug_stmt THEN
2740       PO_DEBUG.debug_stmt(l_log_head,l_progress,'encumbrance on');
2741    END IF;
2742 END IF;
2743 
2744 l_progress := '099';
2745 
2746 
2747 -- bug 3435714 START
2748 
2749 IF (p_use_enc_gt_flag = g_parameter_NO) THEN
2750    l_progress := 'a00';
2751    l_doc_level := p_doc_level;
2752    l_doc_level_id_tbl := po_tbl_number( p_doc_level_id );
2753 END IF;
2754 
2755 l_progress := 'a10';
2756 
2757 -----------------------------------------------------------------------------
2758 -----------------------------------------------------------------------------
2759 -- Check:  "do" on multiple ids
2760 --   - doc_level, doc_type must be constant
2761 --     This requirement makes the state checks easier.
2762 --   - additional checks for this scenario (same header_id, etc.)
2763 --     will be done as part of other use_enc_gt_flag = YES checks
2764 -----------------------------------------------------------------------------
2765 -----------------------------------------------------------------------------
2766 
2767 IF (     p_action NOT IN (g_action_ADJUST, g_action_REQ_SPLIT)
2768    AND   p_check_only_flag = g_parameter_NO
2769    AND   p_use_enc_gt_flag = g_parameter_YES
2770 ) THEN
2771 
2772    l_progress := 'a20';
2773    IF g_debug_stmt THEN
2774       PO_DEBUG.debug_stmt(l_log_head,l_progress,'multiple id do action');
2775       PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT'
2776          ,PO_DEBUG.g_all_rows
2777          ,po_tbl_varchar30('distribution_type','doc_level','doc_level_id')
2778          );
2779    END IF;
2780 
2781    -- Make sure the doc_level, doc_type are constant.
2782 
2783    SELECT
2784       ENC.doc_level
2785    ,  ENC.distribution_type
2786    ,  COUNT(*)
2787    BULK COLLECT INTO
2788       l_doc_level_tbl
2789    ,  l_dist_type_tbl
2790    ,  l_count_tbl
2791    FROM PO_ENCUMBRANCE_GT ENC
2792    GROUP BY ENC.doc_level, ENC.distribution_type
2793    ;
2794 
2795    l_progress := 'a30';
2796    IF g_debug_stmt THEN
2797       PO_DEBUG.debug_var(l_log_head,l_progress,'l_doc_level_tbl',l_doc_level_tbl);
2798       PO_DEBUG.debug_var(l_log_head,l_progress,'l_dist_type_tbl',l_dist_type_tbl);
2799       PO_DEBUG.debug_var(l_log_head,l_progress,'l_count_tbl',l_count_tbl);
2800    END IF;
2801 
2802    IF (l_doc_level_tbl.COUNT <> 1) THEN
2803       l_progress := 'a35';
2804       l_exc_code := g_INVALID_CALL_EXC_CODE;
2805       RAISE FND_API.G_EXC_ERROR;
2806    END IF;
2807 
2808    l_doc_level := l_doc_level_tbl(1);
2809 
2810    l_progress := 'a40';
2811 
2812    -- Make sure we're not trying to act on the same entity twice.
2813 
2814    SELECT DISTINCT ENC.doc_level_id
2815    BULK COLLECT INTO l_doc_level_id_tbl
2816    FROM PO_ENCUMBRANCE_GT ENC
2817    ;
2818 
2819    l_progress := 'a50';
2820 
2821    IF (l_doc_level_id_tbl.COUNT <> l_count_tbl(1)) THEN
2822       l_progress := 'a55';
2823       l_exc_code := g_INVALID_CALL_EXC_CODE;
2824       RAISE FND_API.G_EXC_ERROR;
2825    END IF;
2826 
2827    l_progress := 'a60';
2828 
2829    -- After verifying that the ids were reasonable,
2830    -- we will fill the table with data from the base tables.
2831    -- Then we can proceed as normal.
2832 
2833    -- We've already gathered the ids from the table, so now
2834    -- we should clear it for the normal encumbrance flow.
2835    -- (i.e., DELETE FROM PO_ENCUMBRANCE_GT)
2836 
2837    delete_encumbrance_gt();
2838 
2839    -- Now fill the table up with all of the info.
2840 
2841    l_progress := 'a70';
2842 
2843    derive_doc_types_from_dist(
2844       p_distribution_type => l_dist_type_tbl(1)
2845    ,  x_doc_type => l_doc_type
2846    ,  x_doc_subtype => l_doc_subtype
2847    );
2848 
2849    l_progress := 'a80';
2850 
2851    PO_DOCUMENT_FUNDS_PVT.populate_encumbrance_gt(
2852       x_return_status => l_return_status
2853    ,  p_doc_type => l_doc_type
2854    ,  p_doc_level => l_doc_level
2855    ,  p_doc_level_id_tbl => l_doc_level_id_tbl
2856    ,  p_adjustment_status_tbl => po_tbl_varchar5( NULL )
2857    ,  p_check_only_flag => g_parameter_NO
2858    );
2859 
2860    l_progress := 'a90';
2861 
2862 END IF;
2863 
2864 -- bug 3435714 END
2865 
2866 l_progress := '100';
2867 
2868 
2869 -----------------------------------------------------------------------------
2870 -----------------------------------------------------------------------------
2871 -- Check:  does the BPA/GA have encumbrance_required_flag set?
2872 -----------------------------------------------------------------------------
2873 -----------------------------------------------------------------------------
2874 
2875 -- If trying to do something on a BPA/GA,
2876 -- make sure it has a distribution and the header's enc_required is YES.
2877 -- Be careful not to pick up Release distributions.
2878 
2879 IF (     p_action <> g_action_ADJUST
2880    AND   p_doc_type = g_doc_type_PA
2881    AND   p_check_only_flag = g_parameter_NO
2882 ) THEN
2883 
2884    l_progress := '110';
2885    IF g_debug_stmt THEN
2886       PO_DEBUG.debug_stmt(l_log_head,l_progress,'doc type PA');
2887    END IF;
2888 
2889    IF (p_use_enc_gt_flag = g_parameter_YES) THEN
2890       l_doc_id := l_doc_level_id_tbl(1);
2891    ELSE
2892       l_doc_id := p_doc_level_id;
2893    END IF;
2894 
2895    l_progress := '120';
2896    IF g_debug_stmt THEN
2897       PO_DEBUG.debug_var(l_log_head,l_progress,'l_doc_id',l_doc_id);
2898    END IF;
2899 
2900    -- actions on PAs only allowed at the header level
2901    IF (l_doc_level <> g_doc_level_HEADER) THEN
2902       l_progress := '125';
2903       l_exc_code := g_INVALID_CALL_EXC_CODE;
2904       RAISE FND_API.G_EXC_ERROR;
2905    END IF;
2906 
2907    l_progress := '130';
2908 
2909    SELECT POD.po_distribution_id
2910    BULK COLLECT INTO l_id_tbl
2911    FROM
2912       PO_DISTRIBUTIONS_ALL POD
2913    ,  PO_HEADERS_ALL POH
2914    WHERE POD.po_header_id = l_doc_id
2915    AND   POD.distribution_type = g_dist_type_AGREEMENT
2916    AND   POH.po_header_id = POD.po_header_id
2917    AND   POH.encumbrance_required_flag = 'Y'
2918    ;
2919 
2920    l_progress := '140';
2921    IF g_debug_stmt THEN
2922       PO_DEBUG.debug_var(l_log_head,l_progress,'l_id_tbl',l_id_tbl);
2923    END IF;
2924 
2925    IF (l_id_tbl.COUNT <> 1) THEN
2926 
2927       l_progress := '150';
2928 
2929       l_exc_message_name := 'PO_ENC_NA_DOC';
2930       l_exc_code := g_ENC_VALIDATION_EXC_CODE;
2931       RAISE FND_API.G_EXC_ERROR;
2932 
2933    ELSE
2934       l_progress := '160';
2935       IF g_debug_stmt THEN
2936          PO_DEBUG.debug_stmt(l_log_head,l_progress,'PA valid');
2937       END IF;
2938    END IF;
2939 
2940    l_progress := '170';
2941 
2942 ELSE
2943    l_progress := '180';
2944    IF g_debug_stmt THEN
2945       PO_DEBUG.debug_stmt(l_log_head,l_progress,'not PA');
2946    END IF;
2947 END IF;
2948 
2949 l_progress := '200';
2950 
2951 -----------------------------------------------------------------------------
2952 -----------------------------------------------------------------------------
2953 -- Check:  make sure the encumbrance table is not being used inappropriately
2954 -----------------------------------------------------------------------------
2955 -----------------------------------------------------------------------------
2956 
2957 -- Multiple documents are only acceptable for check actions.
2958 -- Reasons for this include submission checks and action history updates.
2959 --    bug 3518116:
2960 --    Req Split supports multiple Reqs concurrently (Sourcing requirement).
2961 
2962 IF (     p_action <> g_action_REQ_SPLIT
2963    AND   p_check_only_flag = g_parameter_NO
2964    AND   p_use_enc_gt_flag = g_parameter_YES
2965 ) THEN
2966 
2967    l_progress := '210';
2968    IF g_debug_stmt THEN
2969       PO_DEBUG.debug_stmt(l_log_head,l_progress,'validate single doc');
2970    END IF;
2971 
2972    SELECT DECODE( p_doc_type
2973                ,  g_doc_type_RELEASE, ENC.po_release_id
2974                ,  ENC.header_id
2975                )
2976    INTO l_doc_id
2977    FROM PO_ENCUMBRANCE_GT ENC
2978    WHERE rownum = 1
2979    ;
2980 
2981    l_progress := '220';
2982    IF g_debug_stmt THEN
2983       PO_DEBUG.debug_var(l_log_head,l_progress,'l_doc_id',l_doc_id);
2984    END IF;
2985 
2986    l_multiple_docs_flag := 'N';
2987 
2988    BEGIN
2989 
2990       l_progress := '230';
2991       IF g_debug_stmt THEN
2992          PO_DEBUG.debug_stmt(l_log_head,l_progress,'checking multiple docs');
2993       END IF;
2994 
2995       IF (p_doc_type = g_doc_type_RELEASE) THEN
2996 
2997          l_progress := '240';
2998          IF g_debug_stmt THEN
2999             PO_DEBUG.debug_stmt(l_log_head,l_progress,'checking release');
3000          END IF;
3001 
3002          SELECT 'Y'
3003          INTO l_multiple_docs_flag
3004          FROM PO_ENCUMBRANCE_GT ENC
3005          WHERE (ENC.po_release_id <> l_doc_id
3006             OR ENC.po_release_id IS NULL
3007             )
3008          AND rownum = 1;
3009 
3010          l_progress := '250';
3011 
3012       ELSE
3013 
3014          l_progress := '260';
3015          IF g_debug_stmt THEN
3016             PO_DEBUG.debug_stmt(l_log_head,l_progress,'checking non-release');
3017          END IF;
3018 
3019          SELECT 'Y'
3020          INTO l_multiple_docs_flag
3021          FROM PO_ENCUMBRANCE_GT ENC
3022          WHERE (ENC.header_id <> l_doc_id
3023             OR ENC.header_id IS NULL
3024             )
3025          AND rownum = 1;
3026 
3027          l_progress := '270';
3028 
3029       END IF;
3030 
3031       l_progress := '275';
3032       IF g_debug_stmt THEN
3033          PO_DEBUG.debug_var(l_log_head,l_progress,'l_multiple_docs_flag',l_multiple_docs_flag);
3034       END IF;
3035 
3036    EXCEPTION
3037       WHEN NO_DATA_FOUND THEN
3038          l_multiple_docs_flag := 'N';
3039    END;
3040 
3041    l_progress := '280';
3042    IF g_debug_stmt THEN
3043       PO_DEBUG.debug_var(l_log_head,l_progress,'l_multiple_docs_flag',l_multiple_docs_flag);
3044    END IF;
3045 
3046    IF (l_multiple_docs_flag = 'Y') THEN
3047 
3048       l_progress := '285';
3049 
3050       l_exc_message_name := 'PO_ENC_API_MULTIPLE_DOCS';
3051       l_exc_code := g_ENC_VALIDATION_EXC_CODE;
3052       RAISE FND_API.G_EXC_ERROR;
3053 
3054    ELSE
3055       l_progress := '290';
3056       IF g_debug_stmt THEN
3057          PO_DEBUG.debug_stmt(l_log_head,l_progress,'no multiple docs');
3058       END IF;
3059    END IF;
3060 
3061    l_progress := '295';
3062 
3063 ELSE
3064    l_progress := '299';
3065    IF g_debug_stmt THEN
3066       PO_DEBUG.debug_stmt(l_log_head,l_progress,'not validating single doc');
3067    END IF;
3068 END IF;
3069 
3070 l_progress := '300';
3071 
3072 
3073 -----------------------------------------------------------------------------
3074 -----------------------------------------------------------------------------
3075 -- Lock the doc header, for non-checks and non-adjust.
3076 -----------------------------------------------------------------------------
3077 -----------------------------------------------------------------------------
3078 
3079 IF (     p_action NOT IN (g_action_ADJUST, g_action_REQ_SPLIT)
3080    AND   p_check_only_flag = g_parameter_NO
3081 ) THEN
3082 
3083    l_progress := '310';
3084    IF g_debug_stmt THEN
3085       PO_DEBUG.debug_stmt(l_log_head,l_progress,'locking header');
3086    END IF;
3087 
3088    IF (p_use_enc_gt_flag = g_parameter_NO) THEN
3089 
3090       l_progress := '320';
3091 
3092       PO_CORE_S.get_document_ids(
3093          p_doc_type => p_doc_type
3094       ,  p_doc_level => p_doc_level
3095       ,  p_doc_level_id_tbl => po_tbl_number( p_doc_level_id )
3096       ,  x_doc_id_tbl => l_id_tbl
3097       );
3098 
3099       l_progress := '330';
3100 
3101       l_doc_id := l_id_tbl(1);
3102 
3103    END IF;
3104 
3105    -- If use_enc_gt_flag was YES, we've already retrieved the doc_id.
3106 
3107    l_progress := '340';
3108 
3109    PO_LOCKS.lock_headers(
3110       p_doc_type => p_doc_type
3111    ,  p_doc_level => g_doc_level_HEADER
3112    ,  p_doc_level_id_tbl => po_tbl_number( l_doc_id )
3113    );
3114 
3115    l_progress := '350';
3116 
3117 ELSE
3118    l_progress := '360';
3119    IF g_debug_stmt THEN
3120       PO_DEBUG.debug_stmt(l_log_head,l_progress,'not locking doc');
3121    END IF;
3122 END IF;
3123 
3124 l_progress := '400';
3125 
3126 -- Do the state check before submission check, since it should be quicker.
3127 
3128 -----------------------------------------------------------------------------
3129 -----------------------------------------------------------------------------
3130 -- Check: document state check (aka. status check)
3131 -----------------------------------------------------------------------------
3132 -----------------------------------------------------------------------------
3133 
3134 -- Bug 3280496: Added p_do_state_check condition
3135 
3136 IF (     p_check_only_flag = g_parameter_NO
3137    AND   p_action IN (g_action_RESERVE, g_action_UNRESERVE)
3138    AND   p_do_state_check_flag <> g_parameter_NO
3139 ) THEN
3140 
3141    l_progress := '410';
3142 
3143    -- bug 3435714
3144 
3145    IF (p_use_enc_gt_flag = g_parameter_NO) THEN
3146       l_doc_type := p_doc_type;
3147       l_doc_subtype := p_doc_subtype;
3148    END IF;
3149 
3150    -- If use_enc_gt_flag is YES (do on multiple ids),
3151    -- the type/subtype have already been set.
3152 
3153    l_progress := '415';
3154 
3155    check_doc_state(
3156       p_action => p_action
3157    ,  p_doc_type => l_doc_type
3158    ,  p_doc_subtype => l_doc_subtype
3159    ,  p_doc_level => l_doc_level
3160    ,  p_doc_level_id_tbl => l_doc_level_id_tbl
3161    ,  x_valid_state_flag => l_doc_state_valid
3162    );
3163 
3164    l_progress := '420';
3165 
3166    IF (NVL(l_doc_state_valid,g_doc_state_valid_NO) <> g_doc_state_valid_YES)
3167    THEN
3168 
3169       l_progress := '430';
3170 
3171       l_exc_message_name := 'PO_ALL_INVALID_DOC_STATE';
3172       l_exc_code := g_ENC_VALIDATION_EXC_CODE;
3173       RAISE FND_API.G_EXC_ERROR;
3174 
3175    ELSE
3176       l_progress := '440';
3177       IF g_debug_stmt THEN
3178          PO_DEBUG.debug_stmt(l_log_head,l_progress,'state check passed');
3179       END IF;
3180    END IF;
3181 
3182    l_progress := '450';
3183 
3184 ELSE
3185    l_progress := '460';
3186    IF g_debug_stmt THEN
3187       PO_DEBUG.debug_stmt(l_log_head,l_progress,'skipping state check');
3188    END IF;
3189 END IF;
3190 
3191 l_progress := '500';
3192 
3193 -----------------------------------------------------------------------------
3194 -----------------------------------------------------------------------------
3195 -- Check: document completeness check / submission check
3196 -----------------------------------------------------------------------------
3197 -----------------------------------------------------------------------------
3198 
3199 IF (     p_validate_document = g_parameter_YES
3200    AND   p_check_only_flag = g_parameter_NO
3201 ) THEN
3202 
3203    l_progress := '510';
3204    IF g_debug_stmt THEN
3205       PO_DEBUG.debug_stmt(l_log_head,l_progress,'doing doc checks');
3206    END IF;
3207 
3208    -- Initialize the return variables.
3209 
3210    l_sub_check_status := NULL;
3211    l_return_status := FND_API.G_RET_STS_SUCCESS;
3212 
3213    -- Set up the submission check call.
3214 
3215    l_progress := '520';
3216 
3217    IF (p_action = g_action_RESERVE) THEN
3218 
3219       l_progress := '525';
3220 
3221       l_sub_check_action
3222          := PO_DOCUMENT_CHECKS_GRP.g_action_DOC_SUBMISSION_CHECK;
3223 
3224       -- While locking the doc header, we already retrieved the doc id.
3225       -- Reserve submission checks are only defined at the header level.
3226 
3227       l_doc_level := g_doc_level_HEADER;
3228       l_doc_level_id_tbl := po_tbl_number( l_doc_id );
3229 
3230    ELSIF (  p_action = g_action_UNRESERVE
3231       AND   p_doc_type IN (g_doc_type_PO, g_doc_type_RELEASE)
3232    ) THEN
3233       -- Unreserve submission check is undefined for Reqs and BPAs.
3234 
3235       l_progress := '530';
3236 
3237       l_sub_check_action := PO_DOCUMENT_CHECKS_GRP.g_action_UNRESERVE;
3238 
3239       -- l_doc_level, l_doc_level_id_tbl have already been set
3240 
3241    ELSE
3242 
3243       l_progress := '535';
3244 
3245       l_sub_check_action := NULL;
3246 
3247    END IF;
3248 
3249    IF g_debug_stmt THEN
3250       PO_DEBUG.debug_var(l_log_head,l_progress,'l_sub_check_action',l_sub_check_action);
3251    END IF;
3252 
3253    l_progress := '540';
3254 
3255    -- Make the submission check call.
3256 
3257    IF (l_sub_check_action IS NOT NULL) THEN
3258 
3259       l_progress := '550';
3260       IF g_debug_stmt THEN
3261          PO_DEBUG.debug_stmt(l_log_head,l_progress,'starting sub check loop');
3262       END IF;
3263 
3264       -- bug 3435714
3265       -- Allowing multiple ids, but submission check isn't designed for this.
3266       -- Reserve submission check can only act at the header level.
3267       -- For Unreserve, we need to call the submission check for
3268       -- each id we are acting on.
3269 
3270       FOR i IN 1 .. l_doc_level_id_tbl.COUNT LOOP
3271 
3272          PO_DOCUMENT_CHECKS_GRP.po_submission_check(
3273             p_api_version => 1.1
3274          ,  p_action_requested => l_sub_check_action
3275          ,  p_document_type => l_doc_type
3276          ,  p_document_subtype => l_doc_subtype -- doesn't matter for reqs
3277          ,  p_document_level => l_doc_level
3278          ,  p_document_level_id => l_doc_level_id_tbl(i)
3279          ,  p_org_id => NULL
3280          ,  p_requested_changes => NULL
3281          ,  p_check_asl => TRUE
3282          ,  x_return_status => l_return_status
3283          ,  x_sub_check_status => l_sub_check_status
3284          ,  x_msg_data => l_msg_data
3285          ,  x_online_report_id => x_sub_check_report_id
3286          ,  x_doc_check_error_record => l_doc_check_error_record
3287          );
3288          --<bug#5487838 START>
3289          --We need to mark all these submission check errors are and
3290          --set the show_in_psa_flag='Y' so that these errors are visible
3291          --in the psa bc error report.
3292          UPDATE po_online_report_text
3293          SET show_in_psa_flag='Y'
3294          WHERE ONLINE_report_id=x_sub_check_report_id;
3295          --<bug#5487838 END>
3296          IF g_debug_stmt THEN
3297             PO_DEBUG.debug_stmt(l_log_head,l_progress,
3298                'Submission check results (i = ' || TO_CHAR(i) || ')');
3299             PO_DEBUG.debug_var(l_log_head,l_progress,'l_sub_check_action',l_sub_check_action);
3300             PO_DEBUG.debug_var(l_log_head,l_progress,'l_doc_type',l_doc_type);
3301             PO_DEBUG.debug_var(l_log_head,l_progress,'l_doc_subtype',l_doc_subtype);
3302             PO_DEBUG.debug_var(l_log_head,l_progress,'l_doc_level',l_doc_level);
3303             PO_DEBUG.debug_var(l_log_head,l_progress,'l_doc_level_id_tbl(i)',l_doc_level_id_tbl(i));
3304             PO_DEBUG.debug_var(l_log_head,l_progress,'l_return_status',l_return_status);
3305             PO_DEBUG.debug_var(l_log_head,l_progress,'l_sub_check_status',l_sub_check_status);
3306             PO_DEBUG.debug_var(l_log_head,l_progress,'l_msg_data',l_msg_data);
3307             PO_DEBUG.debug_var(l_log_head,l_progress,'x_sub_check_report_id',x_sub_check_report_id);
3308          END IF;
3309 
3310          IF (l_sub_check_status <> FND_API.G_RET_STS_SUCCESS) THEN
3311             l_progress := '560';
3312             l_exc_code := g_SUBMISSION_CHECK_EXC_CODE;
3313             RAISE FND_API.G_EXC_ERROR;
3314          ELSIF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
3315             l_progress := '570';
3316             l_exc_message_name := 'PO_ALL_INVALID_DOC_STATE';
3317             l_exc_code := g_ENC_VALIDATION_EXC_CODE;
3318             RAISE FND_API.G_EXC_ERROR;
3319          END IF;
3320 
3321       END LOOP;
3322 
3323       l_progress := '580';
3324       IF g_debug_stmt THEN
3325          PO_DEBUG.debug_stmt(l_log_head,l_progress,'finished sub check loop');
3326       END IF;
3327 
3328    ELSE
3329       l_progress := '585';
3330       IF g_debug_stmt THEN
3331          PO_DEBUG.debug_stmt(l_log_head,l_progress,'not performing sub check');
3332       END IF;
3333    END IF;
3334 
3335    l_progress := '590';
3336 
3337 ELSE
3338    l_progress := '600';
3339    IF g_debug_stmt THEN
3340       PO_DEBUG.debug_stmt(l_log_head,l_progress,'not validating doc');
3341    END IF;
3342 END IF;
3343 
3344 l_progress := '900';
3345 
3346 -- If we've made it this far without throwing an exception,
3347 -- we've passed all of the checks.
3348 
3349 x_validation_successful_flag := g_parameter_YES;
3350 
3351 IF g_debug_stmt THEN
3352    PO_DEBUG.debug_var(l_log_head,l_progress,'x_validation_successful_flag',x_validation_successful_flag);
3353    PO_DEBUG.debug_var(l_log_head,l_progress,'x_sub_check_report_id',x_sub_check_report_id);
3354    PO_DEBUG.debug_end(l_log_head);
3355 END IF;
3356 
3357 EXCEPTION
3358 WHEN OTHERS THEN
3359    IF g_debug_unexp THEN
3360       PO_DEBUG.debug_exc(l_log_head,l_progress);
3361    END IF;
3362 
3363    x_validation_successful_flag := g_parameter_NO;
3364 
3365    IF (l_exc_code = g_SUBMISSION_CHECK_EXC_CODE) THEN
3366       l_exc_message_name := 'PO_ALL_INVALID_DOC_STATE';
3367       -- If there was a submission check error,
3368       -- make sure there is an online report id.
3369       IF (x_sub_check_report_id IS NULL) THEN
3370          FND_MESSAGE.set_name('PO', l_exc_message_name);
3371          l_exc_message_text := FND_MESSAGE.get;
3372          PO_ENCUMBRANCE_POSTPROCESSING.create_exception_report(
3373             p_message_text       => l_exc_message_text
3374          ,  p_user_id            => NULL
3375          ,  x_online_report_id   => x_sub_check_report_id
3376          );
3377       END IF;
3378    END IF;
3379 
3380    IF g_debug_stmt THEN
3381       PO_DEBUG.debug_var(l_log_head,l_progress,'l_exc_code',l_exc_code);
3382       PO_DEBUG.debug_var(l_log_head,l_progress,'l_exc_message_name',l_exc_message_name);
3383       PO_DEBUG.debug_var(l_log_head,l_progress,'x_validation_successful_flag',x_validation_successful_flag);
3384       PO_DEBUG.debug_var(l_log_head,l_progress,'x_sub_check_report_id',x_sub_check_report_id);
3385    END IF;
3386 
3387    -- Prepare the message to put on the API message list.
3388    IF (l_exc_code IN (g_ENC_VALIDATION_EXC_CODE,g_SUBMISSION_CHECK_EXC_CODE)) THEN
3389       FND_MESSAGE.set_name('PO', l_exc_message_name);
3390    ELSIF (l_exc_code = g_INVALID_CALL_EXC_CODE) THEN
3391       FND_MESSAGE.set_name('PO', 'PO_ALL_INVALID_PARAMETER');
3392       FND_MESSAGE.set_token('PROCEDURE', l_api_name);
3393       FND_MESSAGE.set_token('PACKAGE', g_pkg_name);
3394    ELSE -- no exception code
3395       -- log a debug msg if necessary and set the dictionary message
3396       po_message_s.sql_error(g_pkg_name,l_api_name,l_progress,SQLCODE,SQLERRM);
3397    END IF;
3398 
3399    -- Add the message that was set to the API message list.
3400    FND_MSG_PUB.add;
3401 
3402    -- RAISE the exception, if necessary.
3403    IF (NVL(l_exc_code,g_INVALID_CALL_EXC_CODE) <> g_SUBMISSION_CHECK_EXC_CODE) THEN
3404       RAISE;
3405    END IF;
3406 
3407 END do_encumbrance_validations;
3408 
3409 
3410 
3411 --------------------------------------------------------------------------------
3412 --Start of Comments
3413 --Name: check_doc_state
3414 --Pre-reqs:
3415 --  None.
3416 --Modifies:
3417 --  None.
3418 --Locks:
3419 --  None.
3420 --Function:
3421 --  Performs the encumbrance doc state check.
3422 --Parameters:
3423 --IN:
3424 --p_action
3425 --  Specifies the action that is being taken on the document.
3426 --  Use the g_action_<> variables (<> = RESERVE, UNRESERVE, ADJUST, etc.).
3427 --p_doc_type
3428 --  Document type.  Use the g_doc_type_<> variables, where <> is:
3429 --    REQUISITION
3430 --    PA
3431 --    PO
3432 --    RELEASE
3433 --p_doc_subtype
3434 --  The document subtype.  Use the g_doc_subtype_<> variables:
3435 --    STANDARD          Standard PO
3436 --    PLANNED           Planned PO
3437 --    BLANKET           Blanket Release, Blanket Agreement, Global Agreement
3438 --    SCHEDULED         Scheduled Release
3439 --  This parameter is not checked for requisitions.
3440 --p_doc_level
3441 --  The type of ids that are being passed.  Use g_doc_level_<>
3442 --    HEADER
3443 --    LINE
3444 --    SHIPMENT
3445 --    DISTRIBUTION
3446 --p_doc_level_id_tbl
3447 --  Table of ids corresponding to the the doc level on which to perform
3448 --  the checks.
3449 --OUT:
3450 --x_valid_state_flag
3451 --  Indicates whether or not the state check passed.
3452 --  VARCHAR2(1)
3453 --Testing:
3454 --
3455 --End of Comments
3456 --------------------------------------------------------------------------------
3457 PROCEDURE check_doc_state(
3458    p_action                         IN             VARCHAR2
3459 ,  p_doc_type                       IN             VARCHAR2
3460 ,  p_doc_subtype                    IN             VARCHAR2
3461 ,  p_doc_level                      IN             VARCHAR2
3462 ,  p_doc_level_id_tbl               IN             po_tbl_number
3463 ,  x_valid_state_flag               OUT NOCOPY     VARCHAR2
3464 )
3465 IS
3466 
3467 l_api_name  CONSTANT VARCHAR2(30) := 'CHECK_DOC_STATE';
3468 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
3469 l_progress  VARCHAR2(3) := '000';
3470 
3471 l_return_status         VARCHAR2(1);
3472 
3473 l_status_rec            PO_STATUS_REC_TYPE;
3474 l_msg_count             NUMBER;
3475 l_msg_data              VARCHAR2(4000);
3476 
3477 l_empty_tbl             po_tbl_number := NULL;
3478 l_header_id_tbl         po_tbl_number := NULL;
3479 l_release_id_tbl        po_tbl_number := NULL;
3480 l_line_id_tbl           po_tbl_number := NULL;
3481 l_line_location_id_tbl  po_tbl_number := NULL;
3482 l_distribution_id_tbl   po_tbl_number := NULL;
3483 
3484 l_doc_id_tbl            po_tbl_number;
3485 
3486 l_mode               VARCHAR2(30);
3487 
3488 BEGIN
3489 
3490 IF g_debug_stmt THEN
3491    PO_DEBUG.debug_begin(l_log_head);
3492    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
3493    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
3494    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
3495    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level', p_doc_level);
3496    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level_id_tbl', p_doc_level_id_tbl);
3497 END IF;
3498 
3499 l_progress := '010';
3500 
3501 -- In the Pro*C status checks, the shipment-level
3502 -- encumbered_flag was also checked.
3503 -- This is no longer being done.
3504 
3505 -- Set up the parameters to the doc state check API.
3506 
3507 -- Set all of the appropriate IDs, as the doc state check API requires them.
3508 
3509 IF (p_doc_level = g_doc_level_HEADER) THEN
3510    l_progress := '020';
3511    l_doc_id_tbl := p_doc_level_id_tbl;
3512 ELSE
3513    -- the doc level is lower than header, so get the header id.
3514    l_progress := '030';
3515 
3516    PO_CORE_S.get_document_ids(
3517       p_doc_type           => p_doc_type
3518    ,  p_doc_level          => p_doc_level
3519    ,  p_doc_level_id_tbl   => p_doc_level_id_tbl
3520    ,  x_doc_id_tbl         => l_doc_id_tbl
3521    );
3522 
3523    IF (p_doc_level = g_doc_level_LINE) THEN
3524       l_progress := '040';
3525       l_line_id_tbl := p_doc_level_id_tbl;
3526    ELSE
3527       -- the doc level is lower than line
3528       l_progress := '050';
3529 
3530       IF (p_doc_type <> g_doc_type_RELEASE) THEN
3531          -- releases don't have lines
3532          l_progress := '060';
3533 
3534          PO_CORE_S.get_line_ids(
3535             p_doc_type           => p_doc_type
3536          ,  p_doc_level          => p_doc_level
3537          ,  p_doc_level_id_tbl   => p_doc_level_id_tbl
3538          ,  x_line_id_tbl        => l_line_id_tbl
3539          );
3540 
3541       END IF;
3542 
3543       IF (p_doc_level = g_doc_level_SHIPMENT) THEN
3544          l_progress := '070';
3545          l_line_location_id_tbl := p_doc_level_id_tbl;
3546       ELSE
3547          -- the doc level is lower than shipment, which must be distribution
3548          l_progress := '080';
3549 
3550          IF (p_doc_type <> g_doc_type_REQUISITION) THEN
3551             -- Reqs don't have shipments
3552             l_progress := '090';
3553 
3554             PO_CORE_S.get_line_location_ids(
3555                p_doc_type              => p_doc_type
3556             ,  p_doc_level             => p_doc_level
3557             ,  p_doc_level_id_tbl      => p_doc_level_id_tbl
3558             ,  x_line_location_id_tbl  => l_line_location_id_tbl
3559             );
3560 
3561          END IF;
3562 
3563          l_progress := '100';
3564          l_distribution_id_tbl := p_doc_level_id_tbl;
3565 
3566       END IF;
3567 
3568    END IF;
3569 
3570 END IF;
3571 
3572 l_progress := '110';
3573 
3574 -- Set the header_id/release_id based on the doc type.
3575 
3576 IF (p_doc_type = g_doc_type_RELEASE) THEN
3577    l_release_id_tbl := l_doc_id_tbl;
3578 ELSE
3579    l_header_id_tbl := l_doc_id_tbl;
3580 END IF;
3581 
3582 -- Initialize all of the unset id tables.
3583 
3584 l_progress := '120';
3585 
3586 l_empty_tbl := po_tbl_number();
3587 l_empty_tbl.EXTEND(p_doc_level_id_tbl.COUNT);
3588 
3589 l_progress := '130';
3590 
3591 IF (l_header_id_tbl IS NULL) THEN
3592    l_header_id_tbl := l_empty_tbl;
3593 END IF;
3594 
3595 l_progress := '140';
3596 
3597 IF (l_release_id_tbl IS NULL) THEN
3598    l_release_id_tbl := l_empty_tbl;
3599 END IF;
3600 
3601 l_progress := '150';
3602 
3603 IF (l_line_id_tbl IS NULL) THEN
3604    l_line_id_tbl := l_empty_tbl;
3605 END IF;
3606 
3607 l_progress := '160';
3608 
3609 IF (l_line_location_id_tbl IS NULL) THEN
3610    l_line_location_id_tbl := l_empty_tbl;
3611 END IF;
3612 
3613 l_progress := '170';
3614 
3615 IF (l_distribution_id_tbl IS NULL) THEN
3616    l_distribution_id_tbl := l_empty_tbl;
3617 END IF;
3618 
3619 
3620 
3621 -- Set the appropriate mode.
3622 
3623 l_progress := '200';
3624 
3625 IF (p_action = g_action_RESERVE) THEN
3626    l_progress := '210';
3627    IF (p_doc_type = g_doc_type_REQUISITION) THEN
3628       l_progress := '220';
3629       l_mode := PO_REQ_DOCUMENT_CHECKS_PVT.G_CHECK_RESERVABLE;
3630    ELSE
3631       l_progress := '230';
3632       l_mode := PO_DOCUMENT_CHECKS_PVT.G_CHECK_RESERVABLE;
3633    END IF;
3634 ELSE
3635    l_progress := '250';
3636    IF (p_doc_type = g_doc_type_REQUISITION) THEN
3637       l_progress := '260';
3638       l_mode := PO_REQ_DOCUMENT_CHECKS_PVT.G_CHECK_UNRESERVABLE;
3639    ELSE
3640       l_progress := '270';
3641       l_mode := PO_DOCUMENT_CHECKS_PVT.G_CHECK_UNRESERVABLE;
3642    END IF;
3643 END IF;
3644 
3645 l_progress := '290';
3646 
3647 IF g_debug_stmt THEN
3648    PO_DEBUG.debug_var(l_log_head,l_progress,'l_header_id_tbl',l_header_id_tbl);
3649    PO_DEBUG.debug_var(l_log_head,l_progress,'l_release_id_tbl',l_release_id_tbl);
3650    PO_DEBUG.debug_var(l_log_head,l_progress,'l_line_id_tbl',l_line_id_tbl);
3651    PO_DEBUG.debug_var(l_log_head,l_progress,'l_line_location_id_tbl',l_line_location_id_tbl);
3652    PO_DEBUG.debug_var(l_log_head,l_progress,'l_distribution_id_tbl',l_distribution_id_tbl);
3653    PO_DEBUG.debug_var(l_log_head,l_progress,'l_mode',l_mode);
3654 END IF;
3655 
3656 -- Call the doc status check.
3657 
3658 l_progress := '300';
3659 
3660 IF (p_doc_type = g_doc_type_REQUISITION) THEN
3661 
3662    l_progress := '310';
3663    IF g_debug_stmt THEN
3664       PO_DEBUG.debug_stmt(l_log_head,l_progress,'req');
3665    END IF;
3666 
3667    PO_REQ_DOCUMENT_CHECKS_GRP.req_status_check(
3668       p_api_version => 1.0
3669    ,  p_req_header_id => l_header_id_tbl
3670    ,  p_req_line_id => l_line_id_tbl
3671    ,  p_req_distribution_id => l_distribution_id_tbl
3672    ,  p_mode => l_mode
3673    ,  p_lock_flag => 'N'
3674    ,  x_req_status_rec => l_status_rec
3675    ,  x_return_status => l_return_status
3676    ,  x_msg_count => l_msg_count
3677    ,  x_msg_data => l_msg_data
3678    );
3679 
3680    l_progress := '320';
3681 
3682 ELSE
3683 
3684    l_progress := '330';
3685    IF g_debug_stmt THEN
3686       PO_DEBUG.debug_stmt(l_log_head,l_progress,'not req');
3687    END IF;
3688 
3689    PO_DOCUMENT_CHECKS_GRP.po_status_check(
3690       p_api_version => 1.0
3691    ,  p_header_id => l_header_id_tbl
3692    ,  p_release_id => l_release_id_tbl
3693    ,  p_document_type => po_tbl_varchar30( p_doc_type )
3694    ,  p_document_subtype => po_tbl_varchar30( p_doc_subtype )
3695    ,  p_document_num => po_tbl_varchar30( NULL )
3696    ,  p_vendor_order_num => po_tbl_varchar30( NULL )
3697    ,  p_line_id => l_line_id_tbl
3698    ,  p_line_location_id => l_line_location_id_tbl
3699    ,  p_distribution_id => l_distribution_id_tbl
3700    ,  p_mode => l_mode
3701    ,  p_lock_flag => 'N'
3702    ,  x_po_status_rec => l_status_rec
3703    ,  x_return_status => l_return_status
3704    );
3705 
3706    l_progress := '340';
3707 
3708 END IF;
3709 
3710 l_progress := '350';
3711 IF g_debug_stmt THEN
3712    PO_DEBUG.debug_var(l_log_head,l_progress,'l_return_status',l_return_status);
3713    PO_DEBUG.debug_var(l_log_head,l_progress,'l_msg_count',l_msg_count);
3714    PO_DEBUG.debug_var(l_log_head,l_progress,'l_msg_data',l_msg_data);
3715    PO_DEBUG.debug_var(l_log_head,l_progress,'reservable flag',l_status_rec.reservable_flag);
3716    PO_DEBUG.debug_var(l_log_head,l_progress,'unreservable flag',l_status_rec.unreservable_flag);
3717 END IF;
3718 
3719 IF (p_action = g_action_RESERVE) THEN
3720 
3721    l_progress := '360';
3722 
3723    x_valid_state_flag := l_status_rec.reservable_flag(1);
3724 
3725 ELSE
3726 
3727    l_progress := '370';
3728 
3729    x_valid_state_flag := l_status_rec.unreservable_flag(1);
3730 
3731 END IF;
3732 
3733 l_progress := '900';
3734 
3735 IF g_debug_stmt THEN
3736    PO_DEBUG.debug_var(l_log_head,l_progress,'x_valid_state_flag',x_valid_state_flag);
3737    PO_DEBUG.debug_end(l_log_head);
3738 END IF;
3739 
3740 EXCEPTION
3741 WHEN OTHERS THEN
3742    --add message to the stack and log a debug msg if necessary
3743    po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
3744    fnd_msg_pub.add;
3745    x_valid_state_flag := g_doc_state_valid_NO;
3746    RAISE;
3747 
3748 END check_doc_state;
3749 
3750 
3751 
3752 
3753 -------------------------------------------------------------------------------
3754 --Start of Comments
3755 --Name: derive_packet_values
3756 --Pre-reqs:
3757 --   PO_ENCUMBRANCE_GT has been populated with the distribution
3758 --   information for both the original doc and backing docs.
3759 --Modifies:
3760 --   PO_ENCUMBRANCE_GT
3761 --Locks:
3762 --   None.
3763 --Function:
3764 --   This procedure updates all of the information required for each
3765 --   entry in PO_ENCUMBRANCE_GT that will be sent to GL for an
3766 --   encumbrance action.  It prepares all of the columns of
3767 --   PO_ENCUMBRANCE_GT that map to columns of GL_BC_PACKETS.
3768 --Parameters:
3769 --IN:
3770 --p_action
3771 --   Specifies the action that is being taken on the main doc.
3772 --p_cbc_flag
3773 --  This parameter is only set to Y if the action is one of the CBC Year-End
3774 --  processes.  If this is Y, p_action is either Reserve or Unreserve
3775 --p_doc_type
3776 --   Differentiates between the doc being a REQ, PO, or RELEASE
3777 --p_doc_subtype
3778 --   Used to differentiate between
3779 --      Scheduled Release vs. Blanket Release
3780 --      Std PO vs. PPO
3781 --p_use_gl_date
3782 --   Y = try to obtain encumbrance period information based on the
3783 --       existing distribution GL date.
3784 --   N = use the override date w/o trying distribution GL date.
3785 --p_override_date
3786 --   Override date used to determine encumbrance period information,
3787 --   if the document distributions date are not used.
3788 --p_prevent_partial_flag
3789 --   Y = never allow a Partial pass in GL
3790 --   N = use normal logic to decide whether partial is allowed
3791 --p_invoice_id
3792 --    For transactions that were caused by an invoice action,
3793 --    this is the id of the invoice that started it all (provided by AP).
3794 --Testing:
3795 --
3796 --End of Comments
3797 ------------------------------------------------------------------------------
3798 PROCEDURE derive_packet_values(
3799    p_action                    IN   VARCHAR2
3800 ,  p_cbc_flag                  IN   VARCHAR2
3801 ,  p_doc_type                  IN   VARCHAR2
3802 ,  p_doc_subtype               IN   VARCHAR2
3803 ,  p_use_gl_date               IN   VARCHAR2
3804 ,  p_override_date             IN   DATE
3805 ,  p_partial_flag              IN   VARCHAR2
3806 ,  p_set_of_books_id           IN   NUMBER
3807 ,  p_currency_code_func        IN   VARCHAR2
3808 ,  p_req_encumb_type_id        IN   NUMBER
3809 ,  p_po_encumb_type_id         IN   NUMBER
3810 ,  p_ap_reinstated_enc_amt     IN   NUMBER
3811 ,  p_ap_cancelled_qty          IN   NUMBER
3812 ,  p_invoice_id                IN   NUMBER
3813 )
3814 
3815 IS
3816 
3817 l_api_name CONSTANT varchar2(40) := 'DERIVE_PACKET_VALUES';
3818 l_progress varchar2(3) := '000';
3819 
3820 l_log_head CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
3821 
3822 BEGIN
3823 
3824 IF g_debug_stmt THEN
3825    PO_DEBUG.debug_begin(l_log_head);
3826    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action',p_action);
3827    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type',p_doc_type);
3828    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype',p_doc_subtype);
3829    PO_DEBUG.debug_var(l_log_head,l_progress,'p_use_gl_date',p_use_gl_date);
3830    PO_DEBUG.debug_var(l_log_head,l_progress,'p_override_date',p_override_date);
3831    PO_DEBUG.debug_var(l_log_head,l_progress,'p_partial_flag',p_partial_flag);
3832    PO_DEBUG.debug_var(l_log_head,l_progress,'p_set_of_books_id',p_set_of_books_id);
3833    PO_DEBUG.debug_var(l_log_head,l_progress,'p_currency_code_func',p_currency_code_func);
3834    PO_DEBUG.debug_var(l_log_head,l_progress,'p_req_encumb_type_id',p_req_encumb_type_id);
3835    PO_DEBUG.debug_var(l_log_head,l_progress,'p_po_encumb_type_id',p_po_encumb_type_id);
3836 END IF;
3837 
3838 l_progress := '010';
3839 
3840 -- Set the period information
3841 get_period_info(
3842    p_action 		=> p_action
3843 ,  p_set_of_books_id 	=> p_set_of_books_id
3844 ,  p_override_date 	=> p_override_date
3845 ,  p_try_dist_date_flag	=> p_use_gl_date
3846 ,  p_partial_flag 	=> p_partial_flag
3847 );
3848 
3849 l_progress := '015';
3850 
3851 -- Set the amounts (this will populate the final_amt column)
3852 get_amounts(
3853    p_action => p_action
3854 ,  p_doc_type => p_doc_type
3855 ,  p_doc_subtype => p_doc_subtype
3856 ,  p_currency_code_func => p_currency_code_func
3857 ,  p_ap_reinstated_enc_amt => p_ap_reinstated_enc_amt
3858 ,  p_ap_cancelled_qty => p_ap_cancelled_qty
3859 );
3860 
3861 l_progress := '020';
3862 
3863 -- Now put the final_amt into the appropriate fields.
3864 -- <SLA R12>
3865 update_amounts(
3866    p_action => p_action,
3867    p_currency_code_func => p_currency_code_func
3868 );
3869 
3870 l_progress := '030';
3871 
3872 -- Set the reference information
3873 get_gl_references(
3874    p_action 		=> p_action
3875 ,  p_cbc_flag           => p_cbc_flag
3876 ,  p_req_encumb_type_id	=> p_req_encumb_type_id
3877 ,  p_po_encumb_type_id	=> p_po_encumb_type_id
3878 ,  p_invoice_id => p_invoice_id
3879 );
3880 
3881 l_progress := '040';
3882 
3883 If g_fnd_debug = 'Y' Then
3884    IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3885      FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
3886                   g_log_head || l_api_name || '.' || l_progress,
3887                   'End of procedure'
3888                  );
3889    END IF;
3890 End If;
3891 
3892 
3893 EXCEPTION
3894    WHEN FND_API.G_EXC_ERROR THEN
3895       RAISE;
3896 
3897    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
3898       RAISE;
3899 
3900    WHEN PO_DOCUMENT_FUNDS_PVT.G_NO_VALID_PERIOD_EXC THEN
3901       RAISE;
3902 
3903   WHEN OTHERS THEN
3904       --add message to the stack and log a debug msg if necessary
3905       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
3906       fnd_msg_pub.add;
3907       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3908 
3909 END derive_packet_values;
3910 
3911 
3912 -------------------------------------------------------------------------------
3913 --Start of Comments
3914 --Name: get_period_info
3915 --Pre-reqs:
3916 --   PO_ENCUMBRANCE_GT has been populated with the date information
3917 --   for both the original doc and backing docs.
3918 --Modifies:
3919 --   PO_ENCUMBRANCE_GT
3920 --Locks:
3921 --   n/a
3922 --Function:
3923 --   This procedure updates the period information in PO_ENCUMBRANCE_GT
3924 --   for both the main doc and backing docs.
3925 --   For backing docs, it sets the period information equal to the
3926 --   period information of the main doc.
3927 --Parameters:
3928 --IN:
3929 --p_action
3930 --   Specifies the action that is being taken on the main doc.
3931 --p_set_of_books_id
3932 --   The set of books in use by this operating unit.
3933 --p_override_date
3934 --   The override date to use if requested.
3935 --p_try_dist_date_flag
3936 --   Indicates whether or not to use the override date:
3937 --   'Y' - try the dist GL date; use overridate date only if that fails
3938 --   'N' - use overridate date only; do not try with dist GL date
3939 --p_partial_flag
3940 --   'Y' - partial reservation of the packet in GL is allowed
3941 --   'N' - partial is not allowed
3942 --Testing:
3943 --
3944 --End of Comments
3945 -------------------------------------------------------------------------------
3946 PROCEDURE get_period_info(
3947    p_action              IN VARCHAR2
3948 ,  p_set_of_books_id     IN NUMBER
3949 ,  p_override_date       IN DATE
3950 ,  p_try_dist_date_flag  IN VARCHAR2
3951 ,  p_partial_flag        IN VARCHAR2
3952 )
3953 IS
3954 
3955    l_api_name CONSTANT varchar2(40) := 'GET_PERIOD_INFO';
3956    l_progress varchar2(3) := '000';
3957 
3958    l_log_head CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
3959 
3960    l_allow_roll_forward  VARCHAR2(1) := 'N';
3961    l_allow_roll_backward VARCHAR2(1) := 'N';
3962    l_missing_date_flag   VARCHAR2(1) := 'N';
3963 
3964    l_period_error_text  FND_NEW_MESSAGES.message_text%TYPE;
3965    l_not_processed_msg  FND_NEW_MESSAGES.message_text%TYPE;
3966 
3967 BEGIN
3968 
3969 IF g_debug_stmt THEN
3970    PO_DEBUG.debug_begin(l_log_head);
3971    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action',p_action);
3972    PO_DEBUG.debug_var(l_log_head,l_progress,'p_set_of_books_id',p_set_of_books_id);
3973    PO_DEBUG.debug_var(l_log_head,l_progress,'p_override_date',p_override_date);
3974    PO_DEBUG.debug_var(l_log_head,l_progress,'p_try_dist_date_flag',p_try_dist_date_flag);
3975    PO_DEBUG.debug_var(l_log_head,l_progress,'p_partial_flag',p_partial_flag);
3976 END IF;
3977 
3978 -- Set the parameters used by the different actions
3979 IF p_action IN (g_action_UNRESERVE, g_action_FINAL_CLOSE,
3980                 g_action_ADJUST)
3981 THEN
3982 
3983    l_allow_roll_forward := 'Y';
3984 
3985 ELSIF p_action IN (g_action_RETURN, g_action_REJECT) THEN
3986 
3987    l_allow_roll_forward  := 'Y';
3988    l_allow_roll_backward := 'Y';
3989 
3990 END IF;
3991 
3992 l_progress := '010';
3993 
3994 IF g_debug_stmt THEN
3995    PO_DEBUG.debug_var(l_log_head,l_progress,'l_allow_roll_forward',l_allow_roll_forward);
3996    PO_DEBUG.debug_var(l_log_head,l_progress,'l_allow_roll_backward',l_allow_roll_backward);
3997 END IF;
3998 
3999 IF (p_try_dist_date_flag = 'Y' OR p_action = g_action_ADJUST) THEN
4000 
4001    l_progress := '015';
4002 
4003    If g_fnd_debug = 'Y' Then
4004       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
4005         FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
4006                      g_log_head || l_api_name || '.' || l_progress,
4007                      'Try distribution GL dates'
4008                     );
4009       END IF;
4010    End If;
4011 
4012    find_open_period(
4013       p_set_of_books_id => p_set_of_books_id
4014    ,  p_try_dist_date_flag => p_try_dist_date_flag
4015    ,  p_override_date => p_override_date
4016    ,  p_override_attempt => 'N'
4017    ,  p_roll_logic_used => g_roll_logic_NONE
4018    ,  x_missing_date_flag => l_missing_date_flag
4019    );
4020 
4021 END IF;
4022 
4023 IF (l_missing_date_flag = 'Y' OR p_try_dist_date_flag = 'N') THEN
4024 
4025    l_progress := '020';
4026 
4027    If g_fnd_debug = 'Y' Then
4028       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
4029         FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
4030                      g_log_head || l_api_name || '.' || l_progress,
4031                      'Try Override GL date'
4032                     );
4033       END IF;
4034    End If;
4035 
4036    find_open_period(
4037       p_set_of_books_id => p_set_of_books_id
4038    ,  p_try_dist_date_flag => p_try_dist_date_flag
4039    ,  p_override_date => p_override_date
4040    ,  p_override_attempt => 'Y'
4041    ,  p_roll_logic_used => g_roll_logic_NONE
4042    ,  x_missing_date_flag => l_missing_date_flag
4043    );
4044 
4045    IF (l_missing_date_flag = 'Y') THEN
4046 
4047       IF (l_allow_roll_forward = 'Y') THEN
4048          -- roll-forward is used for:
4049          -- programmatic UNRESERVE
4050          -- Final Close that is entered from AP Final Match
4051          -- Return
4052          -- Reject
4053 
4054          l_progress := '030';
4055 
4056          If g_fnd_debug = 'Y' Then
4057             IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
4058               FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
4059                            g_log_head || l_api_name || '.' || l_progress,
4060                            'Try roll forward logic'
4061                           );
4062             END IF;
4063          End If;
4064 
4065          find_open_period(
4066             p_set_of_books_id => p_set_of_books_id
4067          ,  p_try_dist_date_flag => p_try_dist_date_flag
4068          ,  p_override_date => p_override_date
4069          ,  p_override_attempt => 'Y'
4070          ,  p_roll_logic_used => g_roll_logic_FORWARD
4071          ,  x_missing_date_flag => l_missing_date_flag
4072          );
4073 
4074 
4075          IF (l_missing_date_flag = 'Y') THEN
4076 	     IF (l_allow_roll_backward = 'Y') THEN
4077 	       -- roll-backward is used for:
4078                -- Return
4079                -- Reject
4080 
4081                l_progress := '040';
4082 
4083                If g_fnd_debug = 'Y' Then
4084                   IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
4085                     FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
4086                                  g_log_head || l_api_name || '.' || l_progress,
4087                                  'Try roll backward logic'
4088                                 );
4089                   END IF;
4090                End If;
4091 
4092                find_open_period(
4093                   p_set_of_books_id => p_set_of_books_id
4094                ,  p_try_dist_date_flag => p_try_dist_date_flag
4095                ,  p_override_date => p_override_date
4096                ,  p_override_attempt => 'Y'
4097                ,  p_roll_logic_used => g_roll_logic_BACKWARD
4098                ,  x_missing_date_flag => l_missing_date_flag
4099                );
4100 
4101             END IF; -- if roll back allowed is 'Y'
4102 
4103          END IF; -- if l_roll_forward_csr_found is 'Y'
4104 
4105       END IF; -- if roll forward allowed = 'Y'
4106 
4107    END IF;  --if override date was valid
4108 
4109 END IF;  -- if we should try override date
4110 
4111 
4112 l_progress := '050';
4113 
4114 If g_fnd_debug = 'Y' Then
4115    IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
4116      FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
4117                   g_log_head || l_api_name || '.' || l_progress,
4118                   'Update backing document GL dates'
4119                  );
4120    END IF;
4121 End If;
4122 
4123 
4124 -- By now, the period info has been set for the original
4125 -- document's distributions.
4126 -- Now update the backing distributions.
4127 UPDATE PO_ENCUMBRANCE_GT BACKING
4128 SET (
4129    BACKING.period_name
4130 ,  BACKING.period_year
4131 ,  BACKING.period_num
4132 ,  BACKING.quarter_num
4133 ,  BACKING.gl_period_date --bug#5098665
4134 )
4135 =
4136 (
4137    SELECT
4138       ORIG.period_name
4139    ,  ORIG.period_year
4140    ,  ORIG.period_num
4141    ,  ORIG.quarter_num
4142    ,  ORIG.gl_period_date --bug#5098665
4143    FROM
4144       PO_ENCUMBRANCE_GT ORIG
4145    WHERE
4146        ORIG.sequence_num = BACKING.origin_sequence_num
4147    AND ORIG.origin_sequence_num IS NULL
4148    AND ORIG.distribution_type <> g_dist_type_REQUISITION
4149 )
4150 WHERE BACKING.origin_sequence_num IS NOT NULL
4151 ;
4152 
4153 IF (l_missing_date_flag = 'Y') THEN
4154    -- there are distributions without valid period information
4155 
4156    l_progress := '060';
4157 
4158    If g_fnd_debug = 'Y' Then
4159       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
4160         FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
4161                      g_log_head || l_api_name || '.' || l_progress,
4162                      'No valid period for some distributions'
4163                     );
4164       END IF;
4165    End If;
4166 
4167    l_period_error_text := FND_MESSAGE.get_string(
4168                              'PO'
4169                           ,  'PO_PDOI_INVALID_GL_ENC_PER'
4170                           );
4171 
4172    -- Mark the missing date lines to not be sent to GL
4173    UPDATE PO_ENCUMBRANCE_GT DISTS
4174    SET DISTS.send_to_gl_flag = 'N'  --bug 5413111 gl period failed rows shouldn't be sent to GL
4175    ,   DISTS.gl_result_code = 'F25'   --GL error code for no period found
4176    ,   DISTS.result_type = g_result_ERROR
4177    ,   DISTS.result_text = l_period_error_text
4178    WHERE DISTS.period_name IS NULL;
4179 
4180    IF (p_partial_flag = 'N') THEN
4181 
4182       l_not_processed_msg := FND_MESSAGE.get_string(
4183                                 'PO'
4184                              , 'PO_ENC_DIST_NOT_PROCESSED'
4185                              );
4186 
4187       -- Mark the other lines as failures, since packet is hosed
4188       UPDATE PO_ENCUMBRANCE_GT DISTS
4189       SET DISTS.send_to_gl_flag = 'Y'  --bug 3568512: new send_to_gl column
4190       ,   DISTS.result_text = l_not_processed_msg
4191       ,   DISTS.result_type = g_result_NOT_PROCESSED
4192       WHERE DISTS.period_name IS NOT NULL;
4193 
4194       --force x_return_status to E and stop processing
4195       RAISE PO_DOCUMENT_FUNDS_PVT.G_NO_VALID_PERIOD_EXC;
4196 
4197    END IF;
4198 
4199 END IF;
4200 
4201 l_progress := '070';
4202 
4203 If g_fnd_debug = 'Y' Then
4204    IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
4205      FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
4206                   g_log_head || l_api_name || '.' || l_progress,
4207                   'End of procedure'
4208                  );
4209    END IF;
4210 End If;
4211 
4212 
4213 EXCEPTION
4214 
4215    WHEN FND_API.G_EXC_ERROR THEN
4216       RAISE;
4217 
4218    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
4219       RAISE;
4220 
4221    WHEN PO_DOCUMENT_FUNDS_PVT.G_NO_VALID_PERIOD_EXC THEN
4222       RAISE;
4223 
4224   WHEN OTHERS THEN
4225       --add message to the stack and log a debug msg if necessary
4226       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
4227       fnd_msg_pub.add;
4228       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4229 
4230 END get_period_info;
4231 
4232 
4233 -------------------------------------------------------------------------------
4234 --Start of Comments
4235 --Name: find_open_period
4236 --Pre-reqs:
4237 --   PO_ENCUMBRANCE_GT has been populated with the date information
4238 --   for both the original doc.
4239 --Modifies:
4240 --   PO_ENCUMBRANCE_GT
4241 --   PO_SESSION_GT
4242 --Locks:
4243 --   n/a
4244 --Function:
4245 --   This procedure updates the period information in PO_ENCUMBRANCE_GT
4246 --   for both the main doc, based on parameters which decide whether to
4247 --   use the distribution GL date, override date, roll-forward or
4248 --   roll-backward logic.
4249 --Parameters:
4250 --IN:
4251 --p_set_of_books_id
4252 --   The set of books in use by this operating unit.
4253 --p_override_date
4254 --   The override date to use if requested.
4255 --p_use_override_date
4256 --   Indicates whether or not to use the override date:
4257 --   'Y' - use override date only; do not try with dist GL date
4258 --   'N' - try the dist GL date; use overridate date only if that fails
4259 --p_roll_logic_used
4260 --   Indicates what kind of rolling logic should be used, if necessary
4261 --   g_roll_logic_NONE - don't roll forward or backward
4262 --   g_roll_logic_FORWARD - use roll forward
4263 --   g_roll_logic_BACKWARD - use roll backward
4264 --OUT:
4265 --x_missing_date_flag
4266 --   Indicates whether there are still distributions without period info
4267 --   at the end of this procedure
4268 --   'Y' - there are distributions w/o period info
4269 --   'N' - all distributions should have period info
4270 --Testing:
4271 --
4272 --End of Comments
4273 -------------------------------------------------------------------------------
4274 PROCEDURE find_open_period(
4275    p_set_of_books_id    IN  NUMBER
4276 ,  p_try_dist_date_flag IN  VARCHAR2
4277 ,  p_override_date      IN  DATE
4278 ,  p_override_attempt   IN  VARCHAR2
4279 ,  p_roll_logic_used    IN  VARCHAR2
4280 ,  x_missing_date_flag  OUT NOCOPY VARCHAR2
4281 )
4282 
4283 IS
4284 
4285 l_proc_name CONSTANT VARCHAR2(30) := 'FIND_OPEN_PERIOD';
4286 l_log_head CONSTANT VARCHAR2(100) := g_log_head || l_proc_name;
4287 l_progress VARCHAR2(3) := '000';
4288 
4289 l_procedure_id NUMBER;
4290 
4291 BEGIN
4292 
4293 IF g_debug_stmt THEN
4294    PO_DEBUG.debug_begin(l_log_head);
4295    PO_DEBUG.debug_var(l_log_head,l_progress,'p_set_of_books_id',p_set_of_books_id);
4296    PO_DEBUG.debug_var(l_log_head,l_progress,'p_try_dist_date_flag',p_try_dist_date_flag);
4297    PO_DEBUG.debug_var(l_log_head,l_progress,'p_override_date',p_override_date);
4298    PO_DEBUG.debug_var(l_log_head,l_progress,'p_override_attempt',p_override_attempt);
4299    PO_DEBUG.debug_var(l_log_head,l_progress,'p_roll_logic_used',p_roll_logic_used);
4300 END IF;
4301 
4302 l_progress := '010';
4303 
4304 l_procedure_id := PO_CORE_S.get_session_gt_nextval();
4305 
4306 l_progress := '020';
4307 
4308 IF (p_override_attempt = 'N') THEN
4309   -- On the first entry into the procedure, p_override_attempt is set
4310   -- to 'N'.  So we have to figure out whether to use the distribution
4311   -- dates or not based on the value of p_try_dist_date_flag (passed by caller)
4312   -- and the action (for NEW lines in Adjust, we always try the dist dates
4313   -- first b/c if the user was trying to adjust the GL date, we don't
4314   -- to just ignore their updated value and skip straight to override
4315   -- date).
4316    l_progress := '030';
4317 
4318    INSERT INTO PO_SESSION_GT
4319    (
4320       key
4321    ,  index_num1  -- bug3543542 : Save sequence_num to an indexed column
4322    ,  date1
4323    )
4324    SELECT
4325       l_procedure_id
4326    ,  DISTS.sequence_num
4327    -- Decide whether to use the override date based on the
4328    -- Use GL Date parameter and the Action
4329    ,  TRUNC(
4330              DECODE (p_try_dist_date_flag
4331                    -- param prefers the distribution date
4332                    ,  'Y', DISTS.gl_encumbered_date
4333 
4334                    -- prefer the override date, except for New Adjust lines
4335                    ,  DECODE (DISTS.adjustment_status
4336                              ,  g_adj_status_NEW, DISTS.gl_encumbered_date
4337                              ,  p_override_date
4338 
4339                        )
4340              )
4341       )
4342    FROM PO_ENCUMBRANCE_GT DISTS
4343    WHERE
4344        DISTS.origin_sequence_num IS NULL  --main doc
4345    AND DISTS.period_name IS NULL
4346    --bug 3568512: use send_to_gl_flag for this filter condition
4347    AND (DISTS.send_to_gl_flag = 'Y'
4348         OR (DISTS.distribution_type = g_dist_type_REQUISITION
4349             AND DISTS.prevent_encumbrance_flag = 'Y')
4350            -- only verify GL date information for prevent-enc distributions if
4351            -- they are Req dists.  no need to check dates for PO prevent dists.
4352        )
4353    ;
4354 
4355 ELSE
4356    -- p_override_attempt = 'Y'
4357    -- Even if the profile indicates to try the distribution dates,
4358    -- if we tried that once and failed, on the next entry into this
4359    -- procedure, we set p_override_attempt to 'Y' to force it to use
4360    -- the override date.
4361    -- We do this as a separate insert for performance reasons, b/c in
4362    -- this case, ALL distributions use the same override_date -- so we
4363    -- only perform the date SQL on one date.
4364    l_progress := '040';
4365 
4366    INSERT INTO PO_SESSION_GT ( key,  date1 )
4367    VALUES ( l_procedure_id, TRUNC(p_override_date))
4368    ;
4369 
4370 END IF;
4371 
4372 l_progress := '050';
4373 
4374 -- Now, get the period information for the date(s) that were inserted
4375 -- into the session gtt
4376 
4377 -- bug#	3627073 The original sql that was written to find the open
4378 -- period was returning multiple rows. Because of this the deleting
4379 -- a requisition line after closing the GL_PERIOD in which it was
4380 -- encumbered was resulting in exceptions.To prevent this and to prevent
4381 -- the use of decode in the where clause the sql was split into 3
4382 -- different sql's below. The first logic is for the normal scenario.
4383 -- the second is for ROLLFORWARD logic the third for a ROLLBACK scenario.
4384 
4385 -- bug #3967418
4386 -- The SQLs for ROLLING FORWARD and ROLLING BACKWARD
4387 -- were returning multiple rows because adjustment periods with overlapping
4388 -- start or end dates with other periods were being matched.
4389 -- Added condition at the period info retrieval query level
4390 -- adjustment_period_flag = 'N' so adjustment periods are no longer
4391 -- picked up.
4392 
4393 -- bug#5098665
4394 -- From now on we would populate the open period start date
4395 -- instead of gl_encumbered_date. This is to ensure that the funds get
4396 -- reserved/unreserved in the correct period. We would first update
4397 -- date1 with start date of the valid open period. This is because period
4398 -- information is being derived by us and the funds would get reserved
4399 -- in a period and the exact date does not matter.
4400 
4401 IF (p_roll_logic_used= g_roll_logic_NONE ) THEN
4402 
4403   UPDATE PO_SESSION_GT TEMP
4404   SET (
4405        TEMP.char1,	-- period_name
4406        TEMP.num2,  	-- period_year
4407        TEMP.num3,  	-- period_num
4408        TEMP.num4
4409       )
4410       =
4411       (
4412       SELECT
4413         GL_PS.PERIOD_NAME,
4414         GL_PS.PERIOD_YEAR,
4415         GL_PS.PERIOD_NUM,
4416         GL_PS.QUARTER_NUM
4417       FROM
4418         GL_PERIOD_STATUSES GL_PS,
4419         GL_PERIOD_STATUSES PO_PS,
4420         GL_SETS_OF_BOOKS GL_SOB
4421       WHERE
4422       -- Join conditions:
4423           GL_SOB.set_of_books_id = p_set_of_books_id
4424       AND GL_PS.set_of_books_id = GL_SOB.set_of_books_id
4425       AND PO_PS.set_of_books_id = GL_SOB.set_of_books_id
4426       AND GL_PS.period_name = PO_PS.period_name
4427       -- GL period conditions:
4428       AND GL_PS.application_id = 101
4429       AND GL_PS.closing_status IN ('O', 'F')
4430       AND GL_PS.adjustment_period_flag = 'N'
4431       AND GL_PS.period_year <= GL_SOB.latest_encumbrance_year
4432       -- PO period conditions:
4433       AND PO_PS.application_id = 201
4434       AND PO_PS.closing_status = 'O'
4435       AND PO_PS.adjustment_period_flag = 'N'
4436       -- Period date conditions:
4437       AND (TEMP.date1 BETWEEN  GL_PS.start_date AND GL_PS.end_date)
4438     )
4439   WHERE TEMP.key = l_procedure_id ;
4440 
4441 --bug#	3627073
4442 ELSIF (p_roll_logic_used= g_roll_logic_FORWARD ) THEN
4443 
4444   UPDATE PO_SESSION_GT TEMP
4445   SET (
4446        TEMP.char1,	-- period_name
4447        TEMP.num2,  	-- period_year
4448        TEMP.num3,  	-- period_num
4449        TEMP.num4,  	-- quarter_num
4450        TEMP.DATE1   -- gl date to use--<bug#5098665>
4451       )
4452       =
4453       (
4454       SELECT
4455         GL_PS2.PERIOD_NAME ,
4456         GL_PS2.PERIOD_YEAR ,
4457         GL_PS2.PERIOD_NUM ,
4458         GL_PS2.QUARTER_NUM,
4459         GL_PS2.START_DATE --<bug#5098665>
4460       FROM
4461 	GL_PERIOD_STATUSES GL_PS2
4462       WHERE
4463         GL_PS2.set_of_books_id = p_set_of_books_id AND
4464         GL_PS2.application_id= 101 AND
4465         /* Bug 3967418 Start */
4466         GL_PS2.adjustment_period_flag = 'N' AND
4467         /* Bug 3967418 End */
4468         GL_PS2.start_date=
4469 	(SELECT min(gl_ps.start_date)
4470 	  FROM
4471 	     GL_PERIOD_STATUSES GL_PS
4472 	  ,  GL_PERIOD_STATUSES PO_PS
4473 	  ,  GL_SETS_OF_BOOKS GL_SOB
4474 	  WHERE
4475 	  -- Join conditions:
4476 	      GL_SOB.set_of_books_id = p_set_of_books_id
4477 	  AND GL_PS.set_of_books_id = GL_SOB.set_of_books_id
4478 	  AND PO_PS.set_of_books_id = GL_SOB.set_of_books_id
4479 	  AND GL_PS.period_name = PO_PS.period_name
4480 	  -- GL period conditions:
4481 	  AND GL_PS.application_id = GL_PS2.application_id
4482 	  AND GL_PS.closing_status IN ('O', 'F')
4483 	  AND GL_PS.adjustment_period_flag = 'N'
4484 	  AND GL_PS.period_year <= GL_SOB.latest_encumbrance_year
4485 	  -- PO period conditions:
4486 	  AND PO_PS.application_id = 201
4487 	  AND PO_PS.closing_status = 'O'
4488 	  AND PO_PS.adjustment_period_flag = 'N'
4489 	  -- Period date conditions:
4490 	  AND (TEMP.date1 < GL_PS.start_date)
4491 
4492 	)
4493       )
4494   WHERE TEMP.key = l_procedure_id;
4495 
4496 --bug#	3627073
4497 ELSIF(p_roll_logic_used= g_roll_logic_BACKWARD ) THEN
4498 
4499   UPDATE PO_SESSION_GT TEMP
4500   SET (
4501        TEMP.char1,	-- period_name
4502        TEMP.num2,  	-- period_year
4503        TEMP.num3,  	-- period_num
4504        TEMP.num4,  	-- quarter_num
4505        TEMP.DATE1   -- gl date to use --<bug#5098665>
4506       )
4507       =
4508       (
4509       SELECT
4510         GL_PS2.PERIOD_NAME ,
4511         GL_PS2.PERIOD_YEAR ,
4512         GL_PS2.PERIOD_NUM ,
4513         GL_PS2.QUARTER_NUM,
4514         GL_PS2.START_DATE --<bug#5098665>
4515       FROM
4516 	GL_PERIOD_STATUSES GL_PS2
4517       WHERE
4518         GL_PS2.set_of_books_id = p_set_of_books_id AND
4519         GL_PS2.application_id= 101 AND
4520         /* Bug 3967418 Start */
4521         GL_PS2.adjustment_period_flag = 'N' AND
4522         /* Bug 3967418 End */
4523         GL_PS2.end_date=
4524 	(SELECT max(gl_ps.end_date)
4525 	  FROM
4526 	     GL_PERIOD_STATUSES GL_PS
4527 	  ,  GL_PERIOD_STATUSES PO_PS
4528 	  ,  GL_SETS_OF_BOOKS GL_SOB
4529 	  WHERE
4530 	  -- Join conditions:
4531 	      GL_SOB.set_of_books_id = p_set_of_books_id
4532 	  AND GL_PS.set_of_books_id = GL_SOB.set_of_books_id
4533 	  AND PO_PS.set_of_books_id = GL_SOB.set_of_books_id
4534 	  AND GL_PS.period_name = PO_PS.period_name
4535 	  -- GL period conditions:
4536 	  AND GL_PS.application_id = GL_PS2.application_id
4537 	  AND GL_PS.closing_status IN ('O', 'F')
4538 	  AND GL_PS.adjustment_period_flag = 'N'
4539 	  AND GL_PS.period_year <= GL_SOB.latest_encumbrance_year
4540 	  -- PO period conditions:
4541 	  AND PO_PS.application_id = 201
4542 	  AND PO_PS.closing_status = 'O'
4543 	  AND PO_PS.adjustment_period_flag = 'N'
4544 	  -- Period date conditions:
4545 	  AND (TEMP.date1 > GL_PS.end_date)
4546 	)
4547       )
4548   WHERE TEMP.key = l_procedure_id;
4549 
4550 END IF;
4551 --bug#	3627073
4552 
4553 l_progress := '060';
4554 
4555 IF g_debug_stmt THEN
4556    PO_DEBUG.debug_stmt(l_log_head,l_progress,'Search for matching periods done');
4557 
4558    SELECT rowid BULK COLLECT INTO PO_DEBUG.g_rowid_tbl
4559    FROM PO_SESSION_GT WHERE key = l_procedure_id
4560    ;
4561 
4562    PO_DEBUG.g_column_tbl := po_tbl_varchar30('key','date1','index_num1','char1','num2','num3','num4');  -- bug3543542
4563 
4564    PO_DEBUG.debug_table(l_log_head,l_progress,'PO_SESSION_GT',PO_DEBUG.g_rowid_tbl,PO_DEBUG.g_column_tbl,'PO');
4565 
4566 END IF;
4567 
4568 
4569 -- Update the main encumbrance GTT with the results from
4570 -- the po_session_gt scratchpad.
4571 IF (p_override_attempt = 'N') THEN
4572    -- There is one row in the session GT for each
4573    -- row in the main encumbrance GT that needs to be updated
4574    l_progress := '070';
4575 
4576    -- bug3543542
4577    -- Need to Add hints to ensure that PO_SESSION_GT_N2 index is used
4578 
4579   --bug#5098665 From now on we would populate the open period start date
4580   --instead of gl_encumbered_date. This is to ensure that the funds get
4581   --reserved/unreserved in the correct period. We would first populate
4582   --po_encumbrance_gt with gl_period_start_date that we derived earlier
4583   --and then this would be passed onto po_bc_distributions.
4584 
4585    UPDATE PO_ENCUMBRANCE_GT DISTS
4586    SET (
4587       DISTS.period_name
4588    ,  DISTS.period_year
4589    ,  DISTS.period_num
4590    ,  DISTS.quarter_num
4591    ,  DISTS.gl_period_date --<bug#5098665>
4592    )
4593    =
4594    (  SELECT /*+ INDEX (VALID_PERIOD PO_SESSION_GT_N2) */
4595          VALID_PERIOD.char1 period_name
4596       ,  VALID_PERIOD.num2 period_year
4597       ,  VALID_PERIOD.num3 period_num
4598       ,  VALID_PERIOD.num4 quarter_num
4599       ,  VALID_PERIOD.date1 gl_period_date --<bug#5098665>
4600       FROM PO_SESSION_GT VALID_PERIOD
4601       WHERE
4602           VALID_PERIOD.key = l_procedure_id
4603       AND VALID_PERIOD.index_num1 = DISTS.sequence_num  -- bug3543542
4604       AND VALID_PERIOD.char1 IS NOT NULL
4605    )
4606    WHERE
4607        DISTS.origin_sequence_num IS NULL
4608    AND DISTS.period_name IS NULL
4609    ;
4610 
4611 ELSE
4612    -- p_override_attempt = 'Y'
4613    -- There is only a single row in the session gtt
4614    -- which is used to update all relevant rows of the
4615    -- main encumbrance gtt
4616    l_progress := '080';
4617   --bug#5098665 From now on we would populate the open period start date
4618   --instead of gl_encumbered_date. This is to ensure that the funds get
4619   --reserved/unreserved in the correct period. We would first populate
4620   --po_encumbrance_gt with gl_period_start_date that we derived earlier
4621   --and then this would be passed onto po_bc_distributions.
4622 
4623    UPDATE PO_ENCUMBRANCE_GT DISTS
4624    SET (
4625       DISTS.period_name
4626    ,  DISTS.period_year
4627    ,  DISTS.period_num
4628    ,  DISTS.quarter_num
4629    ,  DISTS.gl_period_date --<bug#5098665>
4630    )
4631    =
4632    (  SELECT
4633          VALID_PERIOD.char1 period_name
4634       ,  VALID_PERIOD.num2 period_year
4635       ,  VALID_PERIOD.num3 period_num
4636       ,  VALID_PERIOD.num4 quarter_num
4637       ,  VALID_PERIOD.date1 gl_period_date --<bug#5098665>
4638       FROM PO_SESSION_GT VALID_PERIOD
4639       WHERE
4640           VALID_PERIOD.key = l_procedure_id
4641       AND VALID_PERIOD.char1 IS NOT NULL
4642       AND rownum = 1
4643    )
4644    WHERE
4645        DISTS.origin_sequence_num IS NULL
4646    AND DISTS.period_name IS NULL
4647    ;
4648 
4649 END IF;
4650 
4651 l_progress := '090';
4652 
4653 IF g_debug_stmt THEN
4654    PO_DEBUG.debug_stmt(l_log_head,l_progress,'Updated main encumbrance gt with period information');
4655 END IF;
4656 
4657 -- Determine if we found period information for all the dates
4658 -- we were looking at.
4659    BEGIN
4660       SELECT 'Y'
4661       INTO x_missing_date_flag
4662       FROM DUAL
4663       WHERE EXISTS
4664          (SELECT 'period information not populated'
4665           FROM  PO_SESSION_GT TEMP
4666           WHERE TEMP.key = l_procedure_id
4667           AND   TEMP.char1 is NULL  -- no period name populated
4668          )
4669       ;
4670    EXCEPTION
4671       WHEN NO_DATA_FOUND THEN
4672          x_missing_date_flag := 'N';
4673    END;
4674 
4675 l_progress := '100';
4676 
4677 -- Clean up the scratchpad
4678 DELETE
4679 FROM PO_SESSION_GT TEMP
4680 WHERE TEMP.key = l_procedure_id
4681 ;
4682 
4683 l_progress := '900';
4684 
4685 IF g_debug_stmt THEN
4686    PO_DEBUG.debug_var(l_log_head,l_progress,'x_missing_date_flag',x_missing_date_flag);
4687    PO_DEBUG.debug_end(l_log_head);
4688 END IF;
4689 
4690 EXCEPTION
4691 
4692    WHEN OTHERS THEN
4693       --add message to the stack and log a debug msg if necessary
4694       po_message_s.sql_error(g_pkg_name, l_proc_name, l_progress, SQLCODE, SQLERRM);
4695       fnd_msg_pub.add;
4696       RAISE;
4697 
4698 END find_open_period;
4699 
4700 
4701 
4702 -------------------------------------------------------------------------------
4703 --Start of Comments
4704 --Name: get_amounts
4705 --Pre-reqs:
4706 --  The PO_ENCUMBRANCE_GT temp table has been populated with all
4707 --  required information about the main and backing documents; and
4708 --  Encumbrance is on for the doc type of the main doc.
4709 --Modifies:
4710 --  PO_ENCUMBRANCE_GT
4711 --Locks:
4712 --  None.
4713 --Function:
4714 --  This procedure calculates the total amount being transacted by
4715 --  the encumbrance action and populates this value in the final_amt
4716 --  column for each row in the PO_ENCUMBRANCE_GT table
4717 --Parameters:
4718 --IN:
4719 --p_action
4720 --   Specifies the action that is being taken on the main doc.
4721 --p_doc_type
4722 --   Differentiates between the doc being a REQ, PO, or RELEASE
4723 --p_doc_subtype
4724 --   Used to differentiate between
4725 --      Scheduled Release vs. Blanket Release
4726 --      Std PO vs. PPO
4727 --p_currency_code_func
4728 --   Identifies the currency that is defined as the functional
4729 --   currency for the current set of books
4730 --p_ap_reinstated_enc_amt
4731 --   For Invoice/Credit Memo cancel only: the amount of encumbrance
4732 --   put back on by AP (w/o any AP variances and excluding tax)
4733 --p_ap_cancelled_qty
4734 --   For Invoice/Credit Memo cancel only: the quantity of the
4735 --   cancelled invoice
4736 --Testing:
4737 --
4738 --End of Comments
4739 -------------------------------------------------------------------------------
4740 PROCEDURE get_amounts(
4741    p_action                IN   VARCHAR2
4742 ,  p_doc_type              IN   VARCHAR2
4743 ,  p_doc_subtype           IN   VARCHAR2
4744 ,  p_currency_code_func    IN   VARCHAR2
4745 ,  p_ap_reinstated_enc_amt IN   NUMBER
4746 ,  p_ap_cancelled_qty      IN   NUMBER
4747 )
4748 IS
4749 
4750    l_api_name CONSTANT VARCHAR2(40) := 'GET_AMOUNTS';
4751    l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
4752    l_progress     VARCHAR2(3) := '000';
4753 
4754    l_ap_reinstated_enc_amt NUMBER;
4755    l_ap_cancelled_qty      NUMBER;
4756 
4757    l_min_acct_unit_func  FND_CURRENCIES.minimum_accountable_unit%TYPE;
4758    l_cur_precision_func  FND_CURRENCIES.precision%TYPE;
4759 
4760    l_is_complex_work_po BOOLEAN := FALSE;  --<Complex Work R12>
4761    l_header_id PO_HEADERS_ALL.po_header_id%TYPE;  --<Complex Work R12>
4762 
4763 BEGIN
4764 
4765 -- ALGORITHM:
4766 -- The amount being calculated is the transactable or 'open' encumbrance
4767 -- amount.  To find the open amount, we take the initial total amount
4768 -- (stored in amt_ordered) and subtract out the amount that is 'closed'
4769 -- for that encumbrance action.
4770 -- We first do the calculations for the main (forward) document.  Then, we
4771 -- do the calculations for the backing document, if applicable.  Finally,
4772 -- these amounts have tax added, and are currency-converted and rounded.
4773 
4774 -- Note:
4775 -- NVLs are not used around fields from the temp table in the calculations
4776 -- below.  It is assumed that NULL values in these fields were given default
4777 -- values upon initial insertion into the global temp table.
4778 
4779 IF g_debug_stmt THEN
4780    PO_DEBUG.debug_begin(l_log_head);
4781    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
4782    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
4783    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
4784    PO_DEBUG.debug_var(l_log_head,l_progress,'p_currency_code_func',p_currency_code_func);
4785    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_reinstated_enc_amt',p_ap_reinstated_enc_amt);
4786    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_cancelled_qty',p_ap_cancelled_qty);
4787 END IF;
4788 
4789 
4790 -- If AP gives us NULL values, deal with them gracefully.
4791 l_ap_reinstated_enc_amt := NVL(p_ap_reinstated_enc_amt,0);
4792 l_ap_cancelled_qty := NVL(p_ap_cancelled_qty,0);
4793 
4794 l_progress := '010';
4795 
4796 -- Get functional currency setup
4797 SELECT
4798    FND_CUR.minimum_accountable_unit
4799 ,  FND_CUR.precision
4800 INTO
4801    l_min_acct_unit_func
4802 ,  l_cur_precision_func
4803 FROM FND_CURRENCIES FND_CUR
4804 WHERE FND_CUR.currency_code = p_currency_code_func
4805 ;
4806 
4807 IF g_debug_stmt THEN
4808    PO_DEBUG.debug_var(l_log_head,l_progress,'l_min_acct_unit_func', l_min_acct_unit_func);
4809    PO_DEBUG.debug_var(l_log_head,l_progress,'l_cur_precision_func', l_cur_precision_func);
4810 END IF;
4811 
4812 
4813 --*********************************************************
4814 -- CALCULATE AMT_ORDERED FOR MAIN, BACKING DOCUMENTS
4815 --*********************************************************
4816 l_progress := '020';
4817 
4818 get_initial_amounts(
4819    p_action               => p_action
4820 ,  p_doc_type             => p_doc_type
4821 ,  p_doc_subtype          => p_doc_subtype
4822 ,  p_currency_code_func   => p_currency_code_func
4823 ,  p_min_acct_unit_func   => l_min_acct_unit_func
4824 ,  p_cur_precision_func   => l_cur_precision_func
4825 );
4826 
4827 --*********************************************************
4828 -- CALCULATE AMT_CLOSED FOR MAIN DOCUMENTS
4829 --*********************************************************
4830 l_progress := '030';
4831 
4832 get_main_doc_amts(
4833    p_action                 => p_action
4834 ,  p_doc_type               => p_doc_type
4835 ,  p_doc_subtype            => p_doc_subtype
4836 ,  p_ap_reinstated_enc_amt  => l_ap_reinstated_enc_amt
4837 ,  p_ap_cancelled_qty       => l_ap_cancelled_qty
4838 );
4839 
4840 --*********************************************************
4841 -- CALCULATE INTERMEDIATE VALUES FOR BACKING DOCUMENTS
4842 --*********************************************************
4843 l_progress := '040';
4844 
4845 IF p_doc_type NOT IN (g_doc_type_REQUISITION, g_doc_type_PA)
4846    AND p_action NOT IN (g_action_ADJUST, g_action_FINAL_CLOSE,
4847                         g_action_UNDO_FINAL_CLOSE)
4848 THEN
4849    -- Reqs and PAs can not have backing docs
4850    -- Adjust, FC actions do not have backing trxns
4851 
4852    l_progress := '050';
4853    IF g_debug_stmt THEN
4854       PO_DEBUG.debug_stmt(l_log_head,l_progress,'Doc type can have backing docs');
4855    END IF;
4856 
4857    --<Complex Work R12>: determine if the Std PO is a Complex Work PO
4858    IF (p_doc_subtype = g_doc_subtype_STANDARD) THEN
4859      -- There should only be 1 main doc per encumbrance trxn in the Standard PO
4860      -- Requester Change Order is the only code that calls encumbrance on multiple docs
4861      -- and they pass the subtype as MIXED_PO_RELEASE.
4862      -- Requester Change Order is not supported for Complex Work POs.
4863 
4864      SELECT header_id
4865      INTO l_header_id
4866      FROM PO_ENCUMBRANCE_GT
4867      WHERE origin_sequence_num is null --main doc
4868      AND rownum = 1  --just get first record since all should have same ID
4869      ;
4870 
4871      l_is_complex_work_po := PO_COMPLEX_WORK_PVT.is_complex_work_po(l_header_id);
4872 
4873    END IF;
4874 
4875    IF (NOT l_is_complex_work_po) THEN
4876      --<Complex Work R12>: skip this method for Complex Work POs
4877      --Complex Work backing Req calculations are done separately, after
4878      --the main doc final amount is set and rounded
4879 
4880      -- Bug 3480949: Use l_ap_cancelled_qty instead of p_ap_cancelled_qty
4881      -- Also, use l_ap_reinstated_enc_amt instead of l_ap_amt_billed_changed
4882      -- The latter variable was being used to stored tax excluded values,
4883      -- but now that p_ap_reinstated_end_amt is assumed to be tax excluded,
4884      -- l_ap_amt_billed_changed has been obsoleted.
4885      get_backing_doc_amts(
4886         p_action               => p_action
4887      ,  p_doc_type             => p_doc_type
4888      ,  p_doc_subtype          => p_doc_subtype
4889      ,  p_currency_code_func   => p_currency_code_func
4890      ,  p_min_acct_unit_func   => l_min_acct_unit_func
4891      ,  p_cur_precision_func   => l_cur_precision_func
4892      ,  p_ap_cancelled_qty     => l_ap_cancelled_qty
4893      ,  p_ap_amt_billed_change => l_ap_reinstated_enc_amt
4894      );
4895 
4896    END IF; --If non-Complex Work case
4897 
4898 END IF;  -- p_action <> Adjust, FC  (so action can have backing trxns)
4899 
4900 --*********************************************************
4901 -- CALCULATE FINAL AMTS FOR MAIN AND BACKING DOCUMENTS
4902 --*********************************************************
4903 l_progress := '060';
4904 
4905 get_final_amounts(
4906    p_action             => p_action
4907 ,  p_doc_type           => p_doc_type
4908 ,  p_doc_subtype        => p_doc_subtype
4909 ,  p_currency_code_func => p_currency_code_func
4910 ,  p_min_acct_unit_func => l_min_acct_unit_func
4911 ,  p_cur_precision_func => l_cur_precision_func
4912 ,  p_ap_reinstated_enc_amt => l_ap_reinstated_enc_amt
4913 ,  p_is_complex_work_po => l_is_complex_work_po --<Complex Work R12>
4914 );
4915 
4916 l_progress := '070';
4917 
4918 IF g_debug_stmt THEN
4919    PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows);
4920    PO_DEBUG.debug_end(l_log_head);
4921 END IF;
4922 
4923 
4924 EXCEPTION
4925    WHEN FND_API.G_EXC_ERROR THEN
4926       RAISE;
4927 
4928    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
4929       RAISE;
4930 
4931    WHEN OTHERS THEN
4932       --add message to the stack and log a debug msg if necessary
4933       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
4934       fnd_msg_pub.add;
4935       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4936 
4937 END get_amounts;
4938 
4939 
4940 -------------------------------------------------------------------------------
4941 --Start of Comments
4942 --Name: get_initial_amounts
4943 --Pre-reqs:
4944 --  The PO_ENCUMBRANCE_GT temp table has been populated with all
4945 --  required information about the main and backing documents; and
4946 --  Encumbrance is on for the doc type of the main doc.
4947 --Modifies:
4948 --  PO_ENCUMBRANCE_GT
4949 --Locks:
4950 --  None.
4951 --Function:
4952 --  Performs the basic calculations for both main and backing docs:
4953 --  1. Calculate the amount_ordered (initial request amt on PO/Req)
4954 --  2. Calculate the 'rate' multiplier for nonrecoverable_tax
4955 --Parameters:
4956 --IN:
4957 --p_action
4958 --   Specifies the action that is being taken on the main doc.
4959 --p_doc_type
4960 --   Differentiates between the doc being a REQ, PO, or RELEASE
4961 --p_doc_subtype
4962 --   Used to differentiate between
4963 --      Scheduled Release vs. Blanket Release
4964 --      Std PO vs. PPO
4965 --p_currency_code_func
4966 --   Identifies the currency that is defined as the functional
4967 --   currency for the current set of books
4968 --p_min_acct_unit_func
4969 --   The minimum accountable unit (defined in FND_CURRENCIES) of the
4970 --   functional currency for the currency Set of Books
4971 --p_cur_precision_func
4972 --   The precision (defined in FND_CURRENCIES) of the functional
4973 --   currency for the current Set of Books
4974 --Testing:
4975 --
4976 --End of Comments
4977 -------------------------------------------------------------------------------
4978 PROCEDURE get_initial_amounts(
4979    p_action               IN  VARCHAR2
4980 ,  p_doc_type             IN  VARCHAR2
4981 ,  p_doc_subtype          IN  VARCHAR2
4982 ,  p_currency_code_func   IN  VARCHAR2
4983 ,  p_min_acct_unit_func   IN  NUMBER
4984 ,  p_cur_precision_func   IN  NUMBER
4985 )
4986 IS
4987 
4988    l_api_name     CONSTANT VARCHAR2(40) := 'GET_INITIAL_AMOUNTS';
4989    l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
4990    l_progress     VARCHAR2(3) := '000';
4991 
4992 BEGIN
4993 
4994 IF g_debug_stmt THEN
4995    PO_DEBUG.debug_begin(l_log_head);
4996    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
4997    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
4998    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
4999    PO_DEBUG.debug_var(l_log_head,l_progress,'p_min_acct_unit_func', p_min_acct_unit_func);
5000    PO_DEBUG.debug_var(l_log_head,l_progress,'p_cur_precision_func', p_cur_precision_func);
5001 END IF;
5002 
5003 
5004 -- If the doc is a BPA, or can have a backing BPA, convert
5005 -- any BPA dist amount_to_encumber to functional currency
5006 -- and store this in the amt_to_encumber_func column.
5007 -- For BPAs, we need to do this before further calculations
5008 -- since the amount_to_encumber and the unencumbered_amount may
5009 -- be in different currencies, and are compared in later calculations.
5010 IF p_doc_subtype IN (g_doc_subtype_BLANKET, g_doc_subtype_STANDARD,
5011                      g_doc_subtype_MIXED_PO_RELEASE)
5012 THEN
5013    round_and_convert_amounts(
5014       p_action => p_action
5015    ,  p_currency_code_func => p_currency_code_func
5016    ,  p_min_acct_unit_func => p_min_acct_unit_func
5017    ,  p_cur_precision_func => p_cur_precision_func
5018    ,  p_column_to_use => g_column_AMOUNT_TO_ENCUMBER
5019    );
5020 END IF;
5021 
5022 l_progress := '010';
5023 
5024 -- Now, calculate the intial amount_ordered for both the
5025 -- main and backing documents
5026 
5027 -- First, get the qty_ordered for quantity-based lines
5028 UPDATE PO_ENCUMBRANCE_GT DISTS
5029 SET DISTS.qty_ordered = nvl(DISTS.quantity_ordered, 0)
5030 WHERE DISTS.prevent_encumbrance_flag = 'N'
5031 AND DISTS.amount_based_flag = 'N'
5032 ;
5033 
5034 l_progress := '020';
5035 
5036 -- Now, get amt_ordered for both Service and non-Service lines
5037 UPDATE PO_ENCUMBRANCE_GT DISTS
5038 SET DISTS.amt_ordered =
5039     DECODE(DISTS.distribution_type
5040           -- Agreements
5041           ,  g_dist_type_AGREEMENT, amt_to_encumber_func
5042 
5043           -- All other doc types
5044           ,  DECODE(DISTS.amount_based_flag
5045                    -- Quantity based lines:
5046                    ,  'N', DISTS.qty_ordered * DISTS.price
5047 
5048                    -- Amount based lines:
5049                    ,  DISTS.amount_ordered
5050           )
5051     )
5052 WHERE DISTS.prevent_encumbrance_flag = 'N'
5053 ;
5054 
5055 l_progress := '030';
5056 
5057 IF g_debug_stmt THEN
5058    PO_DEBUG.debug_table(
5059       l_log_head, l_progress,'PO_ENCUMBRANCE_GT', PO_DEBUG.g_all_rows,
5060       po_tbl_varchar30( 'amount_based_flag', 'qty_ordered', 'amt_ordered' )
5061    );
5062 END IF;
5063 
5064 -- Based on the amount_ordered and the stored tax amount,
5065 -- we can calculate the 'rate' of that tax.
5066 
5067 -- Note: we do not worry about foreign vs functional currency
5068 -- for nonrecoverable_tax_rate, since it is obtained by dividing
5069 -- two amounts that are either both foreign or both functional.
5070 
5071 -- Note: the nonrecoverable_tax can be negative due
5072 -- to tax adjustments from Req Split.(bug 3428139, bug 3428600)
5073 
5074 UPDATE PO_ENCUMBRANCE_GT DISTS
5075 SET DISTS.nonrecoverable_tax_rate =
5076    DECODE(  NVL(DISTS.amt_ordered,0)
5077 
5078          -- Bug 3410522: If amt_ordered is 0, we can ignore tax.
5079          ,  0, 0
5080 
5081          -- Else, calculate rate multiplier for tax
5082          ,  (1 + (DISTS.nonrecoverable_tax / DISTS.amt_ordered))
5083          )
5084 WHERE DISTS.prevent_encumbrance_flag = 'N'
5085 ;
5086 
5087 l_progress := '040';
5088 
5089 IF g_debug_stmt THEN
5090    PO_DEBUG.debug_table(
5091       l_log_head, l_progress,'PO_ENCUMBRANCE_GT', PO_DEBUG.g_all_rows,
5092       po_tbl_varchar30( 'nonrecoverable_tax_rate')
5093    );
5094    PO_DEBUG.debug_end(l_log_head);
5095 END IF;
5096 
5097 
5098 EXCEPTION
5099    WHEN FND_API.G_EXC_ERROR THEN
5100       RAISE;
5101 
5102    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
5103       RAISE;
5104 
5105   WHEN OTHERS THEN
5106       --add message to the stack and log a debug msg if necessary
5107       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
5108       fnd_msg_pub.add;
5109       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5110 
5111 END get_initial_amounts;
5112 
5113 
5114 -------------------------------------------------------------------------------
5115 --Start of Comments
5116 --Name: get_main_doc_amts
5117 --Pre-reqs:
5118 --  The PO_ENCUMBRANCE_GT temp table has been populated with all
5119 --  required information about the main and backing documents; and
5120 --  Encumbrance is on for the doc type of the main doc.
5121 --Modifies:
5122 --  PO_ENCUMBRANCE_GT
5123 --Locks:
5124 --  None.
5125 --Function:
5126 --  Calculates the amount of encumbrance from the main document that
5127 --  is now 'relieved', e.g. for a PO, from billing/delivery; or for a
5128 --  PPO/PA, from releases created against them
5129 --Parameters:
5130 --IN:
5131 --p_action
5132 --   Specifies the action that is being taken on the main doc.
5133 --p_doc_type
5134 --   Differentiates between the doc being a REQ, PO, or RELEASE
5135 --p_doc_subtype
5136 --   Used to differentiate between
5137 --      Scheduled Release vs. Blanket Release
5138 --      Std PO vs. PPO
5139 --p_ap_reinstated_enc_amt
5140 --   For Invoice/Credit Memo cancel only: the amount of encumbrance
5141 --   put back on by AP (w/o any AP variances)
5142 --p_ap_cancelled_qty
5143 --   For Invoice/Credit Memo cancel only: the quantity of the
5144 --   cancelled invoice
5145 --Testing:
5146 --
5147 --End of Comments
5148 -------------------------------------------------------------------------------
5149 PROCEDURE get_main_doc_amts(
5150    p_action                 IN  VARCHAR2
5151 ,  p_doc_type               IN  VARCHAR2
5152 ,  p_doc_subtype            IN  VARCHAR2
5153 ,  p_ap_reinstated_enc_amt  IN  NUMBER
5154 ,  p_ap_cancelled_qty       IN  NUMBER
5155 )
5156 IS
5157 
5158    l_api_name     CONSTANT VARCHAR2(40) := 'GET_MAIN_DOC_AMTS';
5159    l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
5160    l_progress     VARCHAR2(3) := '000';
5161 
5162    -- Bug 3480949: removed now unused variabe l_ap_amt_billed_change
5163 
5164 BEGIN
5165 
5166 IF g_debug_stmt THEN
5167    PO_DEBUG.debug_begin(l_log_head);
5168    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
5169    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
5170    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
5171    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_reinstated_enc_amt', p_ap_reinstated_enc_amt);
5172    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_cancelled_qty', p_ap_cancelled_qty);
5173 END IF;
5174 
5175 
5176 IF p_action NOT IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL) THEN
5177    -- All other encumbrance actions (Res, Unres, Adjust, Cancel etc..)
5178    l_progress := '010';
5179 
5180    IF (p_doc_type = g_doc_type_REQUISITION) THEN
5181       -- main doc is a Req
5182       l_progress := '020';
5183 
5184       UPDATE PO_ENCUMBRANCE_GT DISTS
5185       SET DISTS.amt_closed =
5186             DISTS.amt_ordered *
5187             DECODE(  DISTS.amount_based_flag
5188 
5189                   -- Quantity-based:
5190                   -- closed amt is pro-rated from the req line's qty delivered
5191                   -- (used for internal Reqs tied to Sales Orders)
5192                   ,  'N', (DISTS.quantity_delivered / DISTS.quantity_on_line)
5193 
5194                   -- Amount-based:
5195                   -- The amt_closed for Services Req lines is always zero,
5196                   -- as they can not be tied to Sales Orders
5197                   ,  0
5198                   )
5199       WHERE DISTS.prevent_encumbrance_flag = 'N'
5200       ;
5201 
5202    ELSIF (p_doc_type = g_doc_type_PA) THEN
5203       -- main doc is a BPA/GA
5204       l_progress := '030';
5205 
5206       -- The closed amount for BPAs is the amount of encumbrance already
5207       -- relieved against the BPA
5208       UPDATE PO_ENCUMBRANCE_GT DISTS
5209       SET DISTS.amt_closed = DISTS.unencumbered_amount
5210       WHERE DISTS.prevent_encumbrance_flag = 'N'
5211       ;
5212 
5213    ELSE
5214       -- main doc is a PPO, PO, or Release (or mix of Std POs/Bl Releases)
5215 
5216       -- First, get the qty_closed for non-Service lines, based on the doc type
5217       -- Then, calculate amt_closed for all line types
5218 
5219       IF (p_doc_subtype = g_doc_subtype_PLANNED) THEN
5220          l_progress := '040';
5221 
5222          -- For PPO, qty closed = qty unencumbered by SR's against the PPO
5223          UPDATE PO_ENCUMBRANCE_GT DISTS
5224          SET DISTS.qty_closed = DISTS.unencumbered_quantity
5225          WHERE DISTS.origin_sequence_num IS NULL  -- main doc
5226          AND DISTS.prevent_encumbrance_flag = 'N'
5227          AND DISTS.amount_based_flag = 'N'
5228          -- no Services lines on a PPO
5229          ;
5230 
5231       ELSE
5232          -- the doc_type is a Std PO or Release (or mix of Std POs/ Bl Releases)
5233          l_progress := '050';
5234 
5235          -- in this case, qty closed is the amount that is already
5236          -- moved to an actual (and not considered for future encumbrance
5237          -- actions)
5238          UPDATE PO_ENCUMBRANCE_GT DISTS
5239          SET DISTS.qty_closed =
5240             DECODE(  DISTS.accrue_on_receipt_flag
5241 
5242                   -- Online Accruals
5243                   ,  'Y', DISTS.quantity_delivered
5244 
5245                   -- Period-End Accruals:
5246                   ,  DECODE(  p_action
5247 
5248                            -- Cancel:
5249                            ,  g_action_CANCEL,
5250                                  GREATEST(   DISTS.quantity_billed
5251                                           ,  DISTS.quantity_delivered
5252                                           )
5253                               -- Invoices can be made against
5254                               -- Cancelled POs. Even if period-end
5255                               -- accrual is used, use the delivered
5256                               -- qty as closed if its greater than
5257                               -- billed qty, because the delivered
5258                               -- qty may be invoiced in the future.
5259 
5260                            -- Actions other than Cancel:
5261                            ,  DISTS.quantity_billed
5262 
5263                            )
5264                   )
5265          WHERE DISTS.origin_sequence_num IS NULL  -- main doc
5266          AND DISTS.amount_based_flag = 'N'
5267          AND DISTS.prevent_encumbrance_flag = 'N'
5268          ;
5269 
5270       END IF;  -- check on p_doc_subtype to calculate qty_closed
5271 
5272       l_progress := '060';
5273 
5274       -- Now that we have the qty_closed for the qty-based main doc
5275       -- lines, we can get the amt_closed for all main doc lines.
5276       UPDATE PO_ENCUMBRANCE_GT DISTS
5277       SET DISTS.amt_closed =
5278             DECODE(  DISTS.amount_based_flag
5279 
5280                   -- quantity-based: use qty_closed calc from above
5281                   ,  'N', DISTS.qty_closed * DISTS.price
5282 
5283                   -- amount-based: mimic qty_closed calc on amt field analogs
5284                   ,  DECODE(  DISTS.accrue_on_receipt_flag
5285 
5286                            -- Online Accruals:
5287                            ,  'Y', DISTS.amount_delivered
5288 
5289                            -- Period-End Accruals:
5290                            ,  DECODE(  p_action
5291 
5292                                     -- Cancel:
5293                                     ,  g_action_CANCEL,
5294                                        GREATEST(   DISTS.amount_billed
5295                                                 ,  DISTS.amount_delivered
5296                                                 )
5297                                        -- Invoices can be made against
5298                                        -- Cancelled POs. Even if period-end
5299                                        -- accrual is used, use the delivered
5300                                        -- amt as closed if its greater than
5301                                        -- billed amt, because the delivered
5302                                        -- amt may be invoiced in the future.
5303 
5304                                     -- Actions other than Cancel:
5305                                     ,  DISTS.amount_billed
5306                                     )
5307                            )
5308                   )
5309       WHERE DISTS.origin_sequence_num IS NULL  --main doc
5310       AND DISTS.prevent_encumbrance_flag = 'N'
5311       ;
5312 
5313    END IF;  -- amt_closed calculation for main doc
5314 
5315 
5316 ELSE
5317    -- p_action is AP Inv/Cr Memo Cancel
5318    -- do calculations based on p_ap_reinstated_enc_amt passed in by AP
5319    -- this parameter represents the amount of encumbrance AP posted back to PO
5320    -- in the ledger, excluding any tax
5321 
5322    l_progress := '080';
5323 
5324    IF g_debug_stmt THEN
5325       PO_DEBUG.debug_stmt(l_log_head,l_progress,'doing AP calculations for main doc');
5326    END IF;
5327 
5328    -- Bug 3480949: Removed logic that would remove tax from ap amount
5329    -- AP now calls the invoice cancel API with p_tax_line_flag = 'Y'
5330    -- and passes a tax free amount into p_ap_reinstated_enc_amt
5331    -- No longer need to store tax free amount in l_ap_amt_billed_change
5332 
5333 
5334    -- The qty_closed and amt_closed set here
5335    -- will be used for backing doc calculations.
5336    -- qty_closed must be updated before amt_closed,
5337    -- since it is used in the calculation for amt_closed.
5338 
5339    UPDATE PO_ENCUMBRANCE_GT DISTS
5340    SET DISTS.qty_closed =
5341          DECODE(  p_action
5342                ,  g_action_INVOICE_CANCEL,
5343                      DISTS.quantity_billed + p_ap_cancelled_qty
5344 
5345                -- cr memo cancel
5346                ,  DISTS.quantity_billed
5347                )
5348    WHERE DISTS.prevent_encumbrance_flag = 'N'
5349    AND   DISTS.origin_sequence_num IS NULL
5350    AND   DISTS.amount_based_flag = 'N'
5351    ;
5352 
5353    l_progress := '100';
5354 
5355   -- Bug 3480949: Use p_ap_reinstated_enc_amt instead of
5356   -- deleted variable l_ap_amt_billed_change
5357 
5358    UPDATE PO_ENCUMBRANCE_GT DISTS
5359    SET DISTS.amt_closed =
5360          DECODE(  DISTS.amount_based_flag
5361 
5362                ,  'N', DISTS.qty_closed * DISTS.price
5363 
5364                ,  DECODE(  p_action
5365                         ,  g_action_INVOICE_CANCEL,
5366                               p_ap_reinstated_enc_amt + DISTS.amount_billed
5367 
5368                         -- cr memo cancel
5369                         ,  DISTS.amount_billed
5370                         )
5371                )
5372    WHERE DISTS.prevent_encumbrance_flag = 'N'
5373    AND DISTS.origin_sequence_num IS NULL
5374    ;
5375 
5376    l_progress := '110';
5377 
5378 END IF;  -- p_action is AP Inv Cancel vs. any other action
5379 
5380 IF g_debug_stmt THEN
5381    PO_DEBUG.debug_stmt(l_log_head,l_progress,
5382       'Calculated amount_closed for main document'
5383    );
5384    PO_DEBUG.debug_table(
5385       l_log_head, l_progress,'PO_ENCUMBRANCE_GT', PO_DEBUG.g_all_rows,
5386       po_tbl_varchar30( 'amount_based_flag', 'qty_closed', 'amt_closed')
5387    );
5388    PO_DEBUG.debug_end(l_log_head);
5389 END IF;
5390 
5391 
5392 EXCEPTION
5393    WHEN FND_API.G_EXC_ERROR THEN
5394       RAISE;
5395 
5396    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
5397       RAISE;
5398 
5399   WHEN OTHERS THEN
5400       --add message to the stack and log a debug msg if necessary
5401       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
5402       fnd_msg_pub.add;
5403       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5404 
5405 END get_main_doc_amts;
5406 
5407 
5408 
5409 -------------------------------------------------------------------------------
5410 --Start of Comments
5411 --Name: get_backing_doc_amts
5412 --Pre-reqs:
5413 --  The PO_ENCUMBRANCE_GT temp table has been populated with all
5414 --  required information about the main and backing documents; and
5415 --  Encumbrance is on for the doc type of the main doc.
5416 --Modifies:
5417 --  PO_ENCUMBRANCE_GT
5418 --Locks:
5419 --  None.
5420 --Function:
5421 --  Calculates the amount of encumbrance from the backing Req/PPO that
5422 --  is still 'active', e.g. for a PPO: the amount that is not yet relieved,
5423 --  or for a backing Req: the difference in the Req qty and the amount
5424 --  relieved on the PO.
5425 --Parameters:
5426 --IN:
5427 --p_action
5428 --   Specifies the action that is being taken on the main doc.
5429 --p_doc_type
5430 --   Differentiates between the doc being a REQ, PO, or RELEASE
5431 --p_doc_subtype
5432 --   Used to differentiate between
5433 --      Scheduled Release vs. Blanket Release
5434 --      Std PO vs. PPO
5435 --p_currency_code_func
5436 --   Identifies the currency that is defined as the functional
5437 --   currency for the current set of books
5438 --p_min_acct_unit_func
5439 --   The minimum accountable unit (defined in FND_CURRENCIES) of the
5440 --   functional currency for the currency Set of Books
5441 --p_cur_precision_func
5442 --   The precision (defined in FND_CURRENCIES) of the functional
5443 --   currency for the current Set of Books
5444 --p_ap_cancelled_qty
5445 --   For Invoice/Credit Memo cancel only: the quantity of the
5446 --   cancelled invoice
5447 --p_ap_amt_billed_change
5448 --   For Invoice/Credit Memo cancel only: the amount of invoice
5449 --   cancelled encumbrance (minus variances/tax)
5450 --Testing:
5451 --
5452 --End of Comments
5453 -------------------------------------------------------------------------------
5454 PROCEDURE get_backing_doc_amts(
5455    p_action               IN  VARCHAR2
5456 ,  p_doc_type             IN  VARCHAR2
5457 ,  p_doc_subtype          IN  VARCHAR2
5458 ,  p_currency_code_func   IN  VARCHAR2
5459 ,  p_min_acct_unit_func   IN  NUMBER
5460 ,  p_cur_precision_func   IN  NUMBER
5461 ,  p_ap_cancelled_qty     IN  NUMBER
5462 ,  p_ap_amt_billed_change IN  NUMBER
5463 )
5464 IS
5465    l_api_name     CONSTANT VARCHAR2(40) := 'GET_BACKING_DOC_AMTS';
5466    l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
5467    l_progress     VARCHAR2(3) := '000';
5468 
5469    l_uom_conversion_error  VARCHAR2(1) := 'N';
5470 
5471 BEGIN
5472 
5473 -- Note: No Calculations for backing Agreements in this procedure.
5474 -- The backing PA encumbrances are set in the call to
5475 -- check_backing_pa_amounts, where the backing PA amount
5476 -- is copied from the main doc amount, and possibly adjusted
5477 -- downwards to stay within PA amt limits.  This occurs AFTER the
5478 -- final rounding/conversion, to prevent penny differences
5479 
5480 IF g_debug_stmt THEN
5481    PO_DEBUG.debug_begin(l_log_head);
5482    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
5483    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
5484    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
5485    PO_DEBUG.debug_var(l_log_head,l_progress,'p_currency_code_func', p_currency_code_func);
5486    PO_DEBUG.debug_var(l_log_head,l_progress,'p_min_acct_unit_func', p_min_acct_unit_func);
5487    PO_DEBUG.debug_var(l_log_head,l_progress,'p_cur_precision_func', p_cur_precision_func);
5488    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_cancelled_qty', p_ap_cancelled_qty);
5489    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_amt_billed_change', p_ap_amt_billed_change);
5490 END IF;
5491 
5492 
5493 -- Calculations for Backing Reqs:
5494 IF (  (p_doc_subtype IN (g_doc_subtype_PLANNED,
5495                          g_doc_subtype_STANDARD,
5496                          g_doc_subtype_MIXED_PO_RELEASE))
5497    OR
5498       (p_doc_type = g_doc_type_RELEASE
5499        AND p_doc_subtype = g_doc_subtype_BLANKET) ) THEN
5500    -- Only PPOs, Standard POs and Blanket Releases have backing Reqs
5501 
5502    l_progress := '010';
5503 
5504    IF (p_action <> g_action_CANCEL) THEN
5505       -- During a Cancel with Recreate Demand, the recreated Req dist
5506       -- generated by the Cancel code is not tied to the PO/Rel.  It is a
5507       -- fresh dist and will not have any closed amount, so we don't need
5508       -- to do these calculations.
5509       l_progress := '020';
5510 
5511       IF g_debug_stmt THEN
5512          PO_DEBUG.debug_stmt(l_log_head,l_progress,
5513                              'Starting calculations for backing Reqs');
5514       END IF;
5515 
5516 
5517       -- Get unit of measure conversion rate, if backing Req UOM is
5518       -- different from main doc UOM
5519       UPDATE PO_ENCUMBRANCE_GT REQ_DISTS
5520       SET REQ_DISTS.uom_conversion_rate =
5521          (SELECT PO_UOM_S.PO_UOM_CONVERT_P( PO_DISTS.unit_meas_lookup_code
5522                                           , REQ_DISTS.unit_meas_lookup_code
5523                                           , REQ_DISTS.item_id
5524                                           )
5525           FROM PO_ENCUMBRANCE_GT PO_DISTS
5526           WHERE REQ_DISTS.origin_sequence_num = PO_DISTS.sequence_num
5527           AND PO_DISTS.distribution_type <> g_dist_type_REQUISITION
5528           AND REQ_DISTS.unit_meas_lookup_code <>
5529                  PO_DISTS.unit_meas_lookup_code
5530          )
5531       WHERE REQ_DISTS.distribution_type = g_dist_type_REQUISITION
5532       AND REQ_DISTS.amount_based_flag = 'N'
5533       AND REQ_DISTS.prevent_encumbrance_flag = 'N'
5534       ;
5535 
5536       l_progress := '030';
5537 
5538       IF g_debug_stmt THEN
5539          PO_DEBUG.debug_stmt(l_log_head,l_progress,'did UoM conversion');
5540          PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows
5541             ,po_tbl_varchar30('prevent_encumbrance_flag','amount_based_flag'
5542                ,'distribution_type','uom_conversion_rate','unit_meas_lookup_code'
5543                ,'item_id','sequence_num','origin_sequence_num'
5544                )
5545             );
5546       END IF;
5547 
5548       -- The UOM conversion above uses a function called within the SQL
5549       -- Check to see if any of the rows returned error from the function
5550       BEGIN
5551          SELECT 'Y'
5552          INTO l_uom_conversion_error
5553          FROM PO_ENCUMBRANCE_GT REQ_DISTS
5554          WHERE REQ_DISTS.distribution_type = g_dist_type_REQUISITION
5555          AND REQ_DISTS.amount_based_flag = 'N'
5556          AND REQ_DISTS.prevent_encumbrance_flag = 'N'
5557          AND REQ_DISTS.uom_conversion_rate = -999
5558          -- the uom function returns -999 on error
5559          AND rownum = 1 -- only need there to be one for it to be an error
5560                         -- (also, without this causes an error for > 1)
5561          ;
5562       EXCEPTION
5563          WHEN NO_DATA_FOUND THEN
5564             l_uom_conversion_error := 'N';
5565       END;
5566 
5567       IF g_debug_stmt THEN
5568          PO_DEBUG.debug_var(l_log_head,l_progress,'l_uom_conversion_error',l_uom_conversion_error);
5569       END IF;
5570 
5571       IF (l_uom_conversion_error = 'Y') THEN
5572          l_progress := '040';
5573          RAISE FND_API.G_EXC_ERROR;
5574       END IF;
5575 
5576       l_progress := '050';
5577 
5578       -- bug 3435571: call round_and_convert amts for main doc amt_closed
5579       -- This is because for Services PO autocreated from Services Req, the
5580       -- Req amts are in functional currency while the PO closed amt could be
5581       -- in foreign currency.  The call below populates a separate column
5582       -- PO_DISTS.amt_closed_func in functional currency so that it can be
5583       -- directly compared to the Req amt.
5584       round_and_convert_amounts(
5585          p_action => p_action
5586       ,  p_currency_code_func => p_currency_code_func
5587       ,  p_min_acct_unit_func => p_min_acct_unit_func
5588       ,  p_cur_precision_func => p_cur_precision_func
5589       ,  p_column_to_use => g_column_AMT_CLOSED
5590       );
5591 
5592       IF p_action NOT IN (g_action_INVOICE_CANCEL,
5593                           g_action_CR_MEMO_CANCEL) THEN
5594 
5595          -- p_action is one of: Check/Do Reserve, Unreserve, Reject
5596          -- Note: FC, Undo FC, Return, Adjust do not have backing Reqs,
5597          -- Cancel w/ recreate demand uses new Req line (so not this calc)
5598          -- and backing Req for Invoice Cancel is calculated separately
5599          l_progress := '060';
5600 
5601          UPDATE PO_ENCUMBRANCE_GT REQ_DISTS
5602          SET REQ_DISTS.amt_closed =
5603             (SELECT
5604                DECODE(  REQ_DISTS.amount_based_flag
5605 
5606                      -- quantity based
5607                      ,  'N', PO_DISTS.qty_closed
5608                               * NVL(REQ_DISTS.uom_conversion_rate,1)
5609                               * REQ_DISTS.price
5610 
5611                      -- amount based
5612                      ,  PO_DISTS.amt_closed_func  --bug 3435571
5613                )
5614              FROM PO_ENCUMBRANCE_GT PO_DISTS
5615              WHERE REQ_DISTS.origin_sequence_num = PO_DISTS.sequence_num
5616              AND PO_DISTS.distribution_type <> g_dist_type_REQUISITION
5617             )
5618          WHERE REQ_DISTS.distribution_type = g_dist_type_REQUISITION
5619          AND REQ_DISTS.prevent_encumbrance_flag = 'N'
5620          ;
5621 
5622       ELSE
5623          -- p_action is Invoice/Credit Memo Cancel
5624          l_progress := '070';
5625 
5626          UPDATE PO_ENCUMBRANCE_GT REQ_DISTS
5627          SET REQ_DISTS.qty_open =
5628             (SELECT
5629                DECODE(  greatest(0, REQ_DISTS.qty_ordered -
5630                                     (PO_DISTS.qty_closed *
5631                                     NVL(REQ_DISTS.uom_conversion_rate,1))
5632                                  )
5633 
5634                      --Req qty < PO qty
5635                      --put (Req qty - PO billed qty) on Req
5636                      ,  0 , (REQ_DISTS.qty_ordered -
5637                               ( NVL(REQ_DISTS.uom_conversion_rate,1)
5638                                 * (PO_DISTS.qty_closed
5639                                    - p_ap_cancelled_qty) )
5640                              )
5641 
5642                      --if zero, Req qty > PO billed qty
5643                      --put entire cancelled qty on Req
5644                      ,  (p_ap_cancelled_qty
5645                            * NVL(REQ_DISTS.uom_conversion_rate,1))
5646                      )
5647             FROM PO_ENCUMBRANCE_GT PO_DISTS
5648             WHERE REQ_DISTS.origin_sequence_num = PO_DISTS.sequence_num
5649             AND PO_DISTS.distribution_type <> g_dist_type_REQUISITION
5650             ) --end select
5651          WHERE REQ_DISTS.distribution_type = g_dist_type_REQUISITION
5652          AND REQ_DISTS.prevent_encumbrance_flag = 'N'
5653          AND REQ_DISTS.amount_based_flag = 'N'
5654          ;
5655 
5656          l_progress := '080';
5657 
5658          UPDATE PO_ENCUMBRANCE_GT REQ_DISTS
5659          SET REQ_DISTS.amt_open =
5660             (SELECT
5661                DECODE(  REQ_DISTS.amount_based_flag
5662 
5663                      --quantity-based
5664                      ,  'N', REQ_DISTS.qty_open * REQ_DISTS.price
5665 
5666                      , --amount based
5667                      DECODE( greatest(0, REQ_DISTS.amt_ordered -
5668                                          PO_DISTS.amt_closed_func) --bug 3435571
5669 
5670                            --if zero, Req amt > PO billed amt
5671                            --put (Req amt - PO billed amt) on Req
5672                            ,  0 , (REQ_DISTS.amt_ordered
5673                                    - (PO_DISTS.amt_closed_func  --bug 3435571
5674                                    - p_ap_amt_billed_change))  -- bug 3480949: fixed parenthesis
5675 
5676                            --put entire cancelled amt on Req
5677                            --we will add tax to and round this amt
5678                            ,  p_ap_amt_billed_change
5679                            )
5680                      )
5681             FROM PO_ENCUMBRANCE_GT PO_DISTS
5682             WHERE REQ_DISTS.origin_sequence_num = PO_DISTS.sequence_num
5683             AND PO_DISTS.distribution_type <> g_dist_type_REQUISITION
5684             )
5685          WHERE REQ_DISTS.distribution_type = g_dist_type_REQUISITION
5686          AND REQ_DISTS.prevent_encumbrance_flag = 'N'
5687          ;
5688 
5689          l_progress := '090';
5690 
5691 
5692       END IF; --p_action is Inv Cancel vs other actions
5693 
5694    END IF;  -- p_action <> Cancel
5695 
5696    IF g_debug_stmt THEN
5697       PO_DEBUG.debug_stmt(l_log_head,l_progress,
5698          'Calculated amount_closed for backing Reqs'
5699          );
5700       PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows
5701          ,po_tbl_varchar30('prevent_encumbrance_flag','amount_based_flag'
5702             ,'qty_open','qty_ordered','qty_closed','uom_conversion_rate'
5703             ,'quantity_billed','distribution_type','sequence_num','origin_sequence_num'
5704             ,'amt_open','price','amt_ordered','amt_closed','amount_billed'
5705             )
5706          );
5707    END IF;
5708 
5709 END IF;  -- doc type is one that can have a backing Req
5710 
5711 
5712 -- Calculations for Backing PPOs:
5713 IF (p_doc_subtype = g_doc_subtype_SCHEDULED) THEN
5714 
5715    -- For backing PPOs of Scheduled Releases, we do not calculate an
5716    -- explicit 'closed' amount.  Instead, we update the 'open quantity'
5717    -- of the PPO, based on the SR open quantity.
5718    -- This PPO open quantity is then used to:
5719    -- 1) calculate the PPO open amt directly (not amt_ordered - amt_closed)
5720    --    in the get_final_amts procedure (this needs to be calculated b/c
5721    --    PPO can have different price from SR, can't assume SR's amt_open
5722    --    will be same amt for the backing PPO trxn).
5723    -- 2) update the PPO unencumbered_quantity during post-processing.
5724 
5725    l_progress := '100';
5726    IF g_debug_stmt THEN
5727       PO_DEBUG.debug_stmt(l_log_head,l_progress,'Starting calculations for backing PPOs');
5728    END IF;
5729 
5730    IF p_action NOT IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL) THEN
5731 
5732       -- p_action is one of: Check/Do Reserve, Unreserve, Reject, Cancel, Adjust
5733       -- Note: FC, Undo FC, Return do not have backing PPO scenarios,
5734       -- and backing PPO qty for Invoice Cancel is calculated separately
5735       l_progress := '110';
5736 
5737       UPDATE PO_ENCUMBRANCE_GT PPO_DISTS
5738       SET PPO_DISTS.qty_open =
5739          (SELECT SR_DISTS.qty_ordered - SR_DISTS.qty_closed
5740           FROM PO_ENCUMBRANCE_GT SR_DISTS
5741           WHERE SR_DISTS.sequence_num = PPO_DISTS.origin_sequence_num
5742          )
5743       WHERE PPO_DISTS.origin_sequence_num IS NOT NULL
5744       AND PPO_DISTS.prevent_encumbrance_flag = 'N'
5745       ;
5746 
5747    ELSE
5748 
5749       -- p_action is Invoice/Credit Memo Cancel
5750       l_progress := '120';
5751 
5752       UPDATE PO_ENCUMBRANCE_GT PPO_DISTS
5753       SET PPO_DISTS.qty_open =
5754          (SELECT
5755             DECODE(  greatest(0, SR_DISTS.qty_ordered -
5756                                     SR_DISTS.qty_closed
5757                               )
5758 
5759                   --put difference between SR ord and SR billed
5760                   --back on PPO
5761                   ,  0 , SR_DISTS.qty_ordered -
5762                            DECODE(  p_action
5763                                  ,  g_action_INVOICE_CANCEL,
5764                                        SR_DISTS.quantity_billed
5765 
5766                                  -- cr memo cancel
5767                                  ,  SR_DISTS.quantity_billed +
5768                                        p_ap_cancelled_qty
5769                                  )
5770 
5771                   --put entire cancelled qty on PPO
5772                   ,  p_ap_cancelled_qty
5773                   )
5774          FROM PO_ENCUMBRANCE_GT SR_DISTS
5775          WHERE PPO_DISTS.origin_sequence_num = SR_DISTS.sequence_num
5776          )
5777       WHERE PPO_DISTS.origin_sequence_num IS NOT NULL
5778       AND PPO_DISTS.prevent_encumbrance_flag = 'N'
5779       ;
5780 
5781    END IF;  -- if action is Invoice Cancel vs. other actions
5782 
5783    IF g_debug_stmt THEN
5784       PO_DEBUG.debug_stmt(l_log_head,l_progress,
5785          'Updated qty_open for backing PPO'
5786       );
5787       PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows
5788          ,po_tbl_varchar30('prevent_encumbrance_flag'
5789             ,'qty_open','qty_ordered','qty_closed','quantity_billed'
5790             ,'distribution_type','sequence_num','origin_sequence_num')
5791       );
5792    END IF;
5793 
5794 END IF; -- doc can have a backing PPO
5795 
5796 IF g_debug_stmt THEN
5797    PO_DEBUG.debug_end(l_log_head);
5798 END IF;
5799 
5800 
5801 EXCEPTION
5802    WHEN FND_API.G_EXC_ERROR THEN
5803       RAISE;
5804 
5805    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
5806       RAISE;
5807 
5808   WHEN OTHERS THEN
5809       --add message to the stack and log a debug msg if necessary
5810       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
5811       fnd_msg_pub.add;
5812       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5813 
5814 END get_backing_doc_amts;
5815 
5816 
5817 
5818 -------------------------------------------------------------------------------
5819 --Start of Comments
5820 --Name: get_final_amounts
5821 --Pre-reqs:
5822 --  The PO_ENCUMBRANCE_GT temp table has been populated with all
5823 --  required information about the main and backing documents; and
5824 --  Encumbrance is on for the doc type of the main doc.
5825 --Modifies:
5826 --  PO_ENCUMBRANCE_GT
5827 --Locks:
5828 --  None.
5829 --Function:
5830 --  Based on the initial encumbrance amounts, and any amounts that are already
5831 --  closed (calculated previously), this procedure sets the final transaction
5832 --  amount on each distribution.  This includes currency conversion and final
5833 --  rounding.  Additionally, this is the procedure in which we adjust any
5834 --  backing PA amounts to ensure that their sum is within the PA limits
5835 --Parameters:
5836 --IN:
5837 --p_action
5838 --   Specifies the action that is being taken on the main doc.
5839 --p_doc_type
5840 --   Differentiates between the doc being a REQ, PO, or RELEASE
5841 --p_doc_subtype
5842 --   Used to differentiate between
5843 --      Scheduled Release vs. Blanket Release
5844 --      Std PO vs. PPO
5845 --p_currency_code_func
5846 --   Identifies the currency that is defined as the functional
5847 --   currency for the current set of books
5848 --p_min_acct_unit_func
5849 --   The minimum accountable unit (defined in FND_CURRENCIES) of the
5850 --   functional currency for the currency Set of Books
5851 --p_cur_precision_func
5852 --   The precision (defined in FND_CURRENCIES) of the functional
5853 --   currency for the current Set of Books
5854 --p_ap_reinstated_enc_amt
5855 --   For Invoice/Credit Memo cancel only: the amount of encumbrance
5856 --   put back on by AP (w/o any AP variances)
5857 --p_is_complex_work_po
5858 --   Boolean value indicating whether the document the encumbrance
5859 --   action is being taken on is a Complex Work PO or not
5860 --Testing:
5861 --
5862 --End of Comments
5863 -------------------------------------------------------------------------------
5864 PROCEDURE get_final_amounts(
5865    p_action                IN  VARCHAR2
5866 ,  p_doc_type              IN  VARCHAR2
5867 ,  p_doc_subtype           IN  VARCHAR2
5868 ,  p_currency_code_func    IN  VARCHAR2
5869 ,  p_min_acct_unit_func    IN  NUMBER
5870 ,  p_cur_precision_func    IN  NUMBER
5871 ,  p_ap_reinstated_enc_amt IN  NUMBER
5872 ,  p_is_complex_work_po    IN  BOOLEAN --<Complex Work R12>
5873 )
5874 IS
5875    l_api_name     CONSTANT VARCHAR2(40) := 'GET_FINAL_AMOUNTS';
5876    l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
5877    l_progress     VARCHAR2(3) := '000';
5878 
5879 BEGIN
5880 
5881 IF g_debug_stmt THEN
5882    PO_DEBUG.debug_begin(l_log_head);
5883    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
5884    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type', p_doc_type);
5885    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype', p_doc_subtype);
5886    PO_DEBUG.debug_var(l_log_head,l_progress,'p_currency_code_func', p_currency_code_func);
5887    PO_DEBUG.debug_var(l_log_head,l_progress,'p_min_acct_unit_func', p_min_acct_unit_func);
5888    PO_DEBUG.debug_var(l_log_head,l_progress,'p_cur_precision_func', p_cur_precision_func);
5889    PO_DEBUG.debug_var(l_log_head,l_progress,'p_ap_reinstated_enc_amt', p_ap_reinstated_enc_amt);
5890 END IF;
5891 
5892 -- First, calculate the 'open' amount, which is basically the
5893 -- transaction amount without any tax or rounding.
5894 
5895 -- Note: for backing PPO trxns, we base the transaction amount of
5896 -- the backing PPO not on how much encumbrance is left on the PPO,
5897 -- but on how much we are transacting on the current SR.  This is
5898 -- because we can have multiple SRs against a single backing PPO, so
5899 -- we are not always relieving the full PPO amt.
5900 
5901 IF (p_doc_subtype = g_doc_subtype_SCHEDULED) THEN
5902 
5903    l_progress := '010';
5904 
5905    UPDATE PO_ENCUMBRANCE_GT PPO_DISTS
5906    SET PPO_DISTS.amt_open =
5907        PPO_DISTS.qty_open * PPO_DISTS.price
5908        -- no Services lines on PPOs/SRs
5909    WHERE PPO_DISTS.origin_sequence_num IS NOT NULL  --backing document
5910    AND PPO_DISTS.distribution_type = g_dist_type_PLANNED
5911    AND PPO_DISTS.prevent_encumbrance_flag = 'N'
5912    ;
5913 
5914 END IF;
5915 
5916 l_progress := '020';
5917 
5918 -- For cases other than the backing PPO, the amt_open represents
5919 -- the difference in the original amount of encumbrance and the
5920 -- amount of encumbrance already moved off to actuals.
5921 -- The greatest(0, <>) adjusts for over-delivered/billed case
5922 
5923 UPDATE PO_ENCUMBRANCE_GT DISTS
5924 SET DISTS.amt_open =
5925    DECODE( DISTS.amt_open
5926 
5927          -- if NULL, then it needs to be calculated still
5928          ,  NULL,
5929                GREATEST( 0 , DISTS.amt_ordered - nvl(DISTS.amt_closed, 0))
5930 
5931          -- already calculated (backing PPO), so do not overwrite
5932          ,  GREATEST(0, DISTS.amt_open)
5933          )
5934 WHERE DISTS.prevent_encumbrance_flag = 'N'
5935 ;
5936 
5937 l_progress := '030';
5938 
5939 
5940 IF p_action IN (g_action_FINAL_CLOSE, g_action_UNDO_FINAL_CLOSE) THEN
5941 
5942    -- For Final Close and Undo Final Close actions only, we need to
5943    -- further subtract out the cancelled amount to get the true open amt
5944    -- Note: these actions do not create backing doc trxns, so we are
5945    --       only peforming this subtraction for the main document
5946 
5947    l_progress := '040';
5948 
5949 
5950    -- Bug 3498811: Truncate amt_open to 0 if it is less than 0.
5951 
5952    --<bug#5199301 START>
5953    --We do not have to subtract cancelled amount on BPA's because
5954    --you cannot cancel quantity/amount on the BPA itself. You can do
5955    --it only on releases. For BPA's the unencumbered amount accounts
5956    --for cancelled quantity of the relese as well.
5957 
5958    UPDATE PO_ENCUMBRANCE_GT DISTS
5959    SET DISTS.amt_open =
5960       GREATEST( 0,
5961                   DISTS.amt_open -
5962                      DECODE(  DISTS.amount_based_flag
5963 
5964                          -- quantity_based:
5965                          ,  'N',  nvl(quantity_cancelled, 0) * nvl(DISTS.price,0)
5966 
5967                          -- Services line:
5968                          ,  nvl(amount_cancelled, 0)
5969                          )
5970               )
5971    WHERE DISTS.prevent_encumbrance_flag = 'N'
5972      AND DISTS.distribution_type <>g_dist_type_AGREEMENT
5973    ;
5974    --<bug#5199301 END>
5975 
5976    l_progress := '050';
5977 
5978   -- end if action is Final Close, Undo Final Close
5979 
5980 ELSIF p_action IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL) THEN
5981 
5982    -- Bug 3480949: Logic changed, and moved up here
5983    -- For these actions, AP passes us the amount they posted
5984    -- to GL, excluding taxes.  They also call us with the tax only in
5985    -- a second API call, but that API call is ignored.  So, set the
5986    -- amt_open to p_ap_reinstated_enc_amt, so that we add tax below.
5987 
5988    l_progress := '055';
5989 
5990    UPDATE PO_ENCUMBRANCE_GT DISTS
5991    SET DISTS.amt_open = p_ap_reinstated_enc_amt
5992    WHERE DISTS.prevent_encumbrance_flag = 'N'
5993    AND DISTS.origin_sequence_num IS NULL  -- main doc
5994    ;
5995 
5996    -- end elsif action in Invoice Cancel, CR Memo Cancel
5997 
5998 END IF;
5999 
6000 
6001 
6002 IF g_debug_stmt THEN
6003    PO_DEBUG.debug_stmt(l_log_head,l_progress,
6004       'Updated amt_open for all lines'
6005    );
6006    PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows
6007                         ,po_tbl_varchar30('prevent_encumbrance_flag' ,'amt_open',
6008                         'qty_ordered','qty_closed','quantity_billed', 'quantity_cancelled'
6009                         ,'distribution_type','sequence_num','origin_sequence_num')
6010    );
6011 END IF;
6012 
6013 
6014 -- Before we do any rounding, we need to add in the tax (pro-rated)
6015 UPDATE PO_ENCUMBRANCE_GT DISTS
6016 SET DISTS.pre_round_amt = (DISTS.amt_open * DISTS.nonrecoverable_tax_rate)
6017 WHERE DISTS.prevent_encumbrance_flag = 'N'
6018 AND DISTS.amt_open IS NOT NULL
6019 ;
6020 
6021 l_progress := '060';
6022 IF g_debug_stmt THEN
6023    PO_DEBUG.debug_stmt(l_log_head,l_progress,
6024       'Updated pre_round_amt for all lines'
6025    );
6026    PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows
6027                         ,po_tbl_varchar30('prevent_encumbrance_flag' ,'pre_round_amt')
6028    );
6029 END IF;
6030 
6031 
6032 -- By now, all of the pre_round_amt columns should be populated,
6033 -- so we can do the final currency conversion and rounding now
6034 -- Note: we used this procedure on other columns previously for 2 cases
6035 -- (backing Req and backing PA), when we needed to convert an intermediate
6036 -- value for comparison.  However, the actual trxn amounts in the table
6037 -- remained in foreign currency.  Now, this call will populate the
6038 -- final_amt column, in which ALL entries are in functional currency.
6039 round_and_convert_amounts(
6040    p_action => p_action
6041 ,  p_currency_code_func => p_currency_code_func
6042 ,  p_min_acct_unit_func => p_min_acct_unit_func
6043 ,  p_cur_precision_func => p_cur_precision_func
6044 ,  p_column_to_use => g_column_PRE_ROUND_AMT
6045 )
6046 ;
6047 
6048 
6049 
6050 IF p_doc_subtype IN (g_doc_subtype_STANDARD, g_doc_subtype_BLANKET,
6051                      g_doc_subtype_MIXED_PO_RELEASE) THEN
6052    -- only Std POs and Bl Releases can have backing PAs
6053    l_progress := '100';
6054 
6055    -- At this point, the final_amt column values for the
6056    -- backing PA entries are based on the final_amt values for
6057    -- the corresponding PO/Rel distribution.
6058    -- However, it is possible that this would over-relieve the
6059    -- BPA, because the BPA amount_to_encumber may be less than
6060    -- the overall BPA amount_limit for releases.
6061    -- This procedure will correct the backing PA entries, if
6062    -- this over-relieving situation arises.  We do this correction
6063    -- of the backing PA amounts AFTER doing the rounding and
6064    -- conversion to avoid the adjusted totals being off
6065    -- by penny differences.
6066 
6067    check_backing_pa_amounts(
6068       p_action => p_action
6069    );
6070 
6071 
6072    --<Complex Work R12 START>: For Complex Work, the backing Req amount should
6073    --be set AFTER the main PO doc amount has had tax and rounding calculations
6074    --performed. (Similar reasoning as for backing BPA logic above)
6075    IF (p_is_complex_work_po) THEN
6076 
6077      set_complex_work_req_amounts(
6078        p_action => p_action
6079      );
6080 
6081    END IF;
6082    --<Complex Work R12 END>
6083 
6084 END IF;
6085 
6086 l_progress := '110';
6087 
6088 IF g_debug_stmt THEN
6089    PO_DEBUG.debug_end(l_log_head);
6090 END IF;
6091 
6092 
6093 EXCEPTION
6094    WHEN FND_API.G_EXC_ERROR THEN
6095       RAISE;
6096 
6097    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
6098       RAISE;
6099 
6100   WHEN OTHERS THEN
6101       --add message to the stack and log a debug msg if necessary
6102       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
6103       fnd_msg_pub.add;
6104       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6105 
6106 END get_final_amounts;
6107 
6108 
6109 
6110 -------------------------------------------------------------------------------
6111 --Start of Comments
6112 --Name: round_and_convert_amounts
6113 --Pre-reqs:
6114 --  The PO_ENCUMBRANCE_GT temp table has been populated with all
6115 --  required information about the main and backing documents; and
6116 --  Encumbrance is on for the doc type of the main doc.
6117 --Modifies:
6118 --  PO_ENCUMBRANCE_GT
6119 --Locks:
6120 --  None.
6121 --Function:
6122 --  This procedure is a wrapper around the currency rounding procedure
6123 --  in PO_CORE_S2.  It pulls the appropriate column to be rounded from
6124 --  the Encumbrance GTT and also updates a corresponding column with
6125 --  the results of the round/conversion.
6126 --  GTT Column to Round           Column with Rounded Result
6127 --  AMOUNT_TO_ENCUMBER            AMT_TO_ENCUMBER_FUNC
6128 --  AMT_CLOSED                    AMT_CLOSED_FUNC
6129 --  PRE_ROUND_AMT                 FINAL_AMT
6130 --Parameters:
6131 --IN:
6132 --p_action
6133 --  Current encumbrance action being performed
6134 --p_currency_code_func
6135 --   Identifies the currency that is defined as the functional
6136 --   currency for the current set of books
6137 --p_min_acct_unit_func
6138 --   The minimum accountable unit (defined in FND_CURRENCIES) of the
6139 --   functional currency for the currency Set of Books
6140 --p_cur_precision_func
6141 --   The precision (defined in FND_CURRENCIES) of the functional
6142 --   currency for the current Set of Books
6143 --p_column_to_use
6144 --  Specifies with column of PO_ENCUMBRANCE_GT to convert and round
6145 --  Valid Values:
6146 --     g_column_AMOUNT_TO_ENCUMBER,
6147 --     g_column_AMOUNT_CLOSED
6148 --     g_column_PRE_ROUND_AMT
6149 --Testing:
6150 --  List any test scripts that exist, etc.
6151 --End of Comments
6152 -------------------------------------------------------------------------------
6153 PROCEDURE round_and_convert_amounts(
6154    p_action              IN  VARCHAR2
6155 ,  p_currency_code_func  IN  VARCHAR2
6156 ,  p_min_acct_unit_func  IN  NUMBER
6157 ,  p_cur_precision_func  IN  NUMBER
6158 ,  p_column_to_use       IN  VARCHAR2
6159 )
6160 
6161 IS
6162    l_api_name CONSTANT varchar2(40) := 'ROUND_AND_CONVERT_AMOUNTS';
6163    l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
6164    l_progress     VARCHAR2(3) := '000';
6165 
6166    l_return_status              VARCHAR2(1);
6167    l_sequence_num_tbl           PO_TBL_NUMBER;
6168    l_amount_to_round_tbl        PO_TBL_NUMBER;
6169    l_exchange_rate_tbl          PO_TBL_NUMBER;
6170    l_cur_precision_foreign_tbl  PO_TBL_NUMBER;
6171    l_min_acct_unit_foreign_tbl  PO_TBL_NUMBER;
6172    l_cur_precision_func_tbl     PO_TBL_NUMBER;
6173    l_min_acct_unit_func_tbl     PO_TBL_NUMBER;
6174    l_round_only_flag_tbl        PO_TBL_VARCHAR1;  --bug 3568671
6175    l_amount_result_tbl          PO_TBL_NUMBER;
6176 
6177    l_origin_sequence_num_tbl    PO_TBL_NUMBER;  -- bug 3480949
6178 
6179 BEGIN
6180 
6181 IF g_debug_stmt THEN
6182    PO_DEBUG.debug_begin(l_log_head);
6183    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action', p_action);
6184    PO_DEBUG.debug_var(l_log_head,l_progress,'p_currency_code_func', p_currency_code_func);
6185    PO_DEBUG.debug_var(l_log_head,l_progress,'p_min_acct_unit_func', p_min_acct_unit_func);
6186    PO_DEBUG.debug_var(l_log_head,l_progress,'p_cur_precision_func', p_cur_precision_func);
6187    PO_DEBUG.debug_var(l_log_head,l_progress,'p_column_to_use',p_column_to_use);
6188 END IF;
6189 
6190 SELECT
6191    DISTS.sequence_num
6192 ,  DECODE( p_column_to_use
6193 
6194          ,  g_column_AMOUNT_TO_ENCUMBER, DISTS.amount_to_encumber
6195 
6196          ,  g_column_AMT_CLOSED, DISTS.amt_closed
6197 
6198          ,  g_column_PRE_ROUND_AMT, DISTS.pre_round_amt
6199 
6200          ,  NULL
6201    )
6202 
6203 -- bug 3568671: removed conditional setting of rate.
6204 -- we now use the l_round_only_flag_tbl to indicate that
6205 -- we do not want to do a currency conversion.
6206 ,  DISTS.rate
6207 ,  DISTS.cur_precision_foreign
6208 ,  DISTS.min_acct_unit_foreign
6209 ,  p_cur_precision_func
6210 ,  p_min_acct_unit_func
6211 
6212 -- bug 3568671: For BPA distributions, currency conversion
6213 -- should only occur for column to use = g_column_AMOUNT_TO_ENCUMBER.
6214 -- We do this initial conversion for foreign currency BPAs, and then
6215 -- all other calculated values are already in functional currency
6216 -- (i.e amt_closed/pre_round_amt), however, there will still be a
6217 -- foreign currency code and rate in the GTT.  We do not want to repeat
6218 -- the currency conversion a 2nd time.  But rounding should occur for all
6219 -- 3 of these columns.
6220 -- Rounding without currency conversion is achieved by setting the
6221 -- round_only_flag to 'Y' when calling PO_CORE_S2.round_and_convert_currency
6222 ,  DECODE ( DISTS.distribution_type
6223            , g_dist_type_AGREEMENT, DECODE( p_column_to_use
6224                                           , g_column_AMOUNT_TO_ENCUMBER, 'N'
6225                                           , 'Y'
6226                                     )
6227            , 'N'
6228    )
6229   -- Bug 3480949: capture origin_sequence_number
6230 ,  DISTS.origin_sequence_num
6231 BULK COLLECT INTO
6232    l_sequence_num_tbl
6233 ,  l_amount_to_round_tbl
6234 ,  l_exchange_rate_tbl
6235 ,  l_cur_precision_foreign_tbl
6236 ,  l_min_acct_unit_foreign_tbl
6237 ,  l_cur_precision_func_tbl
6238 ,  l_min_acct_unit_func_tbl
6239 ,  l_round_only_flag_tbl     --bug 3568671
6240 ,  l_origin_sequence_num_tbl -- bug 3480949
6241 FROM PO_ENCUMBRANCE_GT DISTS
6242 WHERE DISTS.prevent_encumbrance_flag = 'N'
6243 ORDER BY DISTS.sequence_num
6244 ;
6245 
6246 
6247 -- Bug 3480949: Do not convert currency for the main document
6248 -- if action is invoice or credit memo cancel.  In that case,
6249 -- which occurs through the reinstate PO encumbrance API call by AP,
6250 -- the final amount should be set to rounded value of
6251 -- p_ap_reinstated_enc_amt * nonrecoverable_tax rate.  Do not do
6252 -- currency conversion, as AP passes us that value in func. currency.
6253 
6254 IF (p_action IN (g_action_INVOICE_CANCEL, g_action_CR_MEMO_CANCEL))
6255 THEN
6256 
6257   FOR i IN 1..l_round_only_flag_tbl.COUNT
6258   LOOP
6259     -- Set main doc round only flag to 'Y'
6260     IF (l_origin_sequence_num_tbl(i) is NULL) THEN
6261        l_round_only_flag_tbl(i) := 'Y';
6262     END IF;
6263 
6264   END LOOP;
6265 
6266 END IF;
6267 
6268 l_progress := '010';
6269 
6270 -- Call the currency conversion/rounding routine
6271 PO_CORE_S2.round_and_convert_currency(
6272    x_return_status               => l_return_status
6273 ,  p_unique_id_tbl               => l_sequence_num_tbl  --bug 4878973
6274 ,  p_amount_in_tbl               => l_amount_to_round_tbl
6275 ,  p_exchange_rate_tbl           => l_exchange_rate_tbl
6276 ,  p_from_currency_precision_tbl => l_cur_precision_foreign_tbl
6277 ,  p_from_currency_mau_tbl       => l_min_acct_unit_foreign_tbl
6278 ,  p_to_currency_precision_tbl   => l_cur_precision_func_tbl
6279 ,  p_to_currency_mau_tbl         => l_min_acct_unit_func_tbl
6280 ,  p_round_only_flag_tbl         => l_round_only_flag_tbl --bug 3568671
6281 ,  x_amount_out_tbl              => l_amount_result_tbl
6282 );
6283 
6284 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6285    l_progress := '015';
6286    -- the API already pushed the SQL error details
6287    -- onto the message stack, so just raise this to
6288    -- bubble back up to do_action.
6289    RAISE FND_API.g_EXC_UNEXPECTED_ERROR;
6290 END IF;
6291 
6292 l_progress := '020';
6293 
6294 -- Now update the appropriate column of the Encumbrance GTT
6295 -- with the converted/rounded amounts.  The DECODEs are used
6296 -- so that if we do not update those columns which do not
6297 -- correspond to the value of p_column_to_use
6298 
6299 FORALL i IN 1 .. l_sequence_num_tbl.COUNT
6300    UPDATE PO_ENCUMBRANCE_GT DISTS
6301    SET
6302       amt_to_encumber_func =
6303         DECODE( p_column_to_use
6304               ,  g_column_AMOUNT_TO_ENCUMBER, l_amount_result_tbl(i)
6305               ,  DISTS.amt_to_encumber_func
6306         )
6307 
6308    ,  amt_closed_func =
6309         DECODE( p_column_to_use
6310               ,  g_column_AMT_CLOSED, l_amount_result_tbl(i)
6311               ,  DISTS.amt_closed_func
6312         )
6313 
6314    ,  final_amt =
6315         DECODE( p_column_to_use
6316               ,  g_column_PRE_ROUND_AMT, l_amount_result_tbl(i)
6317               ,  DISTS.final_amt
6318         )
6319    WHERE DISTS.prevent_encumbrance_flag = 'N'
6320    AND   DISTS.sequence_num = l_sequence_num_tbl(i)
6321    ;
6322 
6323 l_progress := '030';
6324 
6325 
6326 EXCEPTION
6327    WHEN FND_API.G_EXC_ERROR THEN
6328       RAISE;
6329 
6330    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
6331       RAISE;
6332 
6333    WHEN OTHERS THEN
6334       --add message to the stack and log a debug msg if necessary
6335       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
6336       fnd_msg_pub.add;
6337       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6338 
6339 END round_and_convert_amounts;
6340 
6341 
6342 -------------------------------------------------------------------------------
6343 --Start of Comments
6344 --Name: check_backing_pa_amounts
6345 --Pre-reqs:
6346 --  The final_amt column of PO_ENCUMBRANCE_GT has
6347 --  been populated correctly with the rounded functional amount for
6348 --  each of the distributions with backing agreements
6349 --  (PO against GA, Release against BPA)
6350 --  and the backing agreement distributions have also been loaded into
6351 --  PO_ENCUMBRANCE_GT.
6352 --  It only makes sense to call this if both PO and Req encumbrance are on
6353 --  (i.e., blanket encumbrance is enabled).
6354 --Modifies:
6355 --  PO_ENCUMBRANCE_GT
6356 --Locks:
6357 --  n/a
6358 --Function:
6359 --  This procedure updates the final_amt column of backing agreement
6360 --  rows in PO_ENCUMBRANCE_GT, based on the final_amt for each
6361 --  of the PO/Release distributions.
6362 --  It prohibits the sum of the amounts against the backing agreement
6363 --  from exceeding the limits of the agreement's encumbrance, based on
6364 --  the action being taken.
6365 --Parameters:
6366 --IN:
6367 --p_action
6368 --  Specifies the action that is being taken on the main doc.
6369 --Testing:
6370 --
6371 --End of Comments
6372 -------------------------------------------------------------------------------
6373 PROCEDURE check_backing_pa_amounts(
6374    p_action        IN   VARCHAR2
6375 )
6376 IS
6377 
6378 -- Scalar Variables
6379    l_api_name CONSTANT 		varchar2(40) := 'CHECK_BACKING_PA_AMOUNTS';
6380    l_progress 			varchar2(3);
6381    l_adjust_flag 		varchar2(1) := 'N';
6382    l_running_total 		number := 0;
6383    l_amount_available 		number := 0;
6384    l_start_row  		number := 0;
6385    l_end_row    		number := 0;
6386    l_changed_amounts_flag       varchar2(1) := 'N';
6387 
6388 -- Collections
6389    l_multiplier_tbl  	       po_tbl_number;
6390    l_pa_dist_id_tbl  	       po_tbl_number;
6391    l_pa_sequence_num_tbl       po_tbl_number;
6392    l_amt_to_encumber_func_tbl  po_tbl_number;
6393    l_unencumbered_amount_tbl   po_tbl_number;
6394    l_amount_tbl 	       po_tbl_number;
6395 
6396 BEGIN
6397 
6398 l_progress := '000';
6399 
6400 If g_fnd_debug = 'Y' Then
6401    IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
6402      FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
6403                   g_log_head || l_api_name || '.' || l_progress,
6404                   'Start of procedure'
6405                  );
6406    END IF;
6407 End If;
6408 
6409 -- Gather the data we need into pl/sql tables
6410 -- The logic is performed in a pl/sql loop due to performance limitations
6411 -- when doing running sums in SQL.
6412 SELECT
6413    DECODE( p_action
6414          -- For Adjust, row is +/- depending on whether its new/old
6415          ,  g_action_ADJUST, DECODE( PA_DISTS.adjustment_status
6416                                    ,  g_adj_status_OLD,  -1
6417                                    ,  1
6418                              )
6419 
6420          -- Reserve, multiplier is always positive 1
6421          ,  g_action_RESERVE,  1
6422 
6423          -- Other actions are all reversals, so use -1
6424          ,  -1
6425    )
6426 ,  PA_DISTS.distribution_id
6427 ,  PA_DISTS.sequence_num
6428 ,  PA_DISTS.amt_to_encumber_func
6429 ,  PA_DISTS.unencumbered_amount
6430 ,  PO_DISTS.final_amt
6431 BULK COLLECT INTO
6432    l_multiplier_tbl
6433 ,  l_pa_dist_id_tbl
6434 ,  l_pa_sequence_num_tbl
6435 ,  l_amt_to_encumber_func_tbl
6436 ,  l_unencumbered_amount_tbl
6437 ,  l_amount_tbl
6438 FROM
6439    PO_ENCUMBRANCE_GT PA_DISTS
6440 ,  PO_ENCUMBRANCE_GT PO_DISTS
6441 WHERE PA_DISTS.origin_sequence_num = PO_DISTS.sequence_num
6442 AND PA_DISTS.distribution_id = PO_DISTS.agreement_dist_id
6443 AND PO_DISTS.prevent_encumbrance_flag = 'N'
6444 AND PA_DISTS.distribution_type = g_dist_type_AGREEMENT
6445 ORDER BY PA_DISTS.distribution_id, PO_DISTS.gl_encumbered_date DESC;
6446 
6447    -- Note: the value in l_amount_tbl is always positive.
6448    -- Need to look at corresponding value in l_multiplier_tbl to
6449    -- determine whether it is adding/removing funds:
6450    -- If multiplier is -1, then the backing PA acct is being debited
6451    --                        (putting funds back on it)
6452    -- If multiplier is 1, then the backing PA acct is being credited
6453    --                        (removing funds from it)
6454 
6455 
6456 l_progress := '010';
6457 
6458 If g_fnd_debug = 'Y' Then
6459    IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
6460      FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
6461                   g_log_head || l_api_name || '.' || l_progress,
6462                   'Before looping'
6463                  );
6464    END IF;
6465 End If;
6466 
6467 
6468 -- The amount used on the backing BPA/GA is equal to the amount used on the
6469 -- Release/PO, except:
6470 --
6471 -- Reserve, Upward Adjust of Release/PO:
6472 -- The sum of all of the backing CRs to the BPA/GA cannot exceed
6473 -- amt_to_encumber_func - unencumbered_amount
6474 --
6475 -- Unreserve, Downward Adjust (and other reverses) of Release/PO:
6476 -- The sum of all of the backing DRs to the BPA/GA cannot exceed
6477 -- unencumbered_amount
6478 --
6479 
6480 FOR i IN 1 .. l_pa_dist_id_tbl.COUNT LOOP
6481    IF (i = 1) THEN
6482       -- first PA dist in tbl
6483       l_start_row := i;
6484       l_running_total := l_amount_tbl(i) * l_multiplier_tbl(i);
6485 
6486    ELSIF l_pa_dist_id_tbl(i) = l_pa_dist_id_tbl(i-1) THEN
6487       -- current PA is the same PA dist I've been working on
6488       l_running_total := l_running_total +
6489                          ( l_amount_tbl(i) * l_multiplier_tbl(i) );
6490 
6491    ELSIF l_pa_dist_id_tbl(i) <> l_pa_dist_id_tbl(i-1) THEN
6492       -- Hit a new PA dist id.  Mark the end of the old set.
6493       -- l_running_total is for dist id's between l_start_row and l_end_row
6494 
6495       l_end_row := i-1;
6496 
6497       -- Fix the amounts for the old (i-1) PA dist, if necessary
6498       correct_backing_pa_amounts(
6499          p_current_pa_dist_id   => l_pa_dist_id_tbl(l_start_row)
6500       ,  p_start_row            => l_start_row
6501       ,  p_end_row              => l_end_row
6502       ,  p_running_total        => l_running_total
6503       ,  p_amt_to_enc_func      => l_amt_to_encumber_func_tbl(l_start_row)
6504       ,  p_unencumbered_amt     => l_unencumbered_amount_tbl(l_start_row)
6505       ,  p_pa_sequence_num_tbl  => l_pa_sequence_num_tbl
6506       ,  p_pa_multiplier_tbl    => l_multiplier_tbl
6507       ,  x_pa_amount_tbl        => l_amount_tbl
6508       ,  x_changed_amounts_flag => l_changed_amounts_flag
6509       );
6510 
6511       -- Reset the variables for the current (new) PA dist:
6512       l_running_total := l_amount_tbl(i) * l_multiplier_tbl(i);
6513       l_start_row := i;
6514 
6515    END IF;  -- if i=1 or dist(i) ?= dist (i-1)
6516 
6517 
6518    IF (i = l_pa_dist_id_tbl.COUNT) THEN
6519       -- End case:  If I am on the last dist, but it is not a different
6520       -- PA from the previous dist, I won't know to make the call to
6521       -- correct_backing_pa_amounts, unless this case is explicitly handled
6522 
6523       l_end_row := i;
6524 
6525       -- Fix the amounts for the current (last) PA dist, if necessary
6526       correct_backing_pa_amounts(
6527          p_current_pa_dist_id   => l_pa_dist_id_tbl(l_start_row)
6528       ,  p_start_row            => l_start_row
6529       ,  p_end_row              => l_end_row
6530       ,  p_running_total        => l_running_total
6531       ,  p_amt_to_enc_func      => l_amt_to_encumber_func_tbl(l_start_row)
6532       ,  p_unencumbered_amt     => l_unencumbered_amount_tbl(l_start_row)
6533       ,  p_pa_sequence_num_tbl  => l_pa_sequence_num_tbl
6534       ,  p_pa_multiplier_tbl    => l_multiplier_tbl
6535       ,  x_pa_amount_tbl        => l_amount_tbl
6536       ,  x_changed_amounts_flag => l_changed_amounts_flag
6537       );
6538 
6539    END IF;  -- if i = last dist id
6540 
6541 END LOOP;
6542 
6543 l_progress := '020';
6544 
6545 -- Then, put the updated amounts back into the main GTT
6546 --IF (l_update_enc_gt_flag = 'Y') THEN
6547 
6548    FORALL i IN 1 .. l_amount_tbl.COUNT
6549       UPDATE PO_ENCUMBRANCE_GT PA_DISTS
6550       SET PA_DISTS.final_amt = l_amount_tbl(i)
6551       WHERE
6552           PA_DISTS.distribution_id = l_pa_dist_id_tbl(i)
6553       AND PA_DISTS.sequence_num = l_pa_sequence_num_tbl(i)
6554       AND PA_DISTS.distribution_type = g_dist_type_AGREEMENT
6555       ;
6556 
6557    If g_fnd_debug = 'Y' Then
6558       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
6559         FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
6560                      g_log_head || l_api_name || '.' || l_progress,
6561                      'Updated of global temp table PA amounts'
6562                     );
6563       END IF;
6564    End If;
6565 
6566 --END IF;
6567 
6568 l_progress := '030';
6569 
6570 If g_fnd_debug = 'Y' Then
6571    IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
6572      FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
6573                   g_log_head || l_api_name || '.' || l_progress,
6574                   'End of procedure'
6575                  );
6576    END IF;
6577 End If;
6578 
6579 EXCEPTION
6580    WHEN FND_API.G_EXC_ERROR THEN
6581       RAISE;
6582 
6583    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
6584       RAISE;
6585 
6586    WHEN OTHERS THEN
6587       --add message to the stack and log a debug msg if necessary
6588       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
6589       fnd_msg_pub.add;
6590       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6591 
6592 END check_backing_pa_amounts;
6593 
6594 
6595 -------------------------------------------------------------------------------
6596 --Start of Comments
6597 --Name: correct_backing_pa_amounts
6598 --Pre-reqs:
6599 --   PO_ENCUMBRANCE_GT is populated correctly with information about all
6600 --   the main doc and backing PA distributions
6601 --Modifies:
6602 --   PO_ENCUMBRANCE_GT
6603 --Locks:
6604 --  n/a
6605 --Function:
6606 --  This procedure updates the final_amt column of backing agreement
6607 --  rows in PO_ENCUMBRANCE_GT, based on the final_amt for each
6608 --  of the PO/Release distributions.
6609 --  It prohibits the sum of the amounts against the backing agreement
6610 --  from exceeding the limits of the agreement's encumbrance, based on
6611 --  the action being taken.
6612 --Parameters:
6613 --IN:
6614 --p_current_pa_dist_id
6615 --  The po_distribution_id of the BPA we are currently checking
6616 --p_start_row
6617 --  Index that indicates where the current BPA dists start in each
6618 --  of the 3 pl/sql table parameters
6619 --p_start_row
6620 --  Index that indicates where the current BPA dists end in each
6621 --  of the 3 pl/sql table parameters
6622 --p_running_total
6623 --  The overall sum of all CRs and DRs against the current PA
6624 --p_amt_to_enc_func
6625 --  The amount to encumber for the current PA, in functional currency
6626 --p_unencumbered_amt
6627 --  The unencumbered amount for the current PA, in functional currency
6628 --p_pa_sequence_num_tbl
6629 --  A colletion of sequence_nums corresponding to the sequence_nums in
6630 --  the PO_ENCUMBRANCE_GT of each backing PA row
6631 --p_pa_multiplier_tbl
6632 --  A collection where each element represents whether the corresponding
6633 --  element of the amount tbl is a DR or CR
6634 --IN OUT:
6635 --x_pa_amount_tbl
6636 --  A collection where each element represent the final_amt calculated
6637 --  in the PO_ENCUMBRANCE_GT table, for a given backing PA entry
6638 --Testing:
6639 --
6640 --End of Comments
6641 -------------------------------------------------------------------------------
6642 PROCEDURE correct_backing_pa_amounts(
6643    p_current_pa_dist_id   IN  NUMBER
6644 ,  p_start_row            IN  NUMBER
6645 ,  p_end_row              IN  NUMBER
6646 ,  p_running_total        IN  NUMBER
6647 ,  p_amt_to_enc_func      IN  NUMBER
6648 ,  p_unencumbered_amt     IN  NUMBER
6649 ,  p_pa_sequence_num_tbl  IN  po_tbl_number
6650 ,  p_pa_multiplier_tbl    IN  po_tbl_number
6651 ,  x_pa_amount_tbl        IN OUT NOCOPY po_tbl_number
6652 ,  x_changed_amounts_flag OUT NOCOPY VARCHAR2
6653 )
6654 
6655 IS
6656 
6657 l_proc_name CONSTANT VARCHAR2(30) := 'CORRECT_BACKING_PA_AMOUNTS';
6658 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_proc_name;
6659 l_progress  VARCHAR2(3) := '000';
6660 
6661 l_amount_available     NUMBER := 0;
6662 l_current_amount       NUMBER := 0;
6663 
6664 BEGIN
6665 
6666 IF g_debug_stmt THEN
6667    PO_DEBUG.debug_begin(l_log_head);
6668    PO_DEBUG.debug_var(l_log_head,l_progress,'p_current_pa_dist_id',p_current_pa_dist_id);
6669    PO_DEBUG.debug_var(l_log_head,l_progress,'p_start_row',p_start_row);
6670    PO_DEBUG.debug_var(l_log_head,l_progress,'p_end_row',p_end_row);
6671    PO_DEBUG.debug_var(l_log_head,l_progress,'p_running_total',p_running_total);
6672    PO_DEBUG.debug_var(l_log_head,l_progress,'p_amt_to_enc_func',p_amt_to_enc_func);
6673    PO_DEBUG.debug_var(l_log_head,l_progress,'p_unencumbered_amt',p_unencumbered_amt);
6674    PO_DEBUG.debug_var(l_log_head,l_progress,'p_pa_sequence_num_tbl',p_pa_sequence_num_tbl);
6675    PO_DEBUG.debug_var(l_log_head,l_progress,'p_pa_multiplier_tbl',p_pa_multiplier_tbl);
6676    PO_DEBUG.debug_var(l_log_head,l_progress,'x_pa_amount_tbl',x_pa_amount_tbl);
6677 END IF;
6678 
6679 l_progress := '010';
6680 
6681 -- Determine the max amount available, depending on whether
6682 -- the overall transaction is a DR or CR:
6683 
6684 IF (p_running_total > 0) THEN
6685    -- The overall backing trxn is relieving the PA (CR against PA acct)
6686    l_amount_available := p_amt_to_enc_func - p_unencumbered_amt;
6687 
6688 ELSIF (p_running_total <= 0) then
6689    -- The overall backing trxn is encumbering the PA (DR against PA acct)
6690    l_amount_available := p_unencumbered_amt;
6691 
6692 END IF;
6693 
6694 -- Now, check if the amount from our running some is greater
6695 -- than the total amount available from above.  If it is, then
6696 -- zero out those distributions that exceed the maximum:
6697 l_progress := '020';
6698 
6699 IF g_debug_stmt THEN
6700    PO_DEBUG.debug_var(l_log_head,l_progress,'l_amount_available',l_amount_available);
6701 END IF;
6702 
6703 IF ABS(p_running_total) > l_amount_available THEN
6704    -- The sum of the PA amount entries is too high.
6705    -- Some of them will be adjusted downwards.
6706 
6707    l_progress := '100';
6708 
6709    -- First, figure out which amounts to zero out
6710    FOR i in p_start_row .. p_end_row LOOP
6711 
6712       If SIGN(p_pa_multiplier_tbl(i)) <> SIGN(p_running_total) THEN
6713 
6714          -- In the Adjust case, zero out those rows that are
6715          -- doing the opposite of the overall transaction (i.e.
6716          -- zero all CR rows if the overall trxn was a DR)
6717          x_pa_amount_tbl(i) := 0;
6718 
6719       Else
6720          -- For the rows with the correct sign, ensure that
6721          -- their sum does not exceed the amount available
6722 
6723          l_current_amount := x_pa_amount_tbl(i);
6724 
6725          If (l_current_amount <= l_amount_available) Then
6726             l_amount_available := l_amount_available - l_current_amount;
6727          Else
6728             x_pa_amount_tbl(i) := l_amount_available;
6729             l_amount_available := 0;
6730          End If;
6731 
6732        End If;
6733 
6734    END LOOP;
6735 
6736    x_changed_amounts_flag := 'Y';
6737 
6738 ELSE
6739    -- this is not the over-relieved case, so no changes required
6740    x_changed_amounts_flag := 'N';
6741 
6742 END IF;  -- if running total was greater than amt available
6743 
6744 l_progress := '900';
6745 
6746 IF g_debug_stmt THEN
6747    PO_DEBUG.debug_var(l_log_head,l_progress,'x_pa_amount_tbl',x_pa_amount_tbl);
6748    PO_DEBUG.debug_var(l_log_head,l_progress,'x_changed_amounts_flag',x_changed_amounts_flag);
6749    PO_DEBUG.debug_end(l_log_head);
6750 END IF;
6751 
6752 EXCEPTION
6753 
6754 WHEN OTHERS THEN
6755    --add message to the stack and log a debug msg if necessary
6756    po_message_s.sql_error(g_pkg_name, l_proc_name, l_progress, SQLCODE, SQLERRM);
6757    fnd_msg_pub.add;
6758    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6759 
6760 END correct_backing_pa_amounts;
6761 
6762 
6763 --<Complex Work R12 START>
6764 -------------------------------------------------------------------------------
6765 --Start of Comments
6766 --Name: set_complex_work_req_amounts
6767 --Pre-reqs:
6768 --  The final_amt column of PO_ENCUMBRANCE_GT has
6769 --  been populated correctly with the rounded functional amount for
6770 --  each of the Complex Work PO distributions
6771 --Modifies:
6772 --  PO_ENCUMBRANCE_GT
6773 --Locks:
6774 --  n/a
6775 --Function:
6776 --  This procedure updates the final_amt column of backing Req rows in
6777 --  PO_ENCUMBRANCE_GT, based on the final_amt for each of the main doc
6778 --  (Complex Work PO doc) distributions
6779 --  It prohibits the sum of the amounts against the backing Requisition
6780 --  from exceeding the limits of the Requisition's encumbrance, if funds
6781 --  are being returned to the Requisition.  If funds are being liquidated
6782 --  from the Requisition, it ensures that no hanging balances are left on
6783 --  the Requisition
6784 --Parameters:
6785 --IN:
6786 --p_action
6787 --  Specifies the action that is being taken on the main doc.
6788 --Testing:
6789 --
6790 --End of Comments
6791 -------------------------------------------------------------------------------
6792 PROCEDURE set_complex_work_req_amounts(
6793    p_action        IN   VARCHAR2
6794 )
6795 IS
6796 
6797 -- Scalar Variables
6798   l_api_name CONSTANT 	varchar2(40) := 'SET_COMPLEX_WORK_REQ_AMOUNTS';
6799   l_log_head     CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
6800   l_progress 		varchar2(3);
6801 
6802 -- Collections
6803   l_req_dist_id_tbl		po_tbl_number;
6804   l_max_total_tbl		po_tbl_number;
6805   l_req_dist_gtt_total_tbl 	po_tbl_number;
6806 
6807 BEGIN
6808 
6809 l_progress := '000';
6810 
6811 IF g_debug_stmt THEN
6812    PO_DEBUG.debug_begin(l_log_head);
6813    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action',p_action);
6814 END IF;
6815 
6816 
6817 -- Algorithm:
6818 -- Set the backing Req final amount to be equal to the main doc final amount.
6819 -- For PO Reserve/Check Funds, the sum for each distinct backing Req dist must
6820 --   equal the total encumbered_amount for that distribution.  Make sure that
6821 --   the last distribution carries any extra balance, or that the distributions
6822 --   are adjusted downwards if they would over-relieve.
6823 -- For PO Unreserve/Reject, the sum for each distinct backing Req distribution
6824 --    may be less than the total allowable amount for the Req, but can not
6825 --    exceed this amount.
6826 
6827 -- First, set the backing Req dist final amount equal to the corresponding
6828 -- main doc final amount
6829 UPDATE PO_ENCUMBRANCE_GT BACKING_REQ
6830 SET BACKING_REQ.final_amt =
6831 	(SELECT MAIN_DOC.final_amt
6832 	 FROM PO_ENCUMBRANCE_GT MAIN_DOC
6833 	 WHERE MAIN_DOC.sequence_num = BACKING_REQ.origin_sequence_num
6834 	 AND MAIN_DOC.origin_sequence_num IS NULL)
6835 WHERE BACKING_REQ.origin_sequence_num IS NOT NULL
6836 AND BACKING_REQ.distribution_type = g_dist_type_REQUISITION
6837 AND BACKING_REQ.prevent_encumbrance_flag = 'N'
6838 ;
6839 IF g_debug_stmt THEN
6840    PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows,NULL,'PO');
6841 END IF;
6842 l_progress := '010';
6843 
6844 -- Next, extract the l_max_total_tbl for each distinct Req distribution: it
6845 -- is either the current Req encumbered amount (on Reserve/Check Funds actions)
6846 -- or the Req amount ordered (on Unreserve/Reject actions).  Note: the value
6847 -- of amount_ordered is set in the get_initial_amounts procedure.
6848 -- Also, extract the current GTT total for each distinct Req dist, based on
6849 -- what we copied over from the main doc in the first step.
6850 SELECT
6851   BACKING_REQ.distribution_id
6852 , MAX(CASE WHEN p_action = g_action_RESERVE
6853 	THEN BACKING_REQ.encumbered_amount
6854 	ELSE BACKING_REQ.amt_ordered --bug#5478754
6855     END)
6856 , SUM(BACKING_REQ.final_amt)
6857 BULK COLLECT INTO
6858   l_req_dist_id_tbl
6859 , l_max_total_tbl
6860 , l_req_dist_gtt_total_tbl
6861 FROM PO_ENCUMBRANCE_GT BACKING_REQ
6862 WHERE BACKING_REQ.origin_sequence_num IS NOT NULL
6863 AND BACKING_REQ.distribution_type = g_dist_type_REQUISITION
6864 AND BACKING_REQ.prevent_encumbrance_flag = 'N'
6865 GROUP BY distribution_id
6866 ;
6867 
6868 IF g_debug_stmt THEN
6869    PO_DEBUG.debug_var(l_log_head,l_progress,'l_req_dist_id_tbl',l_req_dist_id_tbl);
6870    PO_DEBUG.debug_var(l_log_head,l_progress,'l_max_total_tbl',l_max_total_tbl);
6871    PO_DEBUG.debug_var(l_log_head,l_progress,'l_req_dist_gtt_total_tbl',l_req_dist_gtt_total_tbl);
6872 END IF;
6873 
6874 l_progress := '020';
6875 
6876 -- Loop through each distinct Req dist.
6877 -- For each distinct dist where the current GTT total > max total
6878 --   Loop through the dists and adjust downward the remaining req distributions
6879 -- For each distinct dist where the current GTT total < max total
6880 --   If the action is Reserve/Check Funds, set the remaining balance on the
6881 --   last distribution.
6882 --   If the action is Unreserve/Reject, then it is fine for the GTT total to
6883 --   be less than the max total (we are just not putting all possible funds
6884 --   back on the Req)
6885 FOR i IN 1 .. l_req_dist_id_tbl.COUNT LOOP
6886 
6887   IF (l_req_dist_gtt_total_tbl(i) > l_max_total_tbl(i)
6888       OR (l_req_dist_gtt_total_tbl(i) < l_max_total_tbl(i)
6889           AND p_action = g_action_RESERVE) )
6890   THEN
6891 
6892     -- Fix the amounts for the current Req dist as necessary
6893     correct_backing_req_amounts(
6894       p_req_dist_id => l_req_dist_id_tbl(i)
6895     , p_max_total_amount => l_max_total_tbl(i)
6896     , p_current_total_amount => l_req_dist_gtt_total_tbl(i)
6897     );
6898 
6899   END IF;
6900 
6901 END LOOP;
6902 
6903 
6904 l_progress := '030';
6905 IF g_debug_stmt THEN
6906    PO_DEBUG.debug_end(l_log_head);
6907 END IF;
6908 
6909 EXCEPTION
6910    WHEN FND_API.G_EXC_ERROR THEN
6911       RAISE;
6912 
6913    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
6914       RAISE;
6915 
6916    WHEN OTHERS THEN
6917       --add message to the stack and log a debug msg if necessary
6918       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
6919       fnd_msg_pub.add;
6920       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6921 
6922 END set_complex_work_req_amounts;
6923 
6924 
6925 -------------------------------------------------------------------------------
6926 --Start of Comments
6927 --Name: correct_backing_req_amounts
6928 --Pre-reqs:
6929 --   PO_ENCUMBRANCE_GT is populated correctly with all information about all
6930 --   the main doc and backing Req distributions
6931 --Modifies:
6932 --   PO_ENCUMBRANCE_GT
6933 --Locks:
6934 --  n/a
6935 --Function:
6936 --  This procedure adjusts the final_amt column of backing Req rows in
6937 --  PO_ENCUMBRANCE_GT for the Complex Work case.
6938 --  It prohibits the sum of the amounts against the backing Requisition
6939 --  from exceeding the limits of the Requisition's encumbrance, if funds
6940 --  are being returned to the Requisition.  If funds are being liquidated
6941 --  from the Requisition, it ensures that no hanging balances are left on
6942 --  the Requisition
6943 --Parameters:
6944 --IN:
6945 --p_current_pa_dist_id
6946 --  The po_distribution_id of the BPA we are currently checking
6947 --p_start_row
6948 --  Index that indicates where the current BPA dists start in each
6949 --  of the 3 pl/sql table parameters
6950 --p_start_row
6951 --  Index that indicates where the current BPA dists end in each
6952 --  of the 3 pl/sql table parameters
6953 --p_running_total
6954 --  The overall sum of all CRs and DRs against the current PA
6955 --p_amt_to_enc_func
6956 --  The amount to encumber for the current PA, in functional currency
6957 --p_unencumbered_amt
6958 --  The unencumbered amount for the current PA, in functional currency
6959 --p_pa_sequence_num_tbl
6960 --  A colletion of sequence_nums corresponding to the sequence_nums in
6961 --  the PO_ENCUMBRANCE_GT of each backing PA row
6962 --p_pa_multiplier_tbl
6963 --  A collection where each element represents whether the corresponding
6964 --  element of the amount tbl is a DR or CR
6965 --IN OUT:
6966 --x_pa_amount_tbl
6967 --  A collection where each element represent the final_amt calculated
6968 --  in the PO_ENCUMBRANCE_GT table, for a given backing PA entry
6969 --Testing:
6970 --
6971 --End of Comments
6972 -------------------------------------------------------------------------------
6973 PROCEDURE correct_backing_req_amounts(
6974   p_req_dist_id          IN NUMBER
6975 , p_max_total_amount     IN NUMBER
6976 , p_current_total_amount IN NUMBER
6977 )
6978 IS
6979 
6980   l_proc_name CONSTANT VARCHAR2(30) := 'CORRECT_BACKING_REQ_AMOUNTS';
6981   l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_proc_name;
6982   l_progress  VARCHAR2(3) := '000';
6983   l_sequence_num_tbl	po_tbl_number;
6984   l_gtt_amount_tbl	po_tbl_number;
6985   l_start_row     	NUMBER := 0;
6986   l_end_row       	NUMBER := 0;
6987   l_amount_available	NUMBER;
6988   l_current_amount	NUMBER;
6989 
6990 BEGIN
6991 
6992 IF g_debug_stmt THEN
6993    PO_DEBUG.debug_begin(l_log_head);
6994    PO_DEBUG.debug_var(l_log_head,l_progress,'p_req_dist_id',p_req_dist_id);
6995    PO_DEBUG.debug_var(l_log_head,l_progress,'p_max_total_amount',p_max_total_amount);
6996    PO_DEBUG.debug_var(l_log_head,l_progress,'p_current_total_amount',p_current_total_amount);
6997 END IF;
6998 
6999 l_progress := '010';
7000 
7001 SELECT
7002   sequence_num
7003 , final_amt
7004 BULK COLLECT INTO
7005   l_sequence_num_tbl
7006 , l_gtt_amount_tbl
7007 FROM PO_ENCUMBRANCE_GT BACKING_REQ
7008 WHERE BACKING_REQ.origin_sequence_num IS NOT NULL
7009 AND BACKING_REQ.distribution_type = g_dist_type_REQUISITION
7010 AND BACKING_REQ.prevent_encumbrance_flag = 'N'
7011 AND BACKING_REQ.distribution_id = p_req_dist_id
7012 ORDER BY distribution_num ASC
7013 ;
7014 
7015 l_progress := '010';
7016 
7017 l_start_row := l_gtt_amount_tbl.FIRST;
7018 l_end_row := l_gtt_amount_tbl.LAST;
7019 
7020 IF g_debug_stmt THEN
7021    PO_DEBUG.debug_var(l_log_head,l_progress,'l_start_row',l_start_row);
7022    PO_DEBUG.debug_var(l_log_head,l_progress,'l_end_row',l_end_row);
7023    PO_DEBUG.debug_var(l_log_head,l_progress,'l_gtt_amount_tbl',l_gtt_amount_tbl);
7024 END IF;
7025 
7026 IF (p_max_total_amount > p_current_total_amount) THEN
7027   -- If p_max_total_amount is greater than p_current_total_amount, then set
7028   -- the balance on the last distribution.
7029   l_progress := '020';
7030 
7031   l_gtt_amount_tbl(l_end_row) :=
7032     l_gtt_amount_tbl(l_end_row) + (p_max_total_amount - p_current_total_amount);
7033 ELSIF (p_max_total_amount < p_current_total_amount) THEN
7034   -- If p_max_total_amount is less than p_current_total_amount, loop through
7035   -- the distributions and readjust the last few downward as needed.
7036   l_progress := '030';
7037 
7038   l_amount_available := p_max_total_amount;
7039   IF g_debug_stmt THEN
7040      PO_DEBUG.debug_var(l_log_head,l_progress,'l_amount_available ',l_amount_available );
7041      PO_DEBUG.debug_var(l_log_head,l_progress,'p_max_total_amount',p_max_total_amount);
7042   END IF;
7043 
7044   FOR i in l_start_row..l_end_row LOOP
7045 
7046     l_current_amount := l_gtt_amount_tbl(i);
7047 
7048     IF g_debug_stmt THEN
7049        PO_DEBUG.debug_var(l_log_head,l_progress,'l_current_amount  ',l_current_amount  );
7050     END IF;
7051     --<bug#5478754 START>
7052     --Modified the condition (<= l_amount_available) as
7053     --(< l_amount_available). This is to ensure that if the remaining
7054     --quantity is equal to the the current distributions quantity then
7055     --the l_amount_available is set to 0.
7056     IF (l_current_amount < l_amount_available) THEN
7057       l_amount_available := l_amount_available - l_current_amount;
7058     ELSE
7059       l_gtt_amount_tbl(i) := l_amount_available;
7060       l_amount_available := 0;
7061     END IF;
7062     --<bug#5478754 END>
7063   END LOOP;
7064 
7065 END IF;
7066 
7067 l_progress := '040';
7068 
7069 --Update the GTT with the adjusted amounts
7070 FORALL i IN l_start_row..l_end_row
7071  UPDATE PO_ENCUMBRANCE_GT BACKING_REQ
7072  SET BACKING_REQ.final_amt = l_gtt_amount_tbl(i)
7073  WHERE BACKING_REQ.sequence_num = l_sequence_num_tbl(i)
7074  ;
7075 
7076 l_progress := '050';
7077 
7078 IF g_debug_stmt THEN
7079    PO_DEBUG.debug_end(l_log_head);
7080 END IF;
7081 
7082 EXCEPTION
7083 WHEN OTHERS THEN
7084    --add message to the stack and log a debug msg if necessary
7085    po_message_s.sql_error(g_pkg_name, l_proc_name, l_progress, SQLCODE, SQLERRM);
7086    fnd_msg_pub.add;
7087    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7088 END correct_backing_req_amounts;
7089 --<Complex Work R12 END>
7090 
7091 
7092 -------------------------------------------------------------------------------
7093 --Start of Comments
7094 --Name: get_gl_references
7095 --Pre-reqs:
7096 --   PO_ENCUMBRANCE_GT has been populated with the information for
7097 --   each of the distributions that will have an entry in GL_BC_PACKETS.
7098 --Modifies:
7099 --   PO_ENCUMBRANCE_GT
7100 --Locks:
7101 --   n/a
7102 --Function:
7103 --   This procedure updates the references and other non-complex columns
7104 --   in PO_ENCUMBRANCE_GT that map to columns of GL_BC_PACKETS.
7105 --Parameters:
7106 --IN:
7107 --p_action
7108 --   Specifies the action that is being taken on the main doc.
7109 --p_cbc_flag
7110 --  This parameter is only set to Y if the action is one of the CBC Year-End
7111 --  processes.  If this is Y, p_action is either Reserve or Unreserve
7112 --p_req_encumb_type_id
7113 --   The identifier for the requisition encumbrance type, defined
7114 --   in financials_system_parameters
7115 --p_po_encumb_type_id
7116 --   The identifier for the po encumbrance type, defined in
7117 --   financials_system_parameters
7118 --p_invoice_id
7119 --    For transactions that were caused by an invoice action,
7120 --    this is the id of the invoice that started it all (provided by AP).
7121 --Testing:
7122 --
7123 --End of Comments
7124 -------------------------------------------------------------------------------
7125 PROCEDURE get_gl_references (
7126    p_action              IN VARCHAR2
7127 ,  p_cbc_flag            IN VARCHAR2
7128 ,  p_req_encumb_type_id  IN NUMBER
7129 ,  p_po_encumb_type_id   IN NUMBER
7130 ,  p_invoice_id          IN NUMBER
7131 )
7132 IS
7133 
7134 l_api_name CONSTANT VARCHAR2(30) := 'GET_GL_REFERENCES';
7135 l_log_head CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
7136 l_progress VARCHAR2(3) := '000';
7137 
7138 l_cbc_action           VARCHAR2(30) := NULL;
7139 l_cbc_line_description PO_LOOKUP_CODES.description%TYPE := NULL;
7140 
7141 l_source_doc_reference  PO_ENCUMBRANCE_GT.reference10%TYPE;
7142 
7143 /* Start Bug 3292870 */
7144 
7145 TYPE g_rowid_char_tbl_type  IS TABLE OF VARCHAR2(18);
7146 l_rowid_char_tbl     g_rowid_char_tbl_type;
7147 
7148 /* End Bug 3292870 */
7149 
7150 BEGIN
7151 
7152 IF g_debug_stmt THEN
7153    PO_DEBUG.debug_begin(l_log_head);
7154    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action',p_action);
7155    PO_DEBUG.debug_var(l_log_head,l_progress,'p_cbc_flag',p_cbc_flag);
7156    PO_DEBUG.debug_var(l_log_head,l_progress,'p_req_encumb_type_id',p_req_encumb_type_id);
7157    PO_DEBUG.debug_var(l_log_head,l_progress,'p_po_encumb_type_id',p_po_encumb_type_id);
7158    PO_DEBUG.debug_var(l_log_head,l_progress,'p_invoice_id',p_invoice_id);
7159 END IF;
7160 
7161 l_progress := '010';
7162 
7163 
7164 /* Start Bug 3292870: Split update of reference5 field off of query to make
7165  * it compatible with an 8i db.
7166  */
7167 
7168 
7169 UPDATE PO_ENCUMBRANCE_GT ALL_DISTS
7170 SET
7171    ALL_DISTS.je_category_name =
7172       DECODE( ALL_DISTS.distribution_type
7173               ,  g_dist_type_REQUISITION,  g_je_category_Requisitions
7174               ,  g_je_category_Purchases
7175             )
7176 
7177 ,  ALL_DISTS.je_line_description =
7178       DECODE( ALL_DISTS.distribution_type
7179               , g_dist_type_AGREEMENT, ALL_DISTS.comments
7180               , ALL_DISTS.item_description
7181             )
7182 
7183 ,  ALL_DISTS.encumbrance_type_id =
7184      to_char( DECODE( ALL_DISTS.distribution_type
7185                     ,  g_dist_type_REQUISITION,  p_req_encumb_type_id  -- Reqs
7186                     ,  g_dist_type_AGREEMENT,  p_req_encumb_type_id
7187                     ,  p_po_encumb_type_id
7188               )
7189      )
7190 
7191 ,  ALL_DISTS.code_combination_id = ALL_DISTS.budget_account_id
7192 
7193 ,  ALL_DISTS.reference1 =
7194       DECODE( ALL_DISTS.distribution_type
7195               ,	 g_dist_type_REQUISITION,  g_reference1_REQ
7196               ,	 g_dist_type_AGREEMENT,  g_reference1_PA
7197               ,  g_dist_type_SCHEDULED,  g_reference1_REL
7198               ,	 g_dist_type_BLANKET,  g_reference1_REL
7199               ,	 g_reference1_PO
7200             )
7201 
7202 -- bug 3404563: NULL out reference 2 and 3 if this is the
7203 -- IP unsaved GMS Req case (identified by non-NULL award_num)
7204 
7205 ,  ALL_DISTS.reference2 =
7206       DECODE( ALL_DISTS.award_num
7207               -- if null, then its a saved doc so use the id
7208               , NULL, to_char(ALL_DISTS.header_id)
7209               -- else means unsaved doc, so NULL out ref2
7210               ,       NULL
7211       )
7212 
7213 ,  ALL_DISTS.reference3 =
7214       DECODE( ALL_DISTS.award_num
7215               -- if null, then its a saved doc so use the id
7216               , NULL, to_char(ALL_DISTS.distribution_id)
7217               -- else means unsaved doc, so NULL out ref3
7218               ,       NULL
7219       )
7220 
7221 ,  ALL_DISTS.reference4 = ALL_DISTS.segment1
7222 
7223 ,  ALL_DISTS.reference15 = to_char(ALL_DISTS.sequence_num)
7224 WHERE ALL_DISTS.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7225 ;
7226 
7227 
7228 l_progress := '050';
7229 
7230 UPDATE PO_ENCUMBRANCE_GT ALL_DISTS
7231 SET   ALL_DISTS.reference5 = ALL_DISTS.reference_num
7232 WHERE ALL_DISTS.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7233   and ALL_DISTS.distribution_type = g_dist_type_REQUISITION
7234 ;
7235 
7236 l_progress := '060';
7237 
7238 UPDATE PO_ENCUMBRANCE_GT ALL_DISTS
7239 SET   ALL_DISTS.reference5 =
7240                            ( SELECT PPO_DISTS.segment1
7241                              FROM PO_ENCUMBRANCE_GT PPO_DISTS
7242                              WHERE PPO_DISTS.origin_sequence_num
7243                                        = ALL_DISTS.sequence_num
7244                               AND PPO_DISTS.distribution_id
7245                                        = ALL_DISTS.source_distribution_id
7246                            )
7247 WHERE ALL_DISTS.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7248   and ALL_DISTS.distribution_type = g_dist_type_SCHEDULED
7249 ;
7250 
7251 l_progress := '070';
7252 
7253 UPDATE PO_ENCUMBRANCE_GT ALL_DISTS
7254 SET   ALL_DISTS.reference5 =
7255                       ( SELECT PA_DISTS.segment1
7256                         FROM PO_ENCUMBRANCE_GT PA_DISTS
7257                         WHERE PA_DISTS.origin_sequence_num =
7258                                      ALL_DISTS.sequence_num
7259                           AND PA_DISTS.distribution_id =
7260                                      ALL_DISTS.agreement_dist_id
7261                       )
7262 WHERE ALL_DISTS.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7263   and ALL_DISTS.distribution_type NOT IN (g_dist_type_SCHEDULED, g_dist_type_REQUISITION)
7264 RETURNING ROWIDTOCHAR(rowid) BULK COLLECT into l_rowid_char_tbl
7265 ;
7266 
7267 l_progress := '080';
7268 
7269 FORALL i IN 1..l_rowid_char_tbl.COUNT
7270 UPDATE PO_ENCUMBRANCE_GT ALL_DISTS
7271 SET   ALL_DISTS.reference5 =
7272                      ( SELECT REQ_DISTS.segment1
7273                        FROM PO_ENCUMBRANCE_GT REQ_DISTS
7274                        WHERE REQ_DISTS.origin_sequence_num =
7275                                      ALL_DISTS.sequence_num
7276                          AND REQ_DISTS.distribution_type =
7277                                      g_dist_type_REQUISITION
7278                       )
7279 WHERE ALL_DISTS.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7280   and rowid = CHARTOROWID(l_rowid_char_tbl(i))
7281   and ALL_DISTS.reference5 IS NULL
7282 ;
7283 
7284 /* End Bug 3292870 */
7285 
7286 
7287 
7288 l_progress := '100';
7289 
7290 -- Update the source doc reference, JFMIP requirement.
7291 -- Backing Reqs/PPOs/BPAs/GAs point to the {PO|Rel}/SR/BR/StdPO's po_header_id.
7292 -- During an invoice activity, the main doc (StdPO/BR/SR)
7293 -- points to the invoice_id.
7294 
7295 UPDATE PO_ENCUMBRANCE_GT BACKING
7296 SET
7297    BACKING.reference6 = g_reference6_SRCDOC
7298 ,  BACKING.reference10 =
7299       (
7300          SELECT TO_CHAR(MAIN.header_id)
7301          FROM PO_ENCUMBRANCE_GT MAIN
7302          WHERE MAIN.sequence_num = BACKING.origin_sequence_num
7303       )
7304 WHERE BACKING.origin_sequence_num IS NOT NULL  --backing doc
7305 AND BACKING.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7306 ;
7307 
7308 l_progress := '110';
7309 
7310 IF (p_invoice_id IS NOT NULL) THEN
7311 
7312    l_progress := '120';
7313 
7314    -- If an invoice is causing this transaction,
7315    -- it needs to be referenced by the main doc rows.
7316 
7317    l_source_doc_reference := TO_CHAR(p_invoice_id);
7318 
7319    UPDATE PO_ENCUMBRANCE_GT MAIN
7320    SET
7321       MAIN.reference6 = g_reference6_SRCDOC
7322    ,  MAIN.reference10 = l_source_doc_reference
7323    WHERE MAIN.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7324    AND   MAIN.origin_sequence_num IS NULL
7325    ;
7326 
7327    l_progress := '130';
7328 
7329 ELSE
7330 
7331    l_progress := '140';
7332 
7333    -- Integration with Grants (GMS)
7334    --
7335    -- In FPI, unsaved requisitions were allowed to undergo a funds check.
7336    -- If Grants information is tied to one of these unsaved reqs,
7337    -- this information must be passed through GL_BC_PACKETS, as
7338    -- it is not saved in the PO transaction tables.
7339    -- One of the pieces of information that was passed to Grants
7340    -- was the award number.  In PO tables, only the award_id is stored.
7341    -- Therefore, we will distinguish this unsaved case that requires
7342    -- Grants data population by the presence of award_num in the
7343    -- encumbrance table.
7344    --
7345    -- Grants data will not be populated for backing docs
7346    -- or during an invoice transaction.
7347    -- In these cases, the Grants data must have been saved in the
7348    -- PO transaction tables anyway, so Grants can still figure it out.
7349 
7350    UPDATE PO_ENCUMBRANCE_GT MAIN
7351    SET
7352       MAIN.reference6 = g_reference6_GMSIP
7353 
7354    ,  MAIN.reference7 = to_char(project_id)
7355 
7356    ,  MAIN.reference8 = to_char(task_id)
7357 
7358    ,  MAIN.reference9 = award_num
7359 
7360    ,  MAIN.reference10 = expenditure_type
7361 
7362    ,  MAIN.reference11 = to_char(expenditure_organization_id)
7363 
7364    ,  MAIN.reference12 = expenditure_item_date /* Bug 3081539 */
7365 
7366    ,  MAIN.reference13 = to_char(vendor_id)
7367 
7368    WHERE MAIN.award_num IS NOT NULL  --identifies the unsaved Req case
7369    AND   MAIN.send_to_gl_flag = 'Y'  --bug 3568512: use new column
7370    AND   MAIN.origin_sequence_num IS NULL
7371    ;
7372 
7373    l_progress := '150';
7374 
7375 END IF;
7376 
7377 
7378 --Bug 3404491: populate reference14 with 'old' distribution
7379 --information for Req Split or Cancel w/ Recreate Req
7380 --This is needed by Projects/GMS, which read POETA info
7381 --from the committed (old) dist.  This works b/c currently
7382 --the user can not change POETA info during Cancel or Req split,
7383 --so the info from old dist is same as for new dist
7384 
7385 IF p_action = g_action_CANCEL THEN
7386 
7387    l_progress := '160';
7388 
7389    UPDATE PO_ENCUMBRANCE_GT BACKING_REQ
7390    SET reference14 =
7391       (SELECT REQ_TABLE.source_req_distribution_id
7392        FROM PO_REQ_DISTRIBUTIONS_ALL REQ_TABLE
7393        WHERE BACKING_REQ.distribution_id = REQ_TABLE.distribution_id
7394       )
7395    WHERE BACKING_REQ.origin_sequence_num IS NOT NULL
7396    AND   BACKING_REQ.distribution_type = g_dist_type_REQUISITION
7397    AND   BACKING_REQ.project_id IS NOT NULL
7398    ;
7399 
7400 ELSIF p_action = g_action_ADJUST THEN
7401 
7402    l_progress := '180';
7403 
7404    UPDATE PO_ENCUMBRANCE_GT MAIN_REQ
7405    SET reference14 =
7406       (SELECT PARENT_DIST.distribution_id
7407        FROM PO_REQ_DISTRIBUTIONS_ALL PARENT_DIST
7408        ,    PO_REQUISITION_LINES_ALL PARENT_LINE
7409        ,    PO_REQUISITION_LINES_ALL CHILD_LINE
7410        WHERE MAIN_REQ.line_id = CHILD_LINE.requisition_line_id
7411        AND   PARENT_LINE.requisition_line_id = CHILD_LINE.parent_req_line_id
7412        AND   PARENT_DIST.requisition_line_id = PARENT_LINE.requisition_line_id
7413       )
7414    WHERE MAIN_REQ.origin_sequence_num IS NULL
7415    AND   MAIN_REQ.distribution_type = g_dist_type_REQUISITION
7416    AND   MAIN_REQ.adjustment_status = g_adj_status_NEW
7417    AND   MAIN_REQ.project_id IS NOT NULL
7418    ;
7419 
7420 END IF;
7421 
7422 
7423 l_progress := '200';
7424 
7425 IF p_cbc_flag = 'Y' THEN
7426 
7427    l_progress := '210';
7428 
7429    IF g_debug_stmt THEN
7430       PO_DEBUG.debug_stmt(l_log_head,l_progress,'modifying packet for CBC');
7431    END IF;
7432 
7433    IF p_action = g_action_RESERVE THEN
7434       l_cbc_action := g_action_CBC_RESERVE;
7435    ELSIF p_action = g_action_UNRESERVE THEN
7436       l_cbc_action := g_action_CBC_UNRESERVE;
7437    END IF;
7438 
7439    l_progress := '220';
7440 
7441    SELECT POLC.description
7442    INTO   l_cbc_line_description
7443    FROM   PO_LOOKUP_CODES POLC
7444    WHERE  POLC.lookup_type = 'CONTROL ACTIONS'
7445    AND    POLC.lookup_code = l_cbc_action
7446    ;
7447 
7448    l_progress := '230';
7449 
7450    IF g_debug_stmt THEN
7451       PO_DEBUG.debug_var(l_log_head,l_progress,'l_cbc_action',l_cbc_action);
7452       PO_DEBUG.debug_var(l_log_head,l_progress,'l_cbc_line_description',l_cbc_line_description);
7453    END IF;
7454 
7455    UPDATE PO_ENCUMBRANCE_GT ALL_DISTS
7456    SET
7457       ALL_DISTS.je_line_description =
7458          SUBSTRB(ALL_DISTS.je_line_description,1,100)
7459          || '-'
7460          || SUBSTRB(l_cbc_line_description,1,139)
7461    WHERE ALL_DISTS.send_to_gl_flag = 'Y'
7462    ;
7463 
7464    l_progress := '240';
7465 
7466 END IF;
7467 
7468 l_progress := '900';
7469 
7470 IF g_debug_stmt THEN
7471    PO_DEBUG.debug_end(l_log_head);
7472 END IF;
7473 
7474 EXCEPTION
7475    WHEN FND_API.G_EXC_ERROR THEN
7476       RAISE;
7477 
7478    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
7479       RAISE;
7480 
7481    WHEN OTHERS THEN
7482       --add message to the stack and log a debug msg if necessary
7483       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
7484       fnd_msg_pub.add;
7485       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7486 
7487 END get_gl_references;
7488 
7489 
7490 
7491 
7492 ------------------------------------------------------------------------------
7493 --Start of Comments
7494 --Name: check_enc_action_possible
7495 --Pre-reqs:
7496 --  This check is meaningless if the appropriate encumbrance is not turned on.
7497 --Modifies:
7498 --  PO_ENCUMBRANCE_GT
7499 --Locks:
7500 --  None.
7501 --Function:
7502 --  This procedure determines whether there are any distributions below
7503 --  the doc level on which the given encumbrance action would have any effect.
7504 --Parameters:
7505 --IN:
7506 --p_action
7507 --  The encumbrance action being performed.
7508 --p_doc_type
7509 --  Differentiates between the doc being a REQ, PA, PO, or RELEASE,
7510 --  which is used to identify the tables to look at (PO vs. Req)
7511 --  and the join conditions
7512 --p_doc_level
7513 --  Specifies the level of the document that is being checked:
7514 --  HEADER, LINE, SHIPMENT, DISTRIBUTION
7515 --p_doc_level_id
7516 --  The id corresponding to the doc level type:
7517 --  header_id/release_id, line_id, line_location_id, distribution_id
7518 --OUT:
7519 --x_action_possible_flag
7520 --  Indicates whether the action is possible on this doc level
7521 --  'Y' means it is possible, 'N' means it isn't.
7522 --Testing:
7523 --
7524 --End of Comments
7525 -------------------------------------------------------------------------------
7526 PROCEDURE check_enc_action_possible(
7527    p_action                         IN          VARCHAR2
7528 ,  p_doc_type                       IN          VARCHAR2
7529 ,  p_doc_subtype                    IN          VARCHAR2
7530 ,  p_doc_level                      IN          VARCHAR2
7531 ,  p_doc_level_id                   IN          NUMBER
7532 ,  x_action_possible_flag           OUT NOCOPY  VARCHAR2
7533 )
7534 IS
7535 
7536 l_proc_name              CONSTANT varchar2(30) := 'CHECK_ENC_ACTION_POSSIBLE';
7537 l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_proc_name;
7538 l_progress              VARCHAR2(3) := '000';
7539 
7540 l_dist_count   NUMBER;
7541 
7542 BEGIN
7543 
7544 SAVEPOINT CHECK_ENC_ACTION_POSSIBLE;
7545 
7546 IF g_debug_stmt THEN
7547    PO_DEBUG.debug_begin(l_log_head);
7548    PO_DEBUG.debug_var(l_log_head,l_progress,'p_action',p_action);
7549    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_type',p_doc_type);
7550    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_subtype',p_doc_subtype);
7551    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level',p_doc_level);
7552    PO_DEBUG.debug_var(l_log_head,l_progress,'p_doc_level_id',p_doc_level_id);
7553 END IF;
7554 
7555 l_progress := '010';
7556 
7557 get_all_distributions(
7558    p_action => p_action
7559 ,  p_check_only_flag => g_parameter_YES
7560 ,  p_doc_type => p_doc_type
7561 ,  p_doc_subtype => p_doc_subtype
7562 ,  p_doc_level => p_doc_level
7563 ,  p_doc_level_id => p_doc_level_id
7564 ,  p_use_enc_gt_flag => g_parameter_NO
7565 ,  p_get_backing_docs_flag => g_parameter_NO
7566 ,  p_ap_budget_account_id => NULL
7567 ,  p_possibility_check_flag => g_parameter_YES
7568 ,  p_cbc_flag => g_parameter_NO
7569 ,  x_count => l_dist_count
7570 );
7571 
7572 l_progress := '020';
7573 
7574 IF (l_dist_count > 0) THEN
7575    x_action_possible_flag := g_parameter_YES;
7576 ELSE
7577    x_action_possible_flag := g_parameter_NO;
7578 END IF;
7579 
7580 l_progress := '900';
7581 
7582 IF g_debug_stmt THEN
7583    PO_DEBUG.debug_var(l_log_head,l_progress,'x_action_possible_flag',x_action_possible_flag);
7584    PO_DEBUG.debug_end(l_log_head);
7585 END IF;
7586 
7587 EXCEPTION
7588 
7589 WHEN OTHERS THEN
7590 
7591    IF g_debug_unexp THEN
7592       PO_DEBUG.debug_exc(l_log_head,l_progress);
7593    END IF;
7594 
7595    RAISE;
7596 
7597 END check_enc_action_possible;
7598 
7599 
7600 
7601 
7602 -------------------------------------------------------------------------------
7603 --Start of Comments
7604 --Name: delete_encumbrance_gt
7605 --Pre-reqs:
7606 --  None.
7607 --Modifies:
7608 --  PO_ENCUMBRANCE_GT
7609 --Locks:
7610 --  None.
7611 --Function:
7612 --  Deletes all of the existing data from PO_ENCUMBRANCE_GT.
7613 --Parameters:
7614 --  None.
7615 --Testing:
7616 --
7617 --End of Comments
7618 -------------------------------------------------------------------------------
7619 PROCEDURE delete_encumbrance_gt
7620 IS
7621 
7622 l_proc_name CONSTANT VARCHAR2(30) := 'DELETE_ENCUMBRANCE_GT';
7623 l_log_head  CONSTANT VARCHAR2(100) := g_log_head||l_proc_name;
7624 l_progress  VARCHAR2(3) := '000';
7625 
7626 BEGIN
7627 
7628 IF g_debug_stmt THEN
7629    PO_DEBUG.debug_begin(l_log_head);
7630 END IF;
7631 
7632 l_progress := '010';
7633 
7634 DELETE FROM PO_ENCUMBRANCE_GT ;
7635 
7636 l_progress := '900';
7637 
7638 IF g_debug_stmt THEN
7639    PO_DEBUG.debug_end(l_log_head);
7640 END IF;
7641 
7642 EXCEPTION
7643 WHEN OTHERS THEN
7644    po_message_s.sql_error(g_pkg_name,l_proc_name,l_progress,SQLCODE,SQLERRM);
7645    fnd_msg_pub.add;
7646    RAISE;
7647 
7648 END delete_encumbrance_gt;
7649 
7650 
7651 -- <SLA R12 Start>
7652   -------------------------------------------------------------------------------
7653   --Start of Comments
7654   --Name: update_amounts
7655   --Pre-reqs:
7656   --  None.
7657   --Modifies:
7658   --  None.
7659   --Locks:
7660   --  None.
7661   --Function:
7662   -- This procedure will be used to update proper entered and accounted amount
7663   -- values in PO_ENCUMBRANCE_GT.
7664   --Parameters:
7665   --IN:
7666   --  p_action : specifies the action
7667   --  p_currency_code_func: currency code of the functional currency.
7668   --IN OUT:
7669   --  None.
7670   --OUT:
7671   --  None.
7672   --Notes:
7673   -- The algorithm of the procedure is as follows :
7674   -- update proper entered and accounted amount values in PO_ENCUMBRANCE_GT.
7675   --Testing:
7676   --
7677   --End of Comments
7678   -------------------------------------------------------------------------------
7679   PROCEDURE update_amounts
7680   (
7681     p_action        IN   VARCHAR2,
7682     p_currency_code_func IN VARCHAR2
7683   )
7684   IS
7685     l_api_name     CONSTANT      varchar2(40) := 'UPDATE_AMOUNTS';
7686     l_progress                   varchar2(3);
7687 
7688     l_return_status              VARCHAR2(1);
7689     l_sequence_num_tbl           PO_TBL_NUMBER;
7690     l_amount_to_round_tbl        PO_TBL_NUMBER;
7691     l_exchange_rate_tbl          PO_TBL_NUMBER;
7692     l_cur_precision_from_tbl  PO_TBL_NUMBER;
7693     l_min_acct_unit_from_tbl  PO_TBL_NUMBER;
7694     l_cur_precision_to_tbl     PO_TBL_NUMBER;
7695     l_min_acct_unit_to_tbl     PO_TBL_NUMBER;
7696     l_round_only_flag_tbl        PO_TBL_VARCHAR1;
7697     l_amount_result_tbl          PO_TBL_NUMBER;
7698     l_origin_sequence_num_tbl    PO_TBL_NUMBER;
7699     l_min_acct_unit_func  FND_CURRENCIES.minimum_accountable_unit%TYPE;
7700     l_cur_precision_func  FND_CURRENCIES.precision%TYPE;
7701     l_log_head  CONSTANT VARCHAR2(100) := g_log_head || l_api_name;
7702   BEGIN
7703 
7704     l_progress := '000';
7705 
7706     If g_fnd_debug = 'Y' Then
7707       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
7708         FND_LOG.string( FND_LOG.LEVEL_STATEMENT,
7709                         g_log_head || l_api_name || '.' || l_progress,
7710                         'Start of procedure'
7711                       );
7712       END IF;
7713     End If;
7714 
7715     IF p_action IN (g_action_RESERVE, g_action_UNDO_FINAL_CLOSE,
7716                     g_action_CR_MEMO_CANCEL, g_action_UNRESERVE,
7717                     g_action_FINAL_CLOSE, g_action_RETURN,
7718                     g_action_REJECT, g_action_INVOICE_CANCEL,
7719                     g_action_ADJUST
7720                    )
7721     THEN
7722       -- if action is RESERVE/UNRESERVE/UNDO_FINAL_CLOSE/CR_MEMO_CANCEL/FINAL_CLOSE/RETURN/REJECT/INVOICE_CANCEL/ADJUST
7723       l_progress := '010';
7724 
7725       If g_fnd_debug = 'Y' Then
7726         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
7727           FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
7728                          g_log_head || l_api_name || '.' || l_progress,
7729                          'Update for '|| p_action
7730                         );
7731         END IF;
7732       End If;
7733       --<bug#5162302 START>
7734       --The objective of this bug is to ensure that the entered_amount is
7735       --is reflected as it was entered in the transaction.i.e in the foreign
7736       --currency and this is only for non-req documents. Reqs are always in
7737       --functional currency.
7738 
7739       --For BPA's the pre-round amount is not the correct thing to look at.
7740       --We need to look at the final amount because this reflects the actual
7741       --amount after all adjustments and calculations have been done to ensure
7742       --that we do not overrelive amount off the BPA. Since the entire amount
7743       --is in functional currency we would need to convert it back to the
7744       --foreign currency.
7745       --<bug#5478754>
7746       --For requisitions it is allright to have entered_amt=accounted_amt=final_amt.
7747       --This is because the requisitions are in functional currency all the time.
7748       UPDATE PO_ENCUMBRANCE_GT DISTS
7749         SET   DISTS.entered_amount = decode(DISTS.distribution_type,g_dist_type_AGREEMENT,
7750                                             DISTS.final_amt,g_dist_type_REQUISITION,DISTS.final_amt,
7751                                             DISTS.pre_round_amt)
7752               ,DISTS.accounted_amount = DISTS.final_amt
7753       WHERE DISTS.prevent_encumbrance_flag = 'N' ;
7754       --<bug#5162302 END>
7755     ELSIF p_action = g_action_CANCEL THEN
7756       -- if action is CANCEL
7757       l_progress := '030';
7758 
7759       If g_fnd_debug = 'Y' Then
7760         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
7761           FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
7762                          g_log_head || l_api_name || '.' || l_progress,
7763                          'Update for Cancel action'
7764                         );
7765         END IF;
7766       End If;
7767       --<bug#5162302 START>
7768       --For BPA's the pre-round amount is not the correct thing to look at.
7769       --We need to look at the final amount because this reflects the actual
7770       --amount after all adjustments and calculations have been done to ensure
7771       --that we do not overrelive amount off the BPA. Since the entire amount
7772       --is in functional currency we would need to convert it back to the
7773       --foreign currency.
7774       --<bug#5478754>
7775       --For requisitions it is allright to have entered_amt=accounted_amt=final_amt.
7776       --This is because the requisitions are in functional currency all the time.
7777       UPDATE PO_ENCUMBRANCE_GT DISTS
7778         SET  DISTS.entered_amount = -1 *decode(DISTS.distribution_type,g_dist_type_AGREEMENT,
7779                                                DISTS.final_amt,g_dist_type_REQUISITION,DISTS.final_amt,
7780                                                DISTS.pre_round_amt)
7781              ,DISTS.accounted_amount = -1 * DISTS.final_amt
7782       WHERE DISTS.prevent_encumbrance_flag = 'N';
7783       --<bug#5162302 END>
7784     ELSE
7785       l_progress := '050';
7786       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, '000', 'Invalid Action');
7787       fnd_msg_pub.add;
7788       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7789     END IF;  -- check on p_action
7790     l_progress:= '060';
7791     --<bug#5162302 START>
7792     -- Get functional currency setup
7793     IF g_debug_stmt THEN
7794         PO_DEBUG.debug_stmt(l_log_head,l_progress,'Before starting currency conversions on entered_amount_fields in po_encumbrance_gt');
7795         PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows,NULL,'PO');
7796     END IF;
7797 
7798     SELECT
7799        FND_CUR.minimum_accountable_unit
7800     ,  FND_CUR.precision
7801     INTO
7802        l_min_acct_unit_func
7803     ,  l_cur_precision_func
7804     FROM FND_CURRENCIES FND_CUR
7805     WHERE FND_CUR.currency_code = p_currency_code_func
7806     ;
7807     IF g_debug_stmt THEN
7808        PO_DEBUG.debug_stmt(l_log_head,l_progress,'After querying functional currency setup');
7809        PO_DEBUG.debug_var(l_log_head,l_progress,'l_min_acct_unit_func' , l_min_acct_unit_func);
7810        PO_DEBUG.debug_var(l_log_head,l_progress,'l_cur_precision_func' , l_cur_precision_func);
7811     END IF;
7812     l_progress:= '070';
7813     --For Agreement Distributions we need to convert back from the
7814     --Functional currency to the foreign currency and then apply rounding.
7815     --We need to assume the rate as 1/rate while converting back because
7816     --we cannot accurately determine the conversion from functional to foreign
7817     --currency. For all other distributions the currency would already be in
7818     --foreign currency except for requisition distributions. In such case we
7819     --can simply round and do no more than that. For all distributions that are
7820     --in functional currency the foreign currency fields would be null. We would
7821     --set these to the functional currency values for rounding precision.
7822     --<bug#5478754>
7823     --Requisitions are already looking at the final_amt which is rounded. We do not
7824     --have to round again.
7825     SELECT
7826        DISTS.sequence_num
7827     ,  DISTS.entered_amount
7828     ,  decode(DISTS.distribution_type,g_dist_type_AGREEMENT,1/nvl(DISTS.rate,1),1)
7829     ,  decode(DISTS.distribution_type,g_dist_type_AGREEMENT,
7830               l_cur_precision_func,DISTS.cur_precision_foreign)
7831     ,  decode(DISTS.distribution_type,g_dist_type_AGREEMENT,
7832               l_min_acct_unit_func,DISTS.min_acct_unit_foreign)
7833     ,  nvl(DISTS.cur_precision_foreign,l_cur_precision_func)
7834     ,  nvl(DISTS.min_acct_unit_foreign,l_min_acct_unit_func)
7835     ,  decode(DISTS.distribution_type,g_dist_type_AGREEMENT,'N','Y') --round only flag.
7836     ,  DISTS.origin_sequence_num
7837     BULK COLLECT INTO
7838        l_sequence_num_tbl
7839     ,  l_amount_to_round_tbl
7840     ,  l_exchange_rate_tbl
7841     ,  l_cur_precision_from_tbl
7842     ,  l_min_acct_unit_from_tbl
7843     ,  l_cur_precision_to_tbl
7844     ,  l_min_acct_unit_to_tbl
7845     ,  l_round_only_flag_tbl
7846     ,  l_origin_sequence_num_tbl
7847     FROM PO_ENCUMBRANCE_GT DISTS
7848     WHERE DISTS.prevent_encumbrance_flag = 'N'
7849     AND   DISTS.distribution_type <> g_dist_type_REQUISITION       --<bug#5478754>
7850     ORDER BY DISTS.sequence_num
7851     ;
7852 
7853     IF g_debug_stmt THEN
7854         PO_DEBUG.debug_stmt(l_log_head,l_progress,'After querying for distributions.');
7855         PO_DEBUG.debug_var(l_log_head,l_progress,'l_sequence_num_tbl',l_sequence_num_tbl);
7856         PO_DEBUG.debug_var(l_log_head,l_progress,'l_amount_to_round_tbl',l_amount_to_round_tbl);
7857         PO_DEBUG.debug_var(l_log_head,l_progress,'l_exchange_rate_tbl',l_exchange_rate_tbl);
7858         PO_DEBUG.debug_var(l_log_head,l_progress,'l_cur_precision_from_tbl',l_cur_precision_from_tbl);
7859         PO_DEBUG.debug_var(l_log_head,l_progress,'l_min_acct_unit_from_tbl',l_min_acct_unit_from_tbl);
7860         PO_DEBUG.debug_var(l_log_head,l_progress,'l_cur_precision_to_tbl',l_cur_precision_to_tbl);
7861         PO_DEBUG.debug_var(l_log_head,l_progress,'l_min_acct_unit_to_tbl',l_min_acct_unit_to_tbl);
7862         PO_DEBUG.debug_var(l_log_head,l_progress,'l_round_only_flag_tbl',l_round_only_flag_tbl);
7863         PO_DEBUG.debug_var(l_log_head,l_progress,'l_origin_sequence_num_tbl',l_origin_sequence_num_tbl);
7864     END IF;
7865     l_progress:= '080';
7866 
7867     PO_CORE_S2.round_and_convert_currency(
7868        x_return_status               => l_return_status
7869     ,  p_unique_id_tbl               => l_sequence_num_tbl
7870     ,  p_amount_in_tbl               => l_amount_to_round_tbl
7871     ,  p_exchange_rate_tbl           => l_exchange_rate_tbl
7872     ,  p_from_currency_precision_tbl => l_cur_precision_from_tbl
7873     ,  p_from_currency_mau_tbl       => l_min_acct_unit_from_tbl
7874     ,  p_to_currency_precision_tbl   => l_cur_precision_to_tbl
7875     ,  p_to_currency_mau_tbl         => l_min_acct_unit_to_tbl
7876     ,  p_round_only_flag_tbl         => l_round_only_flag_tbl
7877     ,  x_amount_out_tbl              => l_amount_result_tbl
7878     );
7879 
7880     IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
7881 
7882        PO_DEBUG.debug_stmt(l_log_head,l_progress,'After completing PO_CORE_S2.round_and_convert_currency on distributions');
7883        PO_DEBUG.debug_var(l_log_head,l_progress,'l_return_status',l_return_status);
7884        l_progress := '090';
7885        RAISE FND_API.g_EXC_UNEXPECTED_ERROR;
7886     END IF;
7887 
7888     IF g_debug_stmt THEN
7889         PO_DEBUG.debug_var(l_log_head,l_progress,'l_amount_result_tbl',l_amount_result_tbl);
7890     END IF;
7891 
7892     l_progress:='100';
7893     FORALL i IN 1 .. l_sequence_num_tbl.COUNT
7894        UPDATE PO_ENCUMBRANCE_GT DISTS
7895        SET DISTS.entered_amount= l_amount_result_tbl(i)
7896        WHERE DISTS.prevent_encumbrance_flag = 'N'
7897        AND DISTS.sequence_num = l_sequence_num_tbl(i)
7898        ;
7899     IF g_debug_stmt THEN
7900         PO_DEBUG.debug_stmt(l_log_head,l_progress,'After completing update on po_encumbrance_gt for distributions');
7901         PO_DEBUG.debug_var(l_log_head,l_progress,'sql%rowcount',sql%rowcount);
7902         PO_DEBUG.debug_table(l_log_head,l_progress,'PO_ENCUMBRANCE_GT',PO_DEBUG.g_all_rows,NULL,'PO');
7903     END IF;
7904     --<bug#5162302 END>
7905     l_progress := '110';
7906 
7907     If g_fnd_debug = 'Y' Then
7908       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
7909         FND_LOG.string(FND_LOG.LEVEL_STATEMENT,
7910                        g_log_head || l_api_name || '.' || l_progress,
7911                        'End of Procedure'
7912                     );
7913       END IF;
7914     End If;
7915 
7916   EXCEPTION
7917     WHEN FND_API.G_EXC_ERROR THEN
7918       RAISE;
7919 
7920     WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
7921       RAISE;
7922 
7923     WHEN OTHERS THEN
7924       --add message to the stack and log a debug msg if necessary
7925       po_message_s.sql_error(g_pkg_name, l_api_name, l_progress, SQLCODE, SQLERRM);
7926       fnd_msg_pub.add;
7927       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7928 
7929   END update_amounts;
7930 -- <SLA R12 End>
7931 
7932 
7933 END PO_ENCUMBRANCE_PREPROCESSING;