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;