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