DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_ENCUMBRANCE_PREPROCESSING

Source


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