[Home] [Help]
PACKAGE BODY: APPS.AP_APPROVAL_PKG
Source
1 PACKAGE BODY AP_APPROVAL_PKG AS
2 /* $Header: apaprvlb.pls 120.140.12010000.28 2009/01/23 10:48:19 ctetala ship $ */
3
4 G_PKG_NAME CONSTANT VARCHAR2(30) := 'AP_APPROVAL_PKG';
5 G_MSG_UERROR CONSTANT NUMBER := FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR;
6 G_MSG_ERROR CONSTANT NUMBER := FND_MSG_PUB.G_MSG_LVL_ERROR;
7 G_MSG_SUCCESS CONSTANT NUMBER := FND_MSG_PUB.G_MSG_LVL_SUCCESS;
8 G_MSG_HIGH CONSTANT NUMBER := FND_MSG_PUB.G_MSG_LVL_DEBUG_HIGH;
9 G_MSG_MEDIUM CONSTANT NUMBER := FND_MSG_PUB.G_MSG_LVL_DEBUG_MEDIUM;
10 G_MSG_LOW CONSTANT NUMBER := FND_MSG_PUB.G_MSG_LVL_DEBUG_LOW;
11 G_LINES_PER_FETCH CONSTANT NUMBER := 1000;
12
13 G_CURRENT_RUNTIME_LEVEL CONSTANT NUMBER := FND_LOG.G_CURRENT_RUNTIME_LEVEL;
14 G_LEVEL_UNEXPECTED CONSTANT NUMBER := FND_LOG.LEVEL_UNEXPECTED;
15 G_LEVEL_ERROR CONSTANT NUMBER := FND_LOG.LEVEL_ERROR;
16 G_LEVEL_EXCEPTION CONSTANT NUMBER := FND_LOG.LEVEL_EXCEPTION;
17 G_LEVEL_EVENT CONSTANT NUMBER := FND_LOG.LEVEL_EVENT;
18 G_LEVEL_PROCEDURE CONSTANT NUMBER := FND_LOG.LEVEL_PROCEDURE;
19 G_LEVEL_STATEMENT CONSTANT NUMBER := FND_LOG.LEVEL_STATEMENT;
20 G_MODULE_NAME CONSTANT VARCHAR2(100) := 'AP.PLSQL.AP_APPROVAL_PKG.';
21
22 /*===========================================================================
23 | Private Global Variable specification
24 *==========================================================================*/
25 g_org_id NUMBER(15); /* Bug 3700128. MOAC Project */
26
27 /*============================================================================
28 | Private (Non Public) Procedure Specifications
29 *===========================================================================*/
30 FUNCTION Inv_Needs_Approving(
31 p_invoice_id IN NUMBER,
32 p_run_option IN VARCHAR2,
33 p_calling_sequence IN VARCHAR2) RETURN BOOLEAN;
34
35 FUNCTION Get_Inv_Matched_Status(
36 p_invoice_id IN NUMBER,
37 p_calling_sequence IN VARCHAR2) RETURN BOOLEAN;
38
39 PROCEDURE Get_Invoice_Statuses(
40 p_invoice_id IN NUMBER,
41 p_holds_count IN OUT NOCOPY NUMBER,
42 p_approval_status IN OUT NOCOPY VARCHAR2,
43 p_calling_sequence IN VARCHAR2);
44
45 PROCEDURE Update_Inv_Dists_To_Approved(
46 p_invoice_id IN NUMBER,
47 p_user_id IN NUMBER,
48 p_calling_sequence IN VARCHAR2);
49
50 PROCEDURE Update_Inv_Dists_To_Selected(
51 p_invoice_id IN NUMBER,
52 P_line_number IN NUMBER,
53 p_run_option IN VARCHAR2,
54 p_calling_sequence IN VARCHAR2);
55
56 PROCEDURE Approval_Init(
57 p_org_id IN NUMBER,
58 p_invoice_id IN NUMBER,
59 p_invoice_type IN VARCHAR2 DEFAULT NULL,
60 p_tolerance_id IN NUMBER,
61 p_services_tolerance_id IN NUMBER,
62 p_conc_flag IN VARCHAR2,
63 p_set_of_books_id IN OUT NOCOPY NUMBER,
64 p_recalc_pay_sched_flag IN OUT NOCOPY VARCHAR2,
65 p_sys_xrate_gain_ccid IN OUT NOCOPY NUMBER,
66 p_sys_xrate_loss_ccid IN OUT NOCOPY NUMBER,
67 p_base_currency_code IN OUT NOCOPY VARCHAR2,
68 p_inv_enc_type_id IN OUT NOCOPY NUMBER,
69 p_purch_enc_type_id IN OUT NOCOPY NUMBER,
70 p_gl_date_from_receipt_flag IN OUT NOCOPY VARCHAR2,
71 p_receipt_acc_days IN OUT NOCOPY NUMBER,
72 p_system_user IN OUT NOCOPY NUMBER,
73 p_user_id IN OUT NOCOPY NUMBER,
74 p_goods_ship_amt_tolerance IN OUT NOCOPY NUMBER,
75 p_goods_rate_amt_tolerance IN OUT NOCOPY NUMBER,
76 p_goods_total_amt_tolerance IN OUT NOCOPY NUMBER,
77 p_services_ship_amt_tolerance IN OUT NOCOPY NUMBER,
78 p_services_rate_amt_tolerance IN OUT NOCOPY NUMBER,
79 p_services_total_amt_tolerance IN OUT NOCOPY NUMBER,
80 p_price_tolerance IN OUT NOCOPY NUMBER,
81 p_qty_tolerance IN OUT NOCOPY NUMBER,
82 p_qty_rec_tolerance IN OUT NOCOPY NUMBER,
83 p_amt_tolerance IN OUT NOCOPY NUMBER,
84 p_amt_rec_tolerance IN OUT NOCOPY NUMBER,
85 p_max_qty_ord_tolerance IN OUT NOCOPY NUMBER,
86 p_max_qty_rec_tolerance IN OUT NOCOPY NUMBER,
87 p_max_amt_ord_tolerance IN OUT NOCOPY NUMBER,
88 p_max_amt_rec_tolerance IN OUT NOCOPY NUMBER,
89 p_invoice_line_count OUT NOCOPY NUMBER, --Bug 6684139
90 p_calling_sequence IN VARCHAR2);
91
92 PROCEDURE Set_Hold(
93 p_invoice_id IN NUMBER,
94 p_line_location_id IN NUMBER,
95 p_rcv_transaction_id IN NUMBER,
96 p_hold_lookup_code IN VARCHAR2,
97 p_hold_reason IN VARCHAR2,
98 p_holds IN OUT NOCOPY HOLDSARRAY,
99 p_holds_count IN OUT NOCOPY COUNTARRAY,
100 p_calling_sequence IN VARCHAR2);
101
102 PROCEDURE Count_Hold(
103 p_hold_lookup_code IN VARCHAR2,
104 p_holds IN OUT NOCOPY HOLDSARRAY,
105 p_count IN OUT NOCOPY COUNTARRAY,
106 p_calling_sequence IN VARCHAR2);
107
108 PROCEDURE Get_Release_Lookup_For_Hold(
109 p_hold_lookup_code IN VARCHAR2,
110 p_release_lookup_code IN OUT NOCOPY VARCHAR2,
111 p_calling_sequence IN VARCHAR2);
112
113 PROCEDURE Withhold_Tax_On(
114 p_invoice_id IN NUMBER,
115 p_gl_date_from_receipt IN VARCHAR2,
116 p_last_updated_by IN NUMBER,
117 p_last_update_login IN NUMBER,
118 p_program_application_id IN NUMBER,
119 p_program_id IN NUMBER,
120 p_request_id IN NUMBER,
121 p_system_user IN NUMBER,
122 p_holds IN OUT NOCOPY HOLDSARRAY,
123 p_holds_count IN OUT NOCOPY COUNTARRAY,
124 p_release_count IN OUT NOCOPY COUNTARRAY,
125 p_calling_sequence IN VARCHAR2);
126
127 PROCEDURE Line_Base_Amount_Calculation(
128 p_invoice_id IN NUMBER,
129 p_invoice_currency_code IN VARCHAR2,
130 p_base_currency_code IN VARCHAR2,
131 p_exchange_rate IN NUMBER,
132 p_need_to_round_flag IN VARCHAR2 DEFAULT 'N',
133 p_calling_sequence IN VARCHAR2);
134
135 PROCEDURE Dist_Base_Amount_Calculation(
136 p_invoice_id IN NUMBER,
137 p_invoice_line_number IN NUMBER,
138 p_invoice_currency_code IN VARCHAR2,
139 p_base_currency_code IN VARCHAR2,
140 p_invoice_exchange_rate IN NUMBER,
141 p_need_to_round_flag IN VARCHAR2 DEFAULT 'N',
142 p_calling_sequence IN VARCHAR2);
143
144 PROCEDURE Execute_General_Checks(
145 p_invoice_id IN NUMBER,
146 p_set_of_books_id IN NUMBER,
147 p_base_currency_code IN VARCHAR2,
148 p_invoice_amount IN NUMBER,
149 p_base_amount IN NUMBER,
150 p_invoice_currency_code IN VARCHAR2,
151 p_invoice_amount_limit IN NUMBER,
152 p_hold_future_payments_flag IN VARCHAR2,
153 p_system_user IN NUMBER,
154 p_holds IN OUT NOCOPY HOLDSARRAY,
155 p_holds_count IN OUT NOCOPY COUNTARRAY,
156 p_release_count IN OUT NOCOPY COUNTARRAY,
157 p_calling_sequence IN VARCHAR2);
158
159 PROCEDURE Check_Dist_Variance(
160 p_invoice_id IN NUMBER,
161 p_invoice_line_number IN NUMBER,
162 p_system_user IN NUMBER,
163 p_holds IN OUT NOCOPY HOLDSARRAY,
164 p_holds_count IN OUT NOCOPY COUNTARRAY,
165 p_release_count IN OUT NOCOPY COUNTARRAY,
166 p_distribution_variance_exist OUT NOCOPY BOOLEAN,
167 p_calling_sequence IN VARCHAR2);
168
169 PROCEDURE Check_Line_Variance(
170 p_invoice_id IN NUMBER,
171 p_system_user IN NUMBER,
172 p_holds IN OUT NOCOPY HOLDSARRAY,
173 p_holds_count IN OUT NOCOPY COUNTARRAY,
174 p_release_count IN OUT NOCOPY COUNTARRAY,
175 p_line_variance_hold_exist OUT NOCOPY BOOLEAN,
176 p_calling_sequence IN VARCHAR2,
177 p_base_currency_code IN VARCHAR2); --bug7271262
178
179 PROCEDURE Check_Prepaid_Amount(
180 p_invoice_id IN NUMBER,
181 p_system_user IN NUMBER,
182 p_holds IN OUT NOCOPY HOLDSARRAY,
183 p_holds_count IN OUT NOCOPY COUNTARRAY,
184 p_release_count IN OUT NOCOPY COUNTARRAY,
185 p_calling_sequence IN VARCHAR2);
186
187 PROCEDURE Check_No_Rate(
188 p_invoice_id IN NUMBER,
189 p_base_currency_code IN VARCHAR2,
190 p_system_user IN NUMBER,
191 p_holds IN OUT NOCOPY HOLDSARRAY,
192 p_holds_count IN OUT NOCOPY COUNTARRAY,
193 p_release_count IN OUT NOCOPY COUNTARRAY,
194 p_calling_sequence IN VARCHAR2);
195
196 PROCEDURE Check_invoice_vendor(
197 p_invoice_id IN NUMBER,
198 p_base_currency_code IN VARCHAR2,
199 p_invoice_amount IN NUMBER,
200 p_base_amount IN NUMBER,
201 p_invoice_currency_code IN VARCHAR2,
202 p_invoice_amount_limit IN NUMBER,
203 p_hold_future_payments_flag IN VARCHAR2,
204 p_system_user IN NUMBER,
205 p_holds IN OUT NOCOPY HOLDSARRAY,
206 p_holds_count IN OUT NOCOPY COUNTARRAY,
207 p_release_count IN OUT NOCOPY COUNTARRAY,
208 p_calling_sequence IN VARCHAR2);
209
210 PROCEDURE Check_Manual_AWT_Segments(
211 p_invoice_id IN NUMBER,
212 p_system_user IN NUMBER,
213 p_holds IN OUT NOCOPY HOLDSARRAY,
214 p_holds_count IN OUT NOCOPY COUNTARRAY,
215 p_release_count IN OUT NOCOPY COUNTARRAY,
216 p_calling_sequence IN VARCHAR2);
217
218 PROCEDURE Check_PO_Required(
219 p_invoice_id IN NUMBER,
220 p_system_user IN NUMBER,
221 p_holds IN OUT NOCOPY HOLDSARRAY,
222 p_holds_count IN OUT NOCOPY COUNTARRAY,
223 p_release_count IN OUT NOCOPY COUNTARRAY,
224 p_calling_sequence IN VARCHAR2);
225
226 PROCEDURE Check_Invalid_Dist_Acct(
227 p_invoice_id IN NUMBER,
228 p_system_user IN NUMBER,
229 p_holds IN OUT NOCOPY HOLDSARRAY,
230 p_holds_count IN OUT NOCOPY COUNTARRAY,
231 p_release_count IN OUT NOCOPY COUNTARRAY,
232 p_calling_sequence IN VARCHAR2);
233
234 FUNCTION Check_hold_batch_releaseable(
235 p_hold_name IN VARCHAR2,
236 p_calling_sequence IN VARCHAR2) RETURN VARCHAR2;
237
238 PROCEDURE Generate_Account_Event(
239 p_invoice_id IN NUMBER,
240 p_calling_sequence IN VARCHAR2);
241
242 PROCEDURE Update_Total_Dist_Amount(
243 p_invoice_id IN NUMBER,
244 p_calling_sequence IN VARCHAR2);
245
246 PROCEDURE Exclude_Tax_Freight_From_Disc(
247 p_invoice_id IN NUMBER,
248 p_exclude_tax_from_discount IN VARCHAR2,
249 p_exclude_freight_from_disc IN VARCHAR2,
250 p_invoice_type_lookup_code IN VARCHAR2,
251 p_curr_calling_sequence IN VARCHAR2) ;
252
253 PROCEDURE update_payment_schedule_prepay(
254 p_invoice_id IN NUMBER,
255 p_apply_amount IN NUMBER,
256 p_amount_positive IN VARCHAR2,
257 p_payment_currency_code IN VARCHAR2,
258 p_user_id IN NUMBER,
259 p_last_update_login IN NUMBER,
260 p_calling_sequence IN VARCHAR2);
261
262 FUNCTION validate_period (p_invoice_id IN NUMBER) RETURN BOOLEAN;
263
264 PROCEDURE Manual_Withhold_Tax(
265 p_invoice_id IN NUMBER,
266 p_last_updated_by IN NUMBER,
267 p_last_update_login IN NUMBER,
268 p_calling_sequence IN VARCHAR2);
269
270 /* Bug 7393338 added this procedure*/
271 PROCEDURE Update_Pay_Sched_For_Awt(p_invoice_id IN NUMBER,
272 p_last_updated_by IN NUMBER,
273 p_last_update_login IN NUMBER,
274 p_calling_sequence IN VARCHAR2);
275
276 PROCEDURE createPaymentSchedules(
277 p_invoice_id IN NUMBER,
278 p_calling_sequence IN VARCHAR2);
279
280 Procedure Print_Debug(
281 p_api_name IN VARCHAR2,
282 p_debug_info IN VARCHAR2);
283
284 CURSOR invoice_line_cur (c_invoice_id NUMBER) IS
285 SELECT INVOICE_ID,
286 LINE_NUMBER,
287 LINE_TYPE_LOOKUP_CODE,
288 REQUESTER_ID,
289 DESCRIPTION,
290 LINE_SOURCE,
291 ORG_ID,
292 LINE_GROUP_NUMBER,
293 INVENTORY_ITEM_ID,
294 ITEM_DESCRIPTION,
295 SERIAL_NUMBER,
296 MANUFACTURER,
297 MODEL_NUMBER,
298 WARRANTY_NUMBER,
299 GENERATE_DISTS,
300 MATCH_TYPE,
301 DISTRIBUTION_SET_ID,
302 ACCOUNT_SEGMENT,
303 BALANCING_SEGMENT,
304 COST_CENTER_SEGMENT,
305 OVERLAY_DIST_CODE_CONCAT,
306 DEFAULT_DIST_CCID,
307 PRORATE_ACROSS_ALL_ITEMS,
308 ACCOUNTING_DATE,
309 PERIOD_NAME ,
310 DEFERRED_ACCTG_FLAG ,
311 DEF_ACCTG_START_DATE ,
312 DEF_ACCTG_END_DATE,
313 DEF_ACCTG_NUMBER_OF_PERIODS,
314 DEF_ACCTG_PERIOD_TYPE ,
315 SET_OF_BOOKS_ID,
316 AMOUNT,
317 BASE_AMOUNT,
318 ROUNDING_AMT,
319 QUANTITY_INVOICED,
320 UNIT_MEAS_LOOKUP_CODE ,
321 UNIT_PRICE,
322 WFAPPROVAL_STATUS,
323 DISCARDED_FLAG,
324 ORIGINAL_AMOUNT,
325 ORIGINAL_BASE_AMOUNT ,
326 ORIGINAL_ROUNDING_AMT ,
327 CANCELLED_FLAG ,
328 INCOME_TAX_REGION,
329 TYPE_1099 ,
330 STAT_AMOUNT ,
331 PREPAY_INVOICE_ID ,
332 PREPAY_LINE_NUMBER ,
333 INVOICE_INCLUDES_PREPAY_FLAG ,
334 CORRECTED_INV_ID ,
335 CORRECTED_LINE_NUMBER ,
336 PO_HEADER_ID,
337 PO_LINE_ID ,
338 PO_RELEASE_ID ,
339 PO_LINE_LOCATION_ID ,
340 PO_DISTRIBUTION_ID,
341 RCV_TRANSACTION_ID,
342 FINAL_MATCH_FLAG,
343 ASSETS_TRACKING_FLAG ,
344 ASSET_BOOK_TYPE_CODE ,
345 ASSET_CATEGORY_ID ,
346 PROJECT_ID ,
347 TASK_ID ,
348 EXPENDITURE_TYPE ,
349 EXPENDITURE_ITEM_DATE ,
350 EXPENDITURE_ORGANIZATION_ID ,
351 PA_QUANTITY,
352 PA_CC_AR_INVOICE_ID ,
353 PA_CC_AR_INVOICE_LINE_NUM ,
354 PA_CC_PROCESSED_CODE ,
355 AWARD_ID,
356 AWT_GROUP_ID ,
357 REFERENCE_1 ,
358 REFERENCE_2 ,
359 RECEIPT_VERIFIED_FLAG ,
360 RECEIPT_REQUIRED_FLAG ,
361 RECEIPT_MISSING_FLAG ,
362 JUSTIFICATION ,
363 EXPENSE_GROUP ,
364 START_EXPENSE_DATE ,
365 END_EXPENSE_DATE ,
366 RECEIPT_CURRENCY_CODE ,
367 RECEIPT_CONVERSION_RATE,
368 RECEIPT_CURRENCY_AMOUNT ,
369 DAILY_AMOUNT ,
370 WEB_PARAMETER_ID ,
371 ADJUSTMENT_REASON ,
372 MERCHANT_DOCUMENT_NUMBER ,
373 MERCHANT_NAME ,
374 MERCHANT_REFERENCE ,
375 MERCHANT_TAX_REG_NUMBER,
376 MERCHANT_TAXPAYER_ID ,
377 COUNTRY_OF_SUPPLY,
378 CREDIT_CARD_TRX_ID ,
379 COMPANY_PREPAID_INVOICE_ID,
380 CC_REVERSAL_FLAG ,
381 CREATION_DATE ,
382 CREATED_BY,
383 LAST_UPDATED_BY ,
384 LAST_UPDATE_DATE ,
385 LAST_UPDATE_LOGIN ,
386 PROGRAM_APPLICATION_ID ,
387 PROGRAM_ID ,
388 PROGRAM_UPDATE_DATE,
389 REQUEST_ID ,
390 ATTRIBUTE_CATEGORY,
391 ATTRIBUTE1,
392 ATTRIBUTE2 ,
393 ATTRIBUTE3 ,
394 ATTRIBUTE4 ,
395 ATTRIBUTE5 ,
396 ATTRIBUTE6 ,
397 ATTRIBUTE7 ,
398 ATTRIBUTE8,
399 ATTRIBUTE9 ,
400 ATTRIBUTE10,
401 ATTRIBUTE11,
402 ATTRIBUTE12,
403 ATTRIBUTE13 ,
404 ATTRIBUTE14,
405 ATTRIBUTE15,
406 GLOBAL_ATTRIBUTE_CATEGORY,
407 GLOBAL_ATTRIBUTE1,
408 GLOBAL_ATTRIBUTE2,
409 GLOBAL_ATTRIBUTE3,
410 GLOBAL_ATTRIBUTE4 ,
411 GLOBAL_ATTRIBUTE5 ,
412 GLOBAL_ATTRIBUTE6 ,
413 GLOBAL_ATTRIBUTE7 ,
414 GLOBAL_ATTRIBUTE8 ,
415 GLOBAL_ATTRIBUTE9 ,
416 GLOBAL_ATTRIBUTE10,
417 GLOBAL_ATTRIBUTE11,
418 GLOBAL_ATTRIBUTE12 ,
419 GLOBAL_ATTRIBUTE13 ,
420 GLOBAL_ATTRIBUTE14 ,
421 GLOBAL_ATTRIBUTE15 ,
422 GLOBAL_ATTRIBUTE16 ,
423 GLOBAL_ATTRIBUTE17 ,
424 GLOBAL_ATTRIBUTE18 ,
425 GLOBAL_ATTRIBUTE19 ,
426 GLOBAL_ATTRIBUTE20 ,
427 INCLUDED_TAX_AMOUNT,
428 PRIMARY_INTENDED_USE,
429 APPLICATION_ID,
430 PRODUCT_TABLE,
431 REFERENCE_KEY1,
432 REFERENCE_KEY2,
433 REFERENCE_KEY3,
434 REFERENCE_KEY4,
435 REFERENCE_KEY5,
436 SHIP_TO_LOCATION_ID,
437 PAY_AWT_GROUP_ID --bug 7022001
438 FROM ap_invoice_lines_all
439 WHERE invoice_id = c_invoice_id
440 ORDER BY decode(line_type_lookup_code,'ITEM',1,2), line_number;
441
442 PROCEDURE initialize_invoice_holds(
443 p_invoice_id IN NUMBER,
444 p_calling_sequence IN VARCHAR2);
445
446 TYPE holds_rec_type IS RECORD (
447 hold_lookup_code ap_holds_all.hold_lookup_code%type,
448 hold_status varchar2(30),
449 invoice_id ap_holds_all.invoice_id%type,
450 hold_reason ap_holds_all.hold_reason%type,
451 release_lookup_code ap_holds_all.release_lookup_code%type,
452 line_location_id ap_holds_all.line_location_id%type,
453 rcv_transaction_id ap_holds_all.rcv_transaction_id%type,
454 last_updated_by ap_holds_all.last_updated_by%type,
455 responsibility_id ap_holds_all.responsibility_id%type);
456
457 TYPE holds_tab_type IS TABLE OF holds_rec_type INDEX BY BINARY_INTEGER;
458
459 g_holds_tab holds_tab_type;
460
461 Procedure Count_Org_Hold(
462 p_org_id IN NUMBER,
463 p_hold_lookup_code IN VARCHAR2,
464 p_place_or_release IN VARCHAR2,
465 p_calling_sequence IN VARCHAR2);
466
467
468 /*============================================================================
469 | Procedure Definitions
470 *===========================================================================*/
471
472 /*=============================================================================
473 | PUBLIC PROCEDURE APPROVE
474 |
475 | Description
476 | Online Approval and later batch approval
477 |
478 | PARAMETERS
479 | p_run_option Run Option to indicate whether to approve
480 | only invoices with unapproved distributions
481 | or all invoices ('New' or 'All)
482 | p_invoice_batch_id Invoice Batch Id (For Batch Approval)
483 | p_begin_invoice_date Begin Invoice Date (Selection criteria)
484 | p_end_invoice_date End of Invoice Date (Selection criteria)
485 | p_pay_group Pay Group(Select criteria for Batch Approval)
486 | p_invoice_id Invoice_id
487 | p_entered_by Entered_by User id
488 | p_set_of_books_id Set of books id
489 | (Selection criteria for Batch Approval)
490 | p_trace_option
491 | p_conc_flag Indicate whether the approval process is a
492 | concurrent process or not or if it is online
493 | p_holds_count Return Hold Count of invoice (For Online
494 | Approval called by invoice workbench)
495 | p_approval_status Return Approval Status of invoice
496 | (For Online Approval called by form)
497 | p_calling_sequence Debugging string to indicate path of module
498 | calls to be printed out upon error.
499 | p_debug_switch Debug switch to be turned on or off
500 |
501 | PROGRAM FLOW
502 |
503 | Retrieve system variables to be used by Approval Program
504 | For each invoice
505 | IF invoice needs approving (i.e. not the case where run_option is 'New'
506 | and the invoice doesn't have any unapproved distributions)
507 | IF Accrual Basis is being used
508 | IF automatic offsets is enabled
509 | Populate Invoice Dist liability account
510 | Calculate Tax (Etax API) which will determine the tax amt and
511 | whether it is inclusive or exclusive...
512 | Check Line Variance
513 | Calculate Base Amount and round at Line level
514 | Call Etax api to 'Calculate Tax', which might return exclusive tax lines
515 | and/or inclusive tax amount.
516 | Open a Lines Cursor - loop for each Line
517 | If inclusive tax is returned by tax calculation api, then create taxable
518 | distributions for (line_amount - inclusive tax amount).
519 | If Line need to generate distributions
520 | check sufficient line data
521 | Generate distributions
522 | end if
523 | Update Invoice Distributions as selected for approval
524 | Execute Distribution variance check
525 | IPV/ERV creation and valid ERV ccid check
526 | Close Line Cursor if no more line to check
527 | Call Etax api 'Determine Recovery' to create Tax Distributions for the invoice.
528 | Open a Lines Cursor - loop for each Line
529 | Base amount calculation and rounding at Distribution Level for line
530 | Close Line Cursor if no more line to check
531 | Execute General Invoice Checks
532 | Get invoice matched status
533 | IF invoice is matched
534 | Execute Quantity Variance Check
535 | Execute Matched Checks
536 | Execute PO Final Close Check
537 | Validate Invoice for Tax (etax api), which will validate
538 | the document for tax information.
539 | IF invoice is not a matched prepayment
540 | Execute Funds Control (Funds Reservation)
541 | Execute Withholding Tax
542 | Update Invoice Dists to Appropriate Approval Status
543 | End Loop
544 | Accounting Event Generation
545 | IF Recalculate Payment Schedule Option is enabled
546 | Execute Due Date Sweeper
547 | If online approval then
548 | Calculate Invoice Hold Count and Release Count
549 | Print out appropriate Return Message
550 | End If
551 |
552 | KNOWN ISSUES:
553 | p_begin_invoice_date,
554 | p_end_invoice_date,
555 | p_pay_group,
556 | p_entered_by,
557 | p_set_of_books_id,
558 | p_trace_option
559 | are not needed here in this
560 | procedure. The logic of selecting all invoices included in a batch
561 | is in Invoice Validation Report. Code clean up should be done when
562 | invoice work bench form is being modified. Now is modified to have
563 | default value so that these two parameters can be omitted.
564 *============================================================================*/
565
566 PROCEDURE Approve(
567 p_run_option IN VARCHAR2,
568 p_invoice_batch_id IN NUMBER,
569 p_begin_invoice_date IN DATE DEFAULT NULL,
570 p_end_invoice_date IN DATE DEFAULT NULL,
571 p_vendor_id IN NUMBER,
572 p_pay_group IN VARCHAR2,
573 p_invoice_id IN NUMBER,
574 p_entered_by IN NUMBER,
575 p_set_of_books_id IN NUMBER,
576 p_trace_option IN VARCHAR2,
577 p_conc_flag IN VARCHAR2,
578 p_holds_count IN OUT NOCOPY NUMBER,
579 p_approval_status IN OUT NOCOPY VARCHAR2,
580 p_funds_return_code OUT NOCOPY VARCHAR2,
581 p_calling_mode IN VARCHAR2 DEFAULT 'APPROVE',
582 p_calling_sequence IN VARCHAR2,
583 p_debug_switch IN VARCHAR2 DEFAULT 'N',
584 p_budget_control IN VARCHAR2 DEFAULT 'Y',
585 p_commit IN VARCHAR2 DEFAULT 'Y') IS
586
587 CURSOR approve_invoice_cur IS
588 SELECT AI.invoice_id,
589 AI.invoice_num,
590 AI.invoice_amount,
591 AI.base_amount,
592 AI.exchange_rate,
593 AI.invoice_currency_code,
594 PVS.invoice_amount_limit,
595 nvl(PVS.hold_future_payments_flag,'N'),
596 AI.invoice_type_lookup_code,
597 AI.exchange_date,
598 AI.exchange_rate_type,
599 AI.vendor_id,
600 AI.invoice_date,
601 AI.org_id,
602 nvl(AI.disc_is_inv_less_tax_flag,'N'),
603 nvl(AI.exclude_freight_from_discount,'N'),
604 pvs.tolerance_id,
605 pvs.services_tolerance_id
606 FROM ap_invoices_all AI,
607 ap_suppliers PV,
608 ap_supplier_sites_all PVS
609 WHERE AI.invoice_id = p_invoice_id
610 AND AI.vendor_id = PV.vendor_id
611 AND AI.vendor_site_id = PVS.vendor_site_id;
612
613
614 -- Payment Requests: Cursor for payment request type of invoices
615 CURSOR approve_pay_request_cur IS
616 SELECT AI.invoice_id,
617 AI.invoice_num,
618 AI.invoice_amount,
619 AI.base_amount,
620 AI.exchange_rate,
621 AI.invoice_currency_code,
622 NULL, -- invoice_amount_limit,
623 'N', -- hold_future_payments_flag
624 AI.invoice_type_lookup_code,
625 AI.exchange_date,
626 AI.exchange_rate_type,
627 AI.vendor_id,
628 AI.invoice_date,
629 AI.org_id,
630 nvl(AI.disc_is_inv_less_tax_flag,'N'),
631 nvl(AI.exclude_freight_from_discount,'N')
632 FROM ap_invoices_all AI
633 WHERE AI.invoice_id = p_invoice_id;
634
635 CURSOR invoice_type_cur IS
636 SELECT invoice_type_lookup_code
637 FROM ap_invoices_all
638 WHERE invoice_id = p_invoice_id;
639
640 l_chart_of_accounts_id NUMBER;
641 l_recalc_pay_schedule_flag VARCHAR2(1);
642 l_gl_date_from_receipt VARCHAR2(1);
643 l_cash_only BOOLEAN;
644 l_system_user NUMBER;
645
646 -- Tolerance Related Variables
647 l_goods_ship_amt_tolerance NUMBER;
648 l_goods_rate_amt_tolerance NUMBER;
649 l_goods_total_amt_tolerance NUMBER;
650 l_services_ship_amt_tolerance NUMBER;
651 l_services_rate_amt_tolerance NUMBER;
652 l_services_total_amt_tolerance NUMBER;
653 l_price_tol NUMBER;
654 l_qty_tol NUMBER;
655 l_qty_rec_tol NUMBER;
656 l_amt_tol NUMBER;
657 l_amt_rec_tol NUMBER;
658 l_max_qty_ord_tol NUMBER;
659 l_max_qty_rec_tol NUMBER;
660 l_max_amt_ord_tol NUMBER;
661 l_max_amt_rec_tol NUMBER;
662
663 l_flex_method VARCHAR2(25);
664 l_sys_xrate_gain_ccid NUMBER;
665 l_sys_xrate_loss_ccid NUMBER;
666 l_base_currency_code VARCHAR2(15);
667 l_inv_enc_type_id NUMBER;
668 l_purch_enc_type_id NUMBER;
669 l_user_id NUMBER;
670 l_invoice_id NUMBER;
671 l_invoice_num VARCHAR2(50);
672 l_holds HOLDSARRAY;
673 l_hold_count COUNTARRAY;
674 l_release_count COUNTARRAY;
675 l_total_hold_count NUMBER;
676 l_total_release_count NUMBER;
677 l_set_of_books_id NUMBER;
678 l_matched BOOLEAN;
679 l_receipt_acc_days NUMBER;
680 l_return_message_name VARCHAR2(100);
681 l_any_records_flag VARCHAR2(1) := 'N';
682 l_set_tokens VARCHAR2(1) := 'N';
683 num BINARY_INTEGER := 1;
684
685 l_debug_loc VARCHAR2(30) := 'Approval';
686 l_curr_calling_sequence VARCHAR2(2000);
687 l_debug_info VARCHAR2(2000);
688
689 l_exchange_rate AP_INVOICES.exchange_rate%TYPE;
690 l_exchange_rate_type AP_INVOICES.exchange_rate_type%TYPE;
691 l_exchange_date AP_INVOICES.exchange_date%TYPE;
692 l_invoice_amount AP_INVOICES.invoice_amount%TYPE;
693 l_invoice_base_amount AP_INVOICES.base_amount%TYPE;
694 l_vendor_id AP_INVOICES.vendor_id%TYPE;
695 l_invoice_date AP_INVOICES.invoice_date%TYPE;
696 l_invoice_currency_code AP_INVOICES.invoice_currency_code%TYPE;
697 l_invoice_type AP_INVOICES.invoice_type_lookup_code%TYPE;
698
699 t_inv_lines_table AP_INVOICES_PKG.t_invoice_lines_table;
700
701 l_insufficient_data_exist BOOLEAN := FALSE;
702 l_line_variance_hold_exist BOOLEAN := FALSE;
703 l_need_to_round_flag VARCHAR2(1) := 'Y';
704 l_distribution_variance_exist BOOLEAN;
705 l_result BOOLEAN;
706 l_org_id NUMBER;
707
708 /* Introduced to handle Consumption Tax */
709 l_invoice_amount_limit NUMBER;
710 l_hold_future_payments_flag VARCHAR2(1);
711 l_diff_flag VARCHAR2(1);
712 l_success BOOLEAN;
713 l_error_code VARCHAR2(4000);
714
715 Tax_Exception EXCEPTION;
716 Global_Exception EXCEPTION;
717 LCM_Exception EXCEPTION; --Bug 7718385
718 --Retropricing
719 l_invoice_type_lookup_code AP_INVOICES_ALL.invoice_type_lookup_code%TYPE;
720
721 l_invoice_type_pr AP_INVOICES_ALL.invoice_type_lookup_code%TYPE;
722 l_exclude_tax_from_discount VARCHAR2(1);
723 l_exclude_freight_from_disc VARCHAR2(1);
724 l_cur_count NUMBER := 0;
725 l_prorate_across_all_items VARCHAR2(1);
726 l_debug_context VARCHAR2(2000);
727
728 l_prepay_dist_count NUMBER;
729 l_retained_amount NUMBER;
730 l_recouped_amount NUMBER;
731 l_tolerance_id NUMBER;
732 l_service_tolerance_id NUMBER;
733
734 l_invoice_rec AP_APPROVAL_PKG.Invoice_Rec;
735
736 l_api_name CONSTANT VARCHAR2(200) := 'Approve';
737
738 -- Bug 6648094
739 l_dist_total NUMBER;
740 l_base_dist_total NUMBER;
741 l_inv_amount NUMBER;
742 l_inv_base_amount NUMBER;
743 l_item_count NUMBER;
744 l_row_count NUMBER:=0;
745 -- Bug 6648094
746 l_invoice_line_count NUMBER :=0; --Bug 6684139
747 l_encumbrance_exists NUMBER := 0; -- Bug 6681580
748
749 l_inv_header_rec ap_invoices_all%rowtype;
750 l_event_class_code zx_trx_headers_gt.event_class_code%TYPE;
751
752 -- Project LCM 7588322
753 l_lcm_return_status VARCHAR2(30) := FND_API.G_RET_STS_SUCCESS;
754 l_lcm_msg_count NUMBER;
755 l_lcm_msg_data VARCHAR2(2000);
756 l_lcm_used VARCHAR2(1) := 'N';
757 l_unpostable_holds_exist VARCHAR2(1) := 'N';
758
759 BEGIN
760
761 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
762
763 IF (p_debug_switch = 'Y') THEN
764 g_debug_mode := 'Y';
765 END IF;
766
767 Print_Debug (l_api_name, 'AP_APPROVAL_PKG.APPROVE.BEGIN');
768
769 ----------------------------------------------------------------
770 l_debug_info := 'Approving INVOICE_ID: '|| p_invoice_id;
771 Print_Debug (l_api_name, l_debug_info);
772 ----------------------------------------------------------------
773
774 IF nvl(p_conc_flag,'N') <> 'Y' THEN
775 g_org_holds.delete;
776 END IF;
777
778 IF p_calling_mode = 'CANCEL' THEN
779 ----------------------------------------------------------------
780 l_debug_info := 'Open Invoice_Type_Cur';
781 Print_Debug(l_api_name, l_debug_info);
782 ----------------------------------------------------------------
783 OPEN Invoice_Type_Cur;
784 FETCH Invoice_Type_Cur
785 INTO l_invoice_type_pr;
786 CLOSE Invoice_Type_Cur;
787 END IF;
788
789
790 IF (p_calling_mode = 'PAYMENT REQUEST') OR
791 (p_calling_mode = 'CANCEL' and l_invoice_type_pr = 'PAYMENT REQUEST') THEN
792
793 ----------------------------------------------------------------
794 l_debug_info := 'Open Approve_Pay_Request_Cur';
795 Print_Debug(l_api_name, l_debug_info);
796 ----------------------------------------------------------------
797 OPEN Approve_Pay_Request_Cur;
798 FETCH Approve_Pay_Request_Cur
799 INTO l_invoice_id,
800 l_invoice_num,
801 l_invoice_amount,
802 l_invoice_base_amount,
803 l_exchange_rate,
804 l_invoice_currency_code,
805 l_invoice_amount_limit,
806 l_hold_future_payments_flag,
807 l_invoice_type,
808 l_exchange_date,
809 l_exchange_rate_type,
810 l_vendor_id,
811 l_invoice_date,
812 g_org_id,
813 l_exclude_tax_from_discount,
814 l_exclude_freight_from_disc;
815
816 ELSE
817 ----------------------------------------------------------------
818 l_debug_info := 'Open Approve_Invoice_Cur';
819 Print_Debug(l_api_name, l_debug_info);
820 ----------------------------------------------------------------
821 OPEN Approve_Invoice_Cur;
822 FETCH Approve_Invoice_Cur
823 INTO l_invoice_id,
824 l_invoice_num,
825 l_invoice_amount,
826 l_invoice_base_amount,
827 l_exchange_rate,
828 l_invoice_currency_code,
829 l_invoice_amount_limit,
830 l_hold_future_payments_flag,
831 l_invoice_type,
832 l_exchange_date,
833 l_exchange_rate_type,
834 l_vendor_id,
835 l_invoice_date,
836 g_org_id,
837 l_exclude_tax_from_discount,
838 l_exclude_freight_from_disc,
839 l_tolerance_id,
840 l_service_tolerance_id;
841
842 IF nvl(p_conc_flag,'N') <> 'Y' THEN
843 ----------------------------------------------------------------
844 l_debug_info := 'Cache Tolerance Templates';
845 Print_Debug(l_api_name, l_debug_info);
846 ----------------------------------------------------------------
847 Cache_Tolerance_Templates(
848 l_tolerance_id,
849 l_service_tolerance_id,
850 l_curr_calling_sequence);
851 END IF;
852
853 END IF;
854
855 ----------------------------------------------------------------
856 l_debug_info := 'Retrieve System Options';
857 Print_Debug(l_api_name, l_debug_info);
858 ----------------------------------------------------------------
859 Approval_Init(
860 g_org_id,
861 l_invoice_id,
862 l_invoice_type,
863 l_tolerance_id,
864 l_service_tolerance_id,
865 p_conc_flag,
866 l_set_of_books_id,
867 l_recalc_pay_schedule_flag,
868 l_sys_xrate_gain_ccid,
869 l_sys_xrate_loss_ccid,
870 l_base_currency_code,
871 l_inv_enc_type_id,
872 l_purch_enc_type_id,
873 l_gl_date_from_receipt,
874 l_receipt_acc_days,
875 l_system_user,
876 l_user_id,
877 l_goods_ship_amt_tolerance,
878 l_goods_rate_amt_tolerance,
879 l_goods_total_amt_tolerance,
880 l_services_ship_amt_tolerance,
881 l_services_rate_amt_tolerance,
882 l_services_total_amt_tolerance,
883 l_price_tol,
884 l_qty_tol,
885 l_qty_rec_tol,
886 l_amt_tol,
887 l_amt_rec_tol,
888 l_max_qty_ord_tol,
889 l_max_qty_rec_tol,
890 l_max_amt_ord_tol,
891 l_max_amt_rec_tol,
892 l_invoice_line_count, --Bug 6684139
893 l_curr_calling_sequence);
894
895 ----------------------------------------------------------------
896 l_debug_info := 'Initialize Invoice Holds Array';
897 Print_Debug(l_api_name, l_debug_info);
898 ----------------------------------------------------------------
899 Initialize_Invoice_Holds(
900 p_invoice_id => p_invoice_id,
901 p_calling_sequence => l_curr_calling_sequence);
902
903
904 IF (p_calling_mode = 'PAYMENT REQUEST') OR
905 (p_calling_mode = 'CANCEL' and l_invoice_type_pr = 'PAYMENT REQUEST') THEN
906 l_cur_count := Approve_Pay_Request_Cur%ROWCOUNT;
907 ELSE
908 l_cur_count := Approve_Invoice_Cur%ROWCOUNT;
909 END IF;
910
911 IF (l_cur_count <> 0 ) THEN
912
913 l_any_records_flag := 'Y';
914
915 -----------------------------------------------------------------------
916 l_debug_info := 'Check run option, to determine whether ok to approve';
917 Print_Debug(l_api_name, l_debug_info);
918 -----------------------------------------------------------------------
919
920 IF Inv_Needs_Approving(
921 p_invoice_id,
922 p_run_option,
923 l_curr_calling_sequence) THEN
924
925 l_matched := Get_Inv_Matched_Status(
926 l_invoice_id,
927 l_curr_calling_sequence);
928
929 IF (p_calling_mode = 'APPROVE'
930 and nvl(p_conc_flag,'N') <> 'Y'
931 and l_invoice_line_count >0 ) THEN --Bug 6684139
932
933 ----------------------------------------------------------------
934 l_debug_info := 'Calculate Tax on the Invoice';
935 Print_Debug(l_api_name, l_debug_info);
936 ----------------------------------------------------------------
937 l_success := ap_etax_pkg.calling_etax(
938 p_invoice_id => l_invoice_id,
939 p_calling_mode => 'CALCULATE',
940 p_all_error_messages => 'N',
941 p_error_code => l_error_code,
942 p_calling_sequence => l_curr_calling_sequence);
943
944 IF (NOT l_success) THEN
945 RAISE Tax_Exception;
946 END IF;
947 END IF;
948
949 ----------------------------------------------------------------
950 l_debug_info := 'Fetch Invoice Lines';
951 Print_Debug(l_api_name, l_debug_info);
952 ----------------------------------------------------------------
953 OPEN Invoice_Line_Cur(p_invoice_id);
954 FETCH Invoice_Line_Cur
955 BULK COLLECT INTO t_inv_lines_table;
956 CLOSE Invoice_Line_Cur;
957
958 IF nvl(p_conc_flag, 'N') <> 'Y' THEN
959
960 l_invoice_rec.invoice_id := l_invoice_id;
961 l_invoice_rec.invoice_date := l_invoice_date;
962 l_invoice_rec.invoice_currency_code := l_invoice_currency_code;
963 l_invoice_rec.exchange_rate := l_exchange_rate;
964 l_invoice_rec.exchange_rate_type := l_exchange_rate_type;
965 l_invoice_rec.exchange_date := l_exchange_date;
966 l_invoice_rec.vendor_id := l_vendor_id;
967 l_invoice_rec.org_id := l_org_id;
968
969 ----------------------------------------------------------------
970 l_debug_info := 'Generate Distributions. Variance Checks';
971 Print_Debug(l_api_name, l_debug_info);
972 ----------------------------------------------------------------
973
974 --bugfix:6684139/6699825
975 IF (l_invoice_line_count > 0) THEN
976 AP_APPROVAL_PKG.Generate_Distributions
977 (p_invoice_rec => l_invoice_rec,
978 p_base_currency_code => l_base_currency_code,
979 p_inv_batch_id => p_invoice_batch_id, /*Bug#7036685 : Passed p_invoice_batch_id to
980 p_inv_batch_id parameter instead of NULL*/
981 p_run_option => NULL,
982 p_calling_sequence => l_curr_calling_sequence,
983 x_error_code => l_error_code,
984 p_calling_mode => p_calling_mode); /*bug6833543 added p_calling_mode*/
985 END IF;
986
987 IF (p_calling_mode = 'APPROVE' and l_invoice_line_count >0 ) THEN --Bug 6684139
988
989 ----------------------------------------------------------------
990 l_debug_info := 'Generate Tax Distributions';
991 Print_Debug(l_api_name, l_debug_info);
992 ----------------------------------------------------------------
993 l_success := ap_etax_pkg.calling_etax(
994 p_invoice_id => p_invoice_id,
995 p_calling_mode => 'DISTRIBUTE',
996 p_all_error_messages => 'N',
997 p_error_code => l_error_code,
998 p_calling_sequence => l_curr_calling_sequence);
999
1000 IF (NOT l_success) THEN
1001 Raise Tax_Exception;
1002 END IF;
1003 END IF;
1004 END IF; /* nvl(p_conc_flag, 'N')... */
1005
1006 IF (nvl(t_inv_lines_table.count,0) <> 0 ) THEN
1007
1008 -- Perf 6759699
1009 -- if p_run_option is not new then we can call this function
1010 -- for a invoice id
1011 IF (nvl(p_run_option,'Yes') <> 'New') THEN
1012 Update_Inv_Dists_To_Selected( l_invoice_id,
1013 null ,
1014 p_run_option,
1015 l_curr_calling_sequence);
1016 ELSE
1017 FOR i IN NVL(t_inv_lines_table.first,0)..NVL(t_inv_lines_table.last,0)
1018 LOOP
1019 ----------------------------------------------------------------
1020 l_debug_info := 'Update Invoice Distributions to SELECTED';
1021 Print_Debug(l_api_name, l_debug_info);
1022 ----------------------------------------------------------------
1023 -- Update distributions to SELECTED as new inclusive/exclusive
1024 -- tax distributions could have been created.
1025
1026 Update_Inv_Dists_To_Selected(
1027 l_invoice_id,
1028 t_inv_lines_table(i).line_number,
1029 p_run_option,
1030 l_curr_calling_sequence);
1031 END LOOP; --bug6661773
1032 END IF; --p_run_option
1033
1034 ----------------------------------------------------------------
1035 l_debug_info := 'Check Distribution Variance';
1036 Print_Debug(l_api_name, l_debug_info);
1037 ----------------------------------------------------------------
1038
1039 Check_Dist_Variance(
1040 l_invoice_id,
1041 null, --bug6661773
1042 l_system_user,
1043 l_holds,
1044 l_hold_count,
1045 l_release_count,
1046 l_distribution_variance_exist,
1047 l_curr_calling_sequence);
1048 --END LOOP;
1049 END IF;
1050
1051 ----------------------------------------------------------------
1052 l_debug_info := 'Create payment schedule for invoice request';
1053 Print_Debug(l_api_name, l_debug_info);
1054 ----------------------------------------------------------------
1055 createPaymentSchedules(l_invoice_id, l_curr_calling_sequence);
1056
1057
1058 FOR i IN nvl(t_inv_lines_table.first,0)..nvl(t_inv_lines_table.last,0) LOOP
1059
1060 IF (t_inv_lines_table.exists(i)) THEN
1061
1062 IF (l_base_currency_code <> l_invoice_currency_code) AND
1063 (t_inv_lines_table(i).match_type <> 'ADJUSTMENT_CORRECTION') THEN
1064
1065 ----------------------------------------------------------------
1066 l_debug_info := 'Distributions: Calculate Base Amount and Round';
1067 Print_Debug(l_api_name, l_debug_info);
1068 ----------------------------------------------------------------
1069
1070 IF ( l_line_variance_hold_exist = TRUE OR
1071 l_distribution_variance_exist = TRUE ) THEN
1072 l_need_to_round_flag := 'N';
1073 END IF;
1074
1075 Dist_Base_Amount_Calculation(
1076 p_invoice_id => l_invoice_id,
1077 p_invoice_line_number => t_inv_lines_table(i).line_number,
1078 p_invoice_currency_code => l_invoice_currency_code,
1079 p_base_currency_code => l_base_currency_code,
1080 p_invoice_exchange_rate => l_exchange_rate,
1081 p_need_to_round_flag => l_need_to_round_flag,
1082 p_calling_sequence => l_curr_calling_sequence );
1083
1084 END IF;
1085
1086 DECLARE
1087 l_awt_success Varchar2(1000);
1088 BEGIN
1089 ----------------------------------------------------------------
1090 l_debug_info := 'Call Extended Withholding Routine';
1091 Print_Debug(l_api_name, l_debug_info);
1092 ----------------------------------------------------------------
1093 Ap_Extended_Withholding_Pkg.Ap_Ext_Withholding_Default
1094 (p_invoice_id => p_invoice_id,
1095 p_inv_line_num => t_inv_lines_table(i).line_number,
1096 p_inv_dist_id => NULL,
1097 p_calling_module => l_curr_calling_sequence,
1098 p_parent_dist_id => NULL,
1099 p_awt_success => l_awt_success);
1100
1101 IF (l_awt_success <> 'SUCCESS') THEN
1102 RAISE Global_Exception;
1103 END IF;
1104 END;
1105
1106 END IF; /* t_inv_lines_table.exists ...*/
1107 END LOOP;
1108
1109 t_inv_lines_table.DELETE;
1110
1111 -- Bug 6648094
1112 -- Adjust distribution base amount if dist variance does not exist.
1113 -- Needed only for foreign currency invoices which have an exchange
1114 -- rate and the distribution base amts do not add up to invoice
1115 -- base amt.
1116 ---------------------------------------------------------------
1117 l_debug_info := 'Adjust Dists Base Amount for foreign currency rounding';
1118 Print_Debug(l_api_name, l_debug_info);
1119 ---------------------------------------------------------------
1120
1121 IF ( l_line_variance_hold_exist = FALSE AND
1122 l_distribution_variance_exist = FALSE ) THEN
1123
1124 IF (l_base_currency_code <> l_invoice_currency_code) THEN
1125
1126 SELECT SUM(amount)
1127 INTO l_dist_total
1128 FROM ap_invoice_distributions
1129 WHERE invoice_id = l_invoice_id
1130 AND ( (line_type_lookup_code NOT IN ('PREPAY','AWT') AND
1131 prepay_tax_parent_id IS NULL) OR
1132 (line_type_lookup_code = 'PREPAY' AND
1133 nvl(invoice_includes_prepay_flag,'N') = 'Y') OR
1134 (line_type_lookup_code IN ('REC_TAX', 'NONREC_TAX',
1135 'TERV','TIPV','TRV') AND
1136 nvl(invoice_includes_prepay_flag,'N') = 'Y' AND
1137 prepay_tax_parent_id IS NOT NULL)
1138 );
1139 ---------------------------------------------------------------
1140 l_debug_info := 'Sum of Distributions Amounts: '|| l_dist_total;
1141 Print_Debug(l_api_name, l_debug_info);
1142 ---------------------------------------------------------------
1143
1144 SELECT invoice_amount, base_amount
1145 INTO l_inv_amount , l_inv_base_amount
1146 FROM ap_invoices
1147 WHERE invoice_id = l_invoice_id;
1148
1149 ---------------------------------------------------------------
1150 l_debug_info := 'Invoice amount: '|| l_inv_amount ||
1151 ' Invoice base amount: '||l_inv_base_amount;
1152 Print_Debug(l_api_name, l_debug_info);
1153 ---------------------------------------------------------------
1154
1155 SELECT COUNT('X')
1156 INTO l_item_count
1157 FROM ap_invoice_distributions
1158 WHERE invoice_id = l_invoice_id AND
1159 line_type_lookup_code = 'ITEM';
1160
1161 IF (l_dist_total = l_inv_amount) THEN
1162
1163 SELECT SUM(base_amount)
1164 INTO l_base_dist_total
1165 FROM ap_invoice_distributions
1166 WHERE invoice_id = l_invoice_id
1167 AND (
1168 (line_type_lookup_code NOT IN ('PREPAY','AWT') AND
1169 prepay_tax_parent_id IS NULL) OR
1170 (line_type_lookup_code = 'PREPAY' AND
1171 nvl(invoice_includes_prepay_flag,'N') = 'Y') OR
1172 (line_type_lookup_code IN ('REC_TAX', 'NONREC_TAX',
1173 'TERV','TIPV','TRV') AND
1174 nvl(invoice_includes_prepay_flag,'N') = 'Y' AND
1175 prepay_tax_parent_id IS NOT NULL)
1176 );
1177 ---------------------------------------------------------------
1178 l_debug_info := 'Sum of Distributions Base Amounts: '||
1179 l_base_dist_total;
1180 Print_Debug(l_api_name, l_debug_info);
1181 ---------------------------------------------------------------
1182
1183 IF (l_inv_base_amount <> l_base_dist_total) THEN
1184
1185 ---------------------------------------------------------------
1186 l_debug_info := 'Adjust for rounding';
1187 ---------------------------------------------------------------
1188 IF (l_item_count > 0) THEN
1189 --Update ITEM Dists
1190 UPDATE ap_invoice_distributions
1191 SET base_amount = base_amount - (l_base_dist_total - l_inv_base_amount)
1192 WHERE invoice_id = l_invoice_id
1193 AND invoice_distribution_id = (
1194 SELECT MAX(AID1.invoice_distribution_id)
1195 FROM ap_invoice_distributions AID1
1196 WHERE AID1.invoice_id = l_invoice_id
1197 AND AID1.line_type_lookup_code = 'ITEM'
1198 /* Bug 3784909. Folowing two lines Added */
1199 AND NVL(AID1.reversal_flag, 'N') <> 'Y'
1200 AND NVL(AID1.posted_flag, 'N') = 'N'
1201 AND ABS(AID1.amount) = (
1202 SELECT MAX(ABS(AID2.amount))
1203 FROM ap_invoice_distributions AID2
1204 WHERE AID2.invoice_id = l_invoice_id
1205 AND AID2.line_type_lookup_code = 'ITEM'
1206 -- Bug 3784909. Folowing two lines Added
1207 AND NVL(AID2.reversal_flag, 'N') <> 'Y'
1208 AND NVL(AID2.posted_flag, 'N') = 'N'));
1209 ELSE
1210 -- Update FREIGHT or MISC Dists
1211 UPDATE ap_invoice_distributions
1212 SET base_amount = base_amount - (l_base_dist_total - l_inv_base_amount)
1213 WHERE invoice_id = l_invoice_id
1214 AND invoice_distribution_id = (
1215 SELECT MAX(AID3.invoice_distribution_id)
1216 FROM ap_invoice_distributions AID3
1217 WHERE AID3.invoice_id = l_invoice_id
1218 AND AID3.line_type_lookup_code
1219 IN ('FREIGHT','MISCELLANEOUS')
1220 AND
1221 /* Bug 3784909. Folowing two lines Added */
1222 NVL(AID3.reversal_flag, 'N') = 'N'
1223 AND NVL(AID3.posted_flag, 'N') = 'N'
1224 AND ABS(AID3.amount) = (
1225 SELECT MAX(ABS(AID4.amount))
1226 FROM ap_invoice_distributions AID4
1227 WHERE AID4.invoice_id = l_invoice_id
1228 AND AID4.line_type_lookup_code
1229 IN('FREIGHT','MISCELLANEOUS')
1230 --Bug 3784909. Folowing two lines Added
1231 AND NVL(AID4.reversal_flag, 'N') <> 'Y'
1232 AND NVL(AID4.posted_flag, 'N') = 'N'));
1233 END IF; --IF (l_item_count > 0)
1234
1235 l_row_count := SQL%ROWCOUNT;
1236 IF (l_row_count > 0) THEN
1237 ---------------------------------------------------------
1238 l_debug_info := l_row_count||' rows updated.';
1239 Print_Debug(l_api_name, l_debug_info);
1240 ---------------------------------------------------------
1241 ELSE
1242 ---------------------------------------------------------
1243 l_debug_info := 'No rows Updated';
1244 Print_Debug(l_api_name, l_debug_info);
1245 ---------------------------------------------------------
1246 END IF;
1247 END IF; -- IF (l_dist_total = l_inv_amount)
1248 END IF; -- IF (l_dist_total = l_inv_amount)
1249 END IF; -- If inv currency <> base currency
1250 END IF; -- If l_distribution_variance_exist = TRUE
1251 -- Bug 6648094 Ends
1252
1253 ----------------------------------------------------------------
1254 l_debug_info := 'Update Total Distribution Amount';
1255 Print_Debug(l_api_name, l_debug_info);
1256 ----------------------------------------------------------------
1257 Update_Total_Dist_Amount(l_invoice_id,
1258 l_curr_calling_sequence);
1259
1260 SELECT invoice_type_lookup_code
1261 INTO l_invoice_type_lookup_code
1262 FROM ap_invoices_all
1263 WHERE invoice_id = l_invoice_id;
1264
1265 IF ((l_exclude_tax_from_discount = 'Y' OR l_exclude_freight_from_disc = 'Y')
1266 OR (l_invoice_type_lookup_code IN ('PO PRICE ADJUST','ADJUSTMENT'))) THEN
1267
1268 ----------------------------------------------------------------
1269 l_debug_info := 'Exclude Tax/Freight: Recalculate Payment Schedules';
1270 Print_Debug(l_api_name, l_debug_info);
1271 ----------------------------------------------------------------
1272 Exclude_Tax_Freight_From_Disc(
1273 l_invoice_id,
1274 l_exclude_tax_from_discount,
1275 l_exclude_freight_from_disc,
1276 l_invoice_type_lookup_code,
1277 l_curr_calling_sequence);
1278
1279 IF (l_invoice_type in ('PO PRICE ADJUST','ADJUSTMENT')) THEN
1280 ----------------------------------------------------------------
1281 l_debug_info := 'Retropricing: Check Line Variance';
1282 Print_Debug(l_api_name, l_debug_info);
1283 ----------------------------------------------------------------
1284 Check_Line_Variance(
1285 l_invoice_id,
1286 l_system_user,
1287 l_holds,
1288 l_hold_count,
1289 l_release_count,
1290 l_line_variance_hold_exist,
1291 l_curr_calling_sequence,
1292 l_base_currency_code); --bug 7271262
1293 END IF;
1294 END IF;
1295
1296 ----------------------------------------------------------------
1297 l_debug_info := 'Execute General Checks';
1298 Print_Debug(l_api_name, l_debug_info);
1299 ----------------------------------------------------------------
1300 Execute_General_Checks(
1301 l_invoice_id,
1302 l_set_of_books_id,
1303 l_base_currency_code,
1304 l_invoice_amount,
1305 l_invoice_base_amount,
1306 l_invoice_currency_code,
1307 l_invoice_amount_limit,
1308 l_hold_future_payments_flag,
1309 l_system_user,
1310 l_holds,
1311 l_hold_count,
1312 l_release_count,
1313 l_curr_calling_sequence);
1314
1315 IF (l_matched) THEN
1316
1317 ----------------------------------------------------------------
1318 l_debug_info := 'Execute Quantity Variance Check';
1319 Print_Debug(l_api_name, l_debug_info);
1320 ----------------------------------------------------------------
1321 IF l_invoice_type_lookup_code <> 'PO PRICE ADJUST' THEN
1322 AP_APPROVAL_MATCHED_PKG.Exec_Qty_Variance_Check(
1323 p_invoice_id => l_invoice_id,
1324 p_base_currency_code => l_base_currency_code,
1325 p_inv_currency_code => l_invoice_currency_code,
1326 p_system_user => l_system_user,
1327 p_calling_sequence => l_curr_calling_sequence);
1328 END IF;
1329
1330 ----------------------------------------------------------------
1331 l_debug_info := 'Execute Amount Variance Check';
1332 Print_Debug(l_api_name, l_debug_info);
1333 ----------------------------------------------------------------
1334 AP_APPROVAL_MATCHED_PKG.Exec_Amt_Variance_Check(
1335 p_invoice_id => l_invoice_id,
1336 p_base_currency_code => l_base_currency_code,
1337 p_inv_currency_code => l_invoice_currency_code,
1338 p_system_user => l_system_user,
1339 p_calling_sequence => l_curr_calling_sequence );
1340
1341 -- 7299826 EnC project
1342 ----------------------------------------------------------------
1343 l_debug_info := 'Execute Pay when paid Check';
1344 Print_Debug(l_api_name, l_debug_info);
1345 ----------------------------------------------------------------
1346 AP_APPROVAL_MATCHED_PKG.exec_pay_when_paid_check(
1347 p_invoice_id => l_invoice_id,
1348 p_system_user => l_system_user,
1349 p_holds => l_holds,
1350 p_holds_count => l_hold_count,
1351 p_release_count => l_release_count,
1352 p_calling_sequence => l_curr_calling_sequence);
1353
1354 -- 7299826 EnC project
1355 ----------------------------------------------------------------
1356 l_debug_info := 'Execute PO Deliverable Check';
1357 Print_Debug(l_api_name, l_debug_info);
1358 ----------------------------------------------------------------
1359 AP_APPROVAL_MATCHED_PKG.exec_po_deliverable_check(
1360 p_invoice_id => l_invoice_id,
1361 p_system_user => l_system_user,
1362 p_holds => l_holds,
1363 p_holds_count => l_hold_count,
1364 p_release_count => l_release_count,
1365 p_calling_sequence => l_curr_calling_sequence);
1366
1367 ----------------------------------------------------------------
1368 l_debug_info := 'Execute Matched Checks';
1369 Print_Debug(l_api_name, l_debug_info);
1370 ----------------------------------------------------------------
1371 AP_APPROVAL_MATCHED_PKG.Execute_Matched_Checks(
1372 p_invoice_id => l_invoice_id,
1373 p_base_currency_code => l_base_currency_code,
1374 p_price_tol => l_price_tol,
1375 p_qty_tol => l_qty_tol,
1376 p_qty_rec_tol => l_qty_rec_tol,
1377 p_amt_tol => l_amt_tol,
1378 p_amt_rec_tol => l_amt_rec_tol,
1379 p_max_qty_ord_tol => l_max_qty_ord_tol,
1380 p_max_qty_rec_tol => l_max_qty_rec_tol,
1381 p_max_amt_ord_tol => l_max_amt_ord_tol,
1382 p_max_amt_rec_tol => l_max_amt_rec_tol,
1383 p_goods_ship_amt_tolerance => l_goods_ship_amt_tolerance,
1384 p_goods_rate_amt_tolerance => l_goods_rate_amt_tolerance,
1385 p_goods_total_amt_tolerance => l_goods_total_amt_tolerance,
1386 p_services_ship_amt_tolerance => l_services_ship_amt_tolerance,
1387 p_services_rate_amt_tolerance => l_services_rate_amt_tolerance,
1388 p_services_total_amt_tolerance => l_services_total_amt_tolerance,
1389 p_system_user => l_system_user,
1390 p_conc_flag => p_conc_flag,
1391 p_holds => l_holds,
1392 p_holds_count => l_hold_count,
1393 p_release_count => l_release_count,
1394 p_calling_sequence => l_curr_calling_sequence);
1395
1396 ----------------------------------------------------------------
1397 l_debug_info := 'Execute PO Final Close';
1398 Print_Debug(l_api_name, l_debug_info);
1399 ----------------------------------------------------------------
1400 AP_APPROVAL_MATCHED_PKG.Exec_PO_Final_Close(
1401 l_invoice_id,
1402 l_system_user,
1403 p_conc_flag,
1404 l_holds,
1405 l_hold_count,
1406 l_release_count,
1407 l_curr_calling_sequence);
1408
1409 END IF; -- end of matched check
1410
1411 IF (p_calling_mode = 'APPROVE' and l_invoice_line_count >0 ) THEN --bug 6684139
1412 ----------------------------------------------------------------
1413 l_debug_info := 'Validate Invoice for Tax';
1414 Print_Debug(l_api_name, l_debug_info);
1415 ----------------------------------------------------------------
1416 l_success := ap_etax_pkg.calling_etax(
1417 p_invoice_id => p_invoice_id,
1418 p_calling_mode => 'VALIDATE',
1419 p_all_error_messages => 'N',
1420 p_error_code => l_error_code,
1421 p_calling_sequence => l_curr_calling_sequence);
1422
1423 IF (NOT l_success) THEN
1424 IF (nvl(p_conc_flag,'N') = 'N') THEN
1425 Raise Tax_Exception;
1426 ELSE
1427 NULL;
1428 END IF;
1429 END IF;
1430 END IF;
1431
1432 ----------------------------------------------------------------
1433 l_debug_info := 'Call GMS API to ensure missing ADLs are generated';
1434 Print_Debug(l_api_name, l_debug_info);
1435 ----------------------------------------------------------------
1436 GMS_AP_API2.verify_create_adls
1437 (l_invoice_id,
1438 l_curr_calling_sequence);
1439
1440 ----------------------------------------------------------------
1441 l_debug_info := 'Execute Withholding';
1442 Print_Debug(l_api_name, l_debug_info);
1443 ----------------------------------------------------------------
1444 Withhold_Tax_On(
1445 l_invoice_id,
1446 l_gl_date_from_receipt,
1447 l_system_user,
1448 l_system_user,
1449 -1,
1450 -1,
1451 -1,
1452 l_system_user,
1453 l_holds,
1454 l_hold_count,
1455 l_release_count,
1456 l_curr_calling_sequence);
1457
1458 ----------------------------------------------------------------
1459 l_debug_info := 'Create Prepayment Application Distributions';
1460 Print_Debug(l_api_name, l_debug_info);
1461 ----------------------------------------------------------------
1462 SELECT count(*)
1463 INTO l_prepay_dist_count
1464 FROM ap_invoice_distributions_all
1465 WHERE Invoice_ID = l_invoice_id
1466 AND Line_Type_Lookup_Code = 'PREPAY'
1467 AND Accounting_Event_ID IS NULL;
1468
1469 IF l_prepay_dist_count > 0 THEN
1470 ap_acctg_prepay_dist_pkg.prepay_dist_appl(
1471 l_invoice_id,
1472 l_curr_calling_sequence);
1473 END IF;
1474
1475 ----------------------------------------------------------------
1476 l_debug_info := 'Execute Budgetary Control';
1477 Print_Debug(l_api_name, l_debug_info);
1478 ----------------------------------------------------------------
1479
1480 IF p_budget_control = 'Y' THEN
1481
1482 l_debug_info := 'p_budget_control is Y';
1483 Print_Debug(l_api_name, l_debug_info);
1484 -- Bug 6681580
1485 select count(*)
1486 INTO l_encumbrance_exists
1487 FROM ap_invoice_distributions aid
1488 WHERE nvl(aid.encumbered_flag,'N') not in ('N','R') ----added check for 'R' due to bug 7264524
1489 AND aid.invoice_id = l_invoice_id;
1490
1491 -- Bug 6681580
1492 IF p_calling_mode = 'CANCEL' AND l_encumbrance_exists = 0 THEN
1493 l_debug_info := 'Calling Mode is CANCEL and No Prior Encumb';
1494 Print_Debug(l_api_name, l_debug_info);
1495 ELSE
1496 l_debug_info := 'Calling AP_FUNDS_CONTROL_PKG.Funds_Reserve';
1497 Print_Debug(l_api_name, l_debug_info);
1498
1499 AP_FUNDS_CONTROL_PKG.Funds_Reserve(
1500 p_calling_mode,
1501 l_invoice_id,
1502 l_set_of_books_id,
1503 l_base_currency_code,
1504 p_conc_flag,
1505 l_system_user,
1506 l_holds,
1507 l_hold_count,
1508 l_release_count,
1509 p_funds_return_code,
1510 l_curr_calling_sequence);
1511 END IF; -- Bug 6681580
1512 END IF;
1513
1514
1515 -- Project LCM 7588322
1516 /*Check whether this invoice is matched to any LCM enabled receipt*/
1517 BEGIN
1518 SELECT 'Y'
1519 INTO l_lcm_used
1520 FROM DUAL
1521 WHERE EXISTS
1522 (SELECT 1 FROM AP_INVOICE_DISTRIBUTIONS aid, RCV_TRANSACTIONS rt
1523 WHERE aid.invoice_id = l_invoice_id
1524 AND aid.rcv_transaction_id = rt.transaction_id
1525 AND rt.lcm_shipment_line_id IS NOT NULL
1526 AND aid.match_status_flag = 'S');
1527 EXCEPTION
1528 WHEN NO_DATA_FOUND THEN NULL;
1529 END;
1530
1531 /*Check if there are unpostable holds put on this invoice by now.
1532 If any such holds are there, we should not be calling LCM to
1533 pick this invoice to LCM.*/
1534 -- Added by 7641045, modified by 7678786, modification reverted by 7830298
1535 BEGIN
1536 SELECT 'Y'
1537 INTO l_unpostable_holds_exist
1538 FROM dual
1539 WHERE EXISTS (SELECT 1
1540 FROM ap_holds H, ap_hold_codes C
1541 WHERE H.invoice_id = l_invoice_id
1542 AND H.hold_lookup_code = C.hold_lookup_code
1543 AND ((H.release_lookup_code IS NULL)
1544 AND ((C.postable_flag = 'N') OR (C.postable_flag = 'X'))));
1545 /* The condition above is same as the one used in Update_Inv_Dists_To_Approved
1546 procedure. However, we removed encumbrance checks.*/
1547
1548 EXCEPTION
1549 WHEN NO_DATA_FOUND THEN NULL;
1550 END;
1551
1552
1553
1554 IF(l_lcm_used = 'Y') THEN
1555 IF (l_unpostable_holds_exist <> 'Y') THEN -- Bug 7641045
1556
1557 ----------------------------------------------------------------
1558 l_debug_info := 'Call LCM API';
1559 Print_Debug(l_api_name, l_debug_info);
1560 ----------------------------------------------------------------
1561
1562 --EXECUTE IMMEDIATE
1563 INL_MATCH_GRP.Create_MatchesFromAP
1564 (p_api_version => 1.0, -- API version
1565 p_init_msg_list => FND_API.G_TRUE, -- This is to initialize the message list whenever the API is called, not cumulating messages from one execution to other
1566 p_commit => FND_API.G_FALSE, -- This is to not issue any commit inside the API, since commit cycle is managed by the calling program
1567 p_invoice_id => l_invoice_id,
1568 x_return_status => l_lcm_return_status, -- Returns "S", "E" or "U", i.e. FND_API.G_RET_STS_SUCCESS , FND_API.G_RET_STS_ERROR or FND_API.G_RET_STS_UNEXP_ERROR.
1569 x_msg_count => l_lcm_msg_count, -- Number of messages in the list
1570 x_msg_data => l_lcm_msg_data); -- Messages stored in encoded format
1571
1572 IF(l_lcm_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1573 -- Bug 7718385
1574 RAISE LCM_Exception;
1575 END IF;
1576 END IF; -- l_unpostable_holds_exist <> 'Y'
1577 END IF; -- l_lcm_used = 'Y'
1578
1579 -- End Project LCM 7588322
1580
1581 ----------------------------------------------------------------
1582 l_debug_info := 'Update Invoice Distributions to APPROVED';
1583 Print_Debug(l_api_name, l_debug_info);
1584 ----------------------------------------------------------------
1585 Update_Inv_Dists_To_Approved(
1586 l_invoice_id,
1587 l_user_id,
1588 l_curr_calling_sequence);
1589
1590 ----------------------------------------------------------------
1591 l_debug_info := 'Generate Accounting Events';
1592 Print_Debug(l_api_name, l_debug_info);
1593 ----------------------------------------------------------------
1594 Generate_Account_Event(
1595 l_invoice_id,
1596 l_curr_calling_sequence);
1597
1598
1599 END IF; -- end of Inv_Needs_Approving...
1600
1601 ----------------------------------------------------------------
1602 l_debug_info := 'Execute Due Date Sweeper after validation';
1603 Print_Debug(l_api_name, l_debug_info);
1604 ----------------------------------------------------------------
1605
1606 IF (l_recalc_pay_schedule_flag = 'Y') THEN
1607
1608 SELECT DECODE(NVL((MAX(aps.last_update_date)- MIN(aps.creation_date)),0),
1609 0,'N','Y')
1610 INTO l_diff_flag
1611 FROM ap_payment_schedules aps
1612 WHERE aps.invoice_id = l_invoice_id;
1613
1614 IF (l_diff_flag = 'N') THEN
1615 AP_PPA_PKG.Due_Date_Sweeper(
1616 l_invoice_id,
1617 l_matched,
1618 l_system_user,
1619 l_receipt_acc_days,
1620 l_curr_calling_sequence);
1621 END IF;
1622 END IF;
1623
1624 ----------------------------------------------------------------
1625 l_debug_info := 'Update force_revalidation_flag to No';
1626 Print_Debug(l_api_name, l_debug_info);
1627 ----------------------------------------------------------------
1628
1629 UPDATE ap_invoices_all
1630 SET force_revalidation_flag = 'N'
1631 WHERE invoice_id = l_invoice_id;
1632
1633 END IF; -- end of approve_invoice_cur cursor count check
1634
1635
1636 IF (p_calling_mode = 'PAYMENT REQUEST') OR
1637 (p_calling_mode = 'CANCEL' and l_invoice_type_pr = 'PAYMENT REQUEST') THEN
1638 ----------------------------------------------------------------
1639 l_debug_info := 'Close approve_pay_request_cur';
1640 Print_Debug(l_api_name, l_debug_info);
1641 ----------------------------------------------------------------
1642 CLOSE approve_pay_request_cur;
1643 ELSE
1644 ----------------------------------------------------------------
1645 l_debug_info := 'Close approve_invoice_cursor';
1646 Print_Debug(l_api_name, l_debug_info);
1647 ----------------------------------------------------------------
1648 CLOSE approve_invoice_cur;
1649 END IF;
1650
1651 ----------------------------------------------------------------
1652 l_debug_info := 'Retrieve total hold count and validation status';
1653 Print_Debug(l_api_name, l_debug_info);
1654 ----------------------------------------------------------------
1655 Get_Invoice_Statuses(
1656 l_invoice_id,
1657 p_holds_count,
1658 p_approval_status,
1659 l_curr_calling_sequence);
1660
1661 ----------------------------------------------------------------
1662 l_debug_info := 'Validation Status: '||p_approval_status;
1663 Print_Debug(l_api_name, l_debug_info);
1664 ----------------------------------------------------------------
1665
1666 IF p_calling_mode = 'APPROVE' THEN
1667
1668 IF l_invoice_line_count > 0 THEN
1669
1670 BEGIN
1671 SELECT *
1672 INTO l_inv_header_rec
1673 FROM ap_invoices_all
1674 WHERE invoice_id = P_Invoice_Id;
1675 END;
1676 --BUG 6974733
1677 IF (l_inv_header_rec.invoice_type_lookup_code NOT IN ('AWT', 'INTEREST')) THEN
1678 -------------------------------------------------------------------
1679 l_debug_info := 'Get event class code';
1680 Print_Debug(l_api_name, l_debug_info);
1681 -------------------------------------------------------------------
1682 IF NOT(AP_ETAX_UTILITY_PKG.Get_Event_Class_Code(
1683 P_Invoice_Type_Lookup_Code => l_inv_header_rec.invoice_type_lookup_code,
1684 P_Event_Class_Code => l_event_class_code,
1685 P_error_code => l_error_code,
1686 P_calling_sequence => l_curr_calling_sequence)) THEN
1687
1688 IF (nvl(p_conc_flag,'N') = 'N') THEN
1689 Raise Tax_Exception;
1690 ELSE
1691 NULL;
1692 END IF;
1693 END IF;
1694
1695 -----------------------------------------------------------------
1696 l_debug_info := 'Call Freeze Distributions';
1697 Print_Debug(l_api_name, l_debug_info);
1698 -----------------------------------------------------------------
1699 --Bug7592845
1700 IF NOT(AP_ETAX_SERVICES_PKG.Freeze_itm_Distributions(
1701 P_Invoice_Header_Rec => l_inv_header_rec,
1702 P_Calling_Mode => 'FREEZE DISTRIBUTIONS',
1703 P_Event_Class_Code => l_event_class_code,
1704 P_All_Error_Messages => 'N',
1705 P_Error_Code => l_error_code,
1706 P_Calling_Sequence => l_curr_calling_sequence)) THEN
1707
1708 IF (nvl(p_conc_flag,'N') = 'N') THEN
1709 Raise Tax_Exception;
1710 ELSE
1711 NULL;
1712 END IF;
1713 END IF;
1714 END IF;--BUG 6974733
1715 IF p_approval_status IN ('APPROVED','AVAILABLE','UNPAID','FULL') THEN
1716
1717 ----------------------------------------------------------------
1718 l_debug_info := 'Call API to freeze invoice in tax schema';
1719 Print_Debug(l_api_name, l_debug_info);
1720 ----------------------------------------------------------------
1721 l_success := ap_etax_pkg.calling_etax(
1722 p_invoice_id => p_invoice_id,
1723 p_calling_mode => 'FREEZE INVOICE',
1724 p_all_error_messages => 'N',
1725 p_error_code => l_error_code,
1726 p_calling_sequence => l_curr_calling_sequence);
1727
1728 IF (NOT l_success) THEN
1729 IF (nvl(p_conc_flag,'N') = 'N') THEN
1730 Raise Tax_Exception;
1731 ELSE
1732 NULL;
1733 END IF;
1734 END IF;
1735 END IF;
1736 END IF;
1737 END IF;
1738
1739 AP_INVOICE_DISTRIBUTIONS_PKG.Make_Distributions_Permanent
1740 (P_Invoice_Id => p_invoice_id,
1741 P_Invoice_Line_Number => NULL,
1742 P_Calling_Sequence => 'Invoice Validation'); --Bug6653070
1743
1744 --END IF;
1745
1746 IF (l_any_records_flag = 'Y') THEN
1747 IF NVL(p_commit, 'Y') = 'Y' THEN
1748 ----------------------------------------------------------------
1749 l_debug_info := 'Commit Data';
1750 Print_Debug(l_api_name, l_debug_info);
1751 ----------------------------------------------------------------
1752 COMMIT;
1753 END IF;
1754 END IF;
1755
1756 Print_Debug (l_api_name, 'AP_APPROVAL_PKG.APPROVE.END');
1757
1758 EXCEPTION
1759 -- Bug 7718385
1760 WHEN LCM_EXCEPTION THEN
1761
1762 -- Logging error messages
1763 FOR i in 1 ..l_lcm_msg_count
1764 LOOP
1765 l_lcm_msg_data := FND_MSG_PUB.get(i, FND_API.g_false);
1766 l_debug_info :='l_msg_data ('||i||'): '||l_lcm_msg_data;
1767 Print_Debug(l_api_name, l_debug_info);
1768 END LOOP;
1769
1770 -- Throwing error messages to form to display
1771 FND_MESSAGE.SET_NAME('SQLAP','AP_LCM_EXCEPTION');
1772 /* Error Text is
1773 -- An error occurred while interfacing the invoice to Landed Cost Management.
1774 -- Error: &ERROR
1775 --
1776 */
1777 FND_MESSAGE.SET_TOKEN('ERROR', l_lcm_msg_data);
1778 APP_EXCEPTION.RAISE_EXCEPTION;
1779
1780 WHEN TAX_EXCEPTION THEN
1781 FND_MESSAGE.SET_NAME('SQLAP','AP_TAX_EXCEPTION');
1782 IF l_error_code IS NOT NULL THEN
1783 FND_MESSAGE.SET_TOKEN('ERROR', l_error_code);
1784 ELSE
1785 FND_MESSAGE.SET_TOKEN('ERROR', SQLERRM);
1786 END IF;
1787
1788 IF (approve_invoice_cur%ISOPEN) THEN
1789 CLOSE approve_invoice_cur;
1790 END IF;
1791 IF (approve_pay_request_cur%ISOPEN) THEN
1792 CLOSE approve_pay_request_cur;
1793 END IF;
1794 IF (invoice_line_cur%ISOPEN) THEN
1795 CLOSE invoice_line_cur;
1796 END IF;
1797
1798 APP_EXCEPTION.RAISE_EXCEPTION;
1799
1800 WHEN OTHERS THEN
1801 IF (SQLCODE <> -20001) THEN
1802 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
1803 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
1804 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
1805 FND_MESSAGE.SET_TOKEN('PARAMETERS',
1806 'Run Option = '|| p_run_option
1807 ||', Batch Id = '|| to_char(p_invoice_batch_id)
1808 ||', Begin Date = '|| to_char(p_begin_invoice_date)
1809 ||', End Date = '|| to_char(p_end_invoice_date)
1810 ||', Vendor Id = '|| to_char(p_vendor_id)
1811 ||', Pay Group = '|| p_pay_group
1812 ||', Invoice Id = '|| to_char(p_invoice_id)
1813 ||', Entered By = '|| to_char(p_entered_by)
1814 ||', Set of Books Id = '|| to_char(p_set_of_books_id));
1815 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
1816 END IF;
1817
1818 IF (approve_invoice_cur%ISOPEN) THEN
1819 CLOSE approve_invoice_cur;
1820 END IF;
1821 IF (approve_pay_request_cur%ISOPEN) THEN
1822 CLOSE approve_pay_request_cur;
1823 END IF;
1824 IF (invoice_line_cur%ISOPEN) THEN
1825 CLOSE invoice_line_cur;
1826 END IF;
1827
1828 APP_EXCEPTION.RAISE_EXCEPTION;
1829
1830 END Approve;
1831
1832 /*bug6858309 - modified the function to look for
1833 ap_invoice_lines instead of ap_invoic_distributions
1834 as dists are not created for freshly created
1835 recurring invoice in R12*/
1836 FUNCTION validate_period (p_invoice_id IN NUMBER)
1837 RETURN BOOLEAN IS
1838
1839 CURSOR get_gl_date IS
1840 SELECT distinct accounting_date acc_date
1841 FROM ap_invoice_lines_all
1842 WHERE invoice_id = p_invoice_id
1843 and NVL(generate_dists,'N') <> 'D';
1844
1845 CURSOR get_inv_source IS
1846 SELECT upper(nvl(source, 'X')), org_id
1847 FROM ap_invoices_all
1848 WHERE invoice_id = p_invoice_id;
1849
1850 l_source ap_invoices_all.source%TYPE;
1851 l_org_id ap_invoices_all.org_id%TYPE;
1852
1853 BEGIN
1854 OPEN get_inv_source;
1855 FETCH get_inv_source INTO l_source, l_org_id;
1856 CLOSE get_inv_source;
1857
1858 IF l_source <> 'RECURRING INVOICE' THEN
1859 return true;
1860 END IF;
1861
1862 FOR gl_date IN get_gl_date LOOP
1863 IF ap_utilities_pkg.period_status(gl_date.acc_date) ='N' then
1864 return false;
1865 END IF;
1866 END LOOP;
1867 return true;
1868 END validate_period;
1869
1870
1871 /*=============================================================================
1872 | PROCEDURE APPROVAL_INIT
1873 |
1874 | Procedure called by APPROVAL to retrieve system variables to be used by
1875 | the APPROVAL program
1876 |
1877 | PROGRAM FLOW
1878 | 1. Retrieve system parameters
1879 | 2. Determine if accounting method is Cash Only
1880 | 3. Retrieve profile option user_id
1881 | 4. Set approval system user_id value
1882 | 5. Retrieve system tolerances
1883 *============================================================================*/
1884
1885 PROCEDURE Approval_Init(
1886 p_org_id IN NUMBER,
1887 p_invoice_id IN NUMBER,
1888 p_invoice_type IN VARCHAR2 DEFAULT NULL,
1889 p_tolerance_id IN NUMBER,
1890 p_services_tolerance_id IN NUMBER,
1891 p_conc_flag IN VARCHAR2,
1892 p_set_of_books_id IN OUT NOCOPY NUMBER,
1893 p_recalc_pay_sched_flag IN OUT NOCOPY VARCHAR2,
1894 p_sys_xrate_gain_ccid IN OUT NOCOPY NUMBER,
1895 p_sys_xrate_loss_ccid IN OUT NOCOPY NUMBER,
1896 p_base_currency_code IN OUT NOCOPY VARCHAR2,
1897 p_inv_enc_type_id IN OUT NOCOPY NUMBER,
1898 p_purch_enc_type_id IN OUT NOCOPY NUMBER,
1899 p_gl_date_from_receipt_flag IN OUT NOCOPY VARCHAR2,
1900 p_receipt_acc_days IN OUT NOCOPY NUMBER,
1901 p_system_user IN OUT NOCOPY NUMBER,
1902 p_user_id IN OUT NOCOPY NUMBER,
1903 p_goods_ship_amt_tolerance IN OUT NOCOPY NUMBER,
1904 p_goods_rate_amt_tolerance IN OUT NOCOPY NUMBER,
1905 p_goods_total_amt_tolerance IN OUT NOCOPY NUMBER,
1906 p_services_ship_amt_tolerance IN OUT NOCOPY NUMBER,
1907 p_services_rate_amt_tolerance IN OUT NOCOPY NUMBER,
1908 p_services_total_amt_tolerance IN OUT NOCOPY NUMBER,
1909 p_price_tolerance IN OUT NOCOPY NUMBER,
1910 p_qty_tolerance IN OUT NOCOPY NUMBER,
1911 p_qty_rec_tolerance IN OUT NOCOPY NUMBER,
1912 p_amt_tolerance IN OUT NOCOPY NUMBER,
1913 p_amt_rec_tolerance IN OUT NOCOPY NUMBER,
1914 p_max_qty_ord_tolerance IN OUT NOCOPY NUMBER,
1915 p_max_qty_rec_tolerance IN OUT NOCOPY NUMBER,
1916 p_max_amt_ord_tolerance IN OUT NOCOPY NUMBER,
1917 p_max_amt_rec_tolerance IN OUT NOCOPY NUMBER,
1918 p_invoice_line_count OUT NOCOPY NUMBER, --Bug 6684139
1919 p_calling_sequence IN VARCHAR2) IS
1920
1921 l_debug_loc VARCHAR2(30) := 'Approval_Init';
1922 l_curr_calling_sequence VARCHAR2(2000);
1923 l_debug_info VARCHAR2(1000);
1924 BEGIN
1925
1926 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
1927 p_calling_sequence;
1928
1929 -- Select stmt added for bug 6684139
1930 SELECT count(*)
1931 into p_invoice_line_count
1932 from ap_invoice_lines
1933 where invoice_id = p_invoice_id;
1934
1935 IF nvl(p_conc_flag, 'N') <> 'Y' THEN
1936
1937 l_debug_info := 'Retrieving system parameters for validation';
1938 Print_Debug(l_debug_loc, l_debug_info);
1939
1940 SELECT nvl(sp.set_of_books_id, -1),
1941 nvl(recalc_pay_schedule_flag, 'N'),
1942 nvl(sp.rate_var_gain_ccid, -1),
1943 nvl(sp.rate_var_loss_ccid, -1),
1944 nvl(sp.base_currency_code, 'USD'),
1945 nvl(fp.inv_encumbrance_type_id, -1),
1946 nvl(fp.purch_encumbrance_type_id, -1),
1947 nvl(sp.receipt_acceptance_days, 0),
1948 nvl(gl_date_from_receipt_flag, 'S')
1949 INTO p_set_of_books_id,
1950 p_recalc_pay_sched_flag,
1951 p_sys_xrate_gain_ccid,
1952 p_sys_xrate_loss_ccid,
1953 p_base_currency_code,
1954 p_inv_enc_type_id,
1955 p_purch_enc_type_id,
1956 p_receipt_acc_days,
1957 p_gl_date_from_receipt_flag
1958 FROM ap_system_parameters_all sp,
1959 financials_system_params_all fp,
1960 gl_sets_of_books gls
1961 WHERE sp.org_id = p_org_id
1962 AND fp.org_id = sp.org_id
1963 AND sp.set_of_books_id = gls.set_of_books_id;
1964
1965 ELSE
1966
1967 l_debug_info := 'Set Options from Cache';
1968 Print_Debug (l_debug_loc, l_debug_info);
1969
1970 p_set_of_books_id := AP_APPROVAL_PKG.G_Options_Table(p_org_id).set_of_books_id;
1971 p_recalc_pay_sched_flag := AP_APPROVAL_PKG.G_Options_Table(p_org_id).recalc_pay_schedule_flag;
1972 p_sys_xrate_gain_ccid := AP_APPROVAL_PKG.G_Options_Table(p_org_id).rate_var_gain_ccid;
1973 p_sys_xrate_loss_ccid := AP_APPROVAL_PKG.G_Options_Table(p_org_id).rate_var_loss_ccid;
1974 p_base_currency_code := AP_APPROVAL_PKG.G_Options_Table(p_org_id).base_currency_code;
1975 p_inv_enc_type_id := AP_APPROVAL_PKG.G_Options_Table(p_org_id).inv_encumbrance_type_id;
1976 p_purch_enc_type_id := AP_APPROVAL_PKG.G_Options_Table(p_org_id).purch_encumbrance_type_id;
1977 p_receipt_acc_days := AP_APPROVAL_PKG.G_Options_Table(p_org_id).receipt_acceptance_days;
1978 p_gl_date_from_receipt_flag := AP_APPROVAL_PKG.G_Options_Table(p_org_id).gl_date_from_receipt_flag;
1979
1980 END IF;
1981
1982 p_system_user := 5;
1983 p_user_id := FND_GLOBAL.user_id;
1984
1985 l_debug_info := 'Retrieving tolerances for validation';
1986 Print_Debug(l_debug_loc, l_debug_info);
1987
1988 IF p_invoice_type <> 'PAYMENT REQUEST' THEN
1989
1990 IF p_tolerance_id IS NOT NULL THEN
1991 p_price_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).price_tolerance;
1992 p_qty_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).quantity_tolerance;
1993 p_qty_rec_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).qty_received_tolerance;
1994 p_max_qty_ord_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).max_qty_ord_tolerance;
1995 p_max_qty_rec_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).max_qty_rec_tolerance;
1996 p_goods_ship_amt_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).ship_amt_tolerance;
1997 p_goods_rate_amt_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).rate_amt_tolerance;
1998 p_goods_total_amt_tolerance := AP_APPROVAL_PKG.G_GOODS_TOLERANCES(p_tolerance_id).total_amt_tolerance;
1999 END IF;
2000
2001 IF p_services_tolerance_id IS NOT NULL THEN
2002 p_amt_tolerance := AP_APPROVAL_PKG.G_SERVICES_TOLERANCES(p_services_tolerance_id).amount_tolerance;
2003 p_amt_rec_tolerance := AP_APPROVAL_PKG.G_SERVICES_TOLERANCES(p_services_tolerance_id).amt_received_tolerance;
2004 p_max_amt_ord_tolerance := AP_APPROVAL_PKG.G_SERVICES_TOLERANCES(p_services_tolerance_id).max_amt_ord_tolerance;
2005 p_max_amt_rec_tolerance := AP_APPROVAL_PKG.G_SERVICES_TOLERANCES(p_services_tolerance_id).max_amt_rec_tolerance;
2006 p_services_ship_amt_tolerance := AP_APPROVAL_PKG.G_SERVICES_TOLERANCES(p_services_tolerance_id).ser_ship_amt_tolerance;
2007 p_services_rate_amt_tolerance := AP_APPROVAL_PKG.G_SERVICES_TOLERANCES(p_services_tolerance_id).ser_rate_amt_tolerance;
2008 p_services_total_amt_tolerance := AP_APPROVAL_PKG.G_SERVICES_TOLERANCES(p_services_tolerance_id).ser_total_amt_tolerance;
2009 END IF;
2010
2011 END IF;
2012
2013 EXCEPTION
2014 WHEN OTHERS THEN
2015 IF (SQLCODE <> -20001) THEN
2016 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
2017 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
2018 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
2019 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
2020 END IF;
2021 APP_EXCEPTION.RAISE_EXCEPTION;
2022 END Approval_Init;
2023
2024 /*=============================================================================
2025 | PROCEDURE Inv_Needs_Approving
2026 |
2027 | Function when given an invoice_id and run_option, it returns a boolean
2028 | to indicate whether to approve an invoice or not. Returns FALSE if the
2029 | run_option is 'New' and the invoice doesn't have any unapproved
2030 | distributions.
2031 |
2032 | PARAMETERS
2033 | p_invoice_id
2034 | p_run_option
2035 | p_calling_sequence
2036 |
2037 | PROGRAM FLOW
2038 |
2039 | KNOWN ISSUES
2040 |
2041 | NOTES:
2042 |
2043 | MODIFICATION HISTORY
2044 | Date Author Description of Change
2045 |
2046 *============================================================================*/
2047
2048 FUNCTION Inv_Needs_Approving(
2049 p_invoice_id IN NUMBER,
2050 p_run_option IN VARCHAR2,
2051 p_calling_sequence IN VARCHAR2) RETURN BOOLEAN
2052 IS
2053
2054 l_unapproved_dist_exists NUMBER;
2055 l_undistributed_line_exists VARCHAR2(30);
2056 l_debug_loc VARCHAR2(30) := 'Inv_Needs_Approving';
2057 l_curr_calling_sequence VARCHAR2(2000);
2058 l_debug_info VARCHAR2(1000);
2059 l_api_name CONSTANT VARCHAR2(200) := 'Approval_Init';
2060 BEGIN
2061
2062 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
2063 p_calling_sequence;
2064
2065 l_undistributed_line_exists := 'N';
2066
2067 IF (p_run_option = 'New') THEN
2068
2069 SELECT count(*)
2070 INTO l_unapproved_dist_exists
2071 FROM ap_invoice_distributions_all
2072 WHERE invoice_id = p_invoice_id
2073 AND (nvl(match_status_flag, 'N')) = 'N'
2074 AND rownum = 1;
2075
2076 --bugfix:4745464
2077 BEGIN
2078 SELECT 'Y'
2079 INTO l_undistributed_line_exists
2080 FROM ap_invoice_lines_all L
2081 WHERE L.invoice_id = p_invoice_id
2082 AND L.amount <>
2083 (SELECT NVL(SUM(NVL(aid.amount,0)),0)
2084 FROM ap_invoice_distributions_all aid
2085 WHERE aid.invoice_id = L.invoice_id
2086 AND aid.invoice_line_number = L.line_number);
2087 END;
2088
2089 IF (l_unapproved_dist_exists = 0 AND l_undistributed_line_exists = 'N') THEN
2090
2091 l_debug_info := 'Skip Validation: Invoice_Id: ' || p_invoice_id;
2092 Print_Debug(l_api_name, l_debug_info);
2093
2094 return(FALSE);
2095 END IF;
2096 END IF;
2097
2098 return(TRUE);
2099
2100 EXCEPTION
2101 WHEN OTHERS THEN
2102 IF (SQLCODE <> -20001) THEN
2103 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
2104 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
2105 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
2106 FND_MESSAGE.SET_TOKEN('PARAMETERS',
2107 'Invoice_id = '|| to_char(p_invoice_id)
2108 || 'Run Option = ' || p_run_option);
2109 END IF;
2110 APP_EXCEPTION.RAISE_EXCEPTION;
2111 END Inv_Needs_Approving;
2112
2113 /*=============================================================================
2114 | PROCEDURE Update_Inv_Dists_To_Selected
2115 |
2116 | Procedure given the invoice_id, invoice line number and run option,
2117 | updates the invoice distributions to be selected for approval depending
2118 | on the run option.
2119 | If the run_option is 'New' then we only select distributions that have
2120 | never been processed by approval, otherwise we select all distributions
2121 | that have not successfully been approved.
2122 |
2123 | PARAMETERS
2124 | p_invoice_id - invoice id
2125 | p_line_number - invoice line number
2126 | p_run_option
2127 | p_calling_sequence
2128 |
2129 | KNOWN ISSUES:
2130 |
2131 | NOTES:
2132 |
2133 | MODIFICATION HISTORY
2134 | Date Author Description of Change
2135 |
2136 *============================================================================*/
2137
2138 PROCEDURE Update_Inv_Dists_To_Selected(
2139 p_invoice_id IN NUMBER,
2140 p_line_number IN NUMBER,
2141 p_run_option IN VARCHAR2,
2142 p_calling_sequence IN VARCHAR2) IS
2143
2144 l_debug_loc VARCHAR2(30) := 'Update_Inv_Dists_To_Selected';
2145 l_curr_calling_sequence VARCHAR2(2000);
2146 l_debug_info VARCHAR2(1000);
2147 BEGIN
2148
2149 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
2150 p_calling_sequence;
2151
2152 IF (p_run_option = 'New') THEN
2153
2154 l_debug_info := 'Run Option: New: Set new distribution flag to S';
2155 Print_Debug (l_debug_loc,l_debug_info);
2156
2157 UPDATE ap_invoice_distributions_all D
2158 SET match_status_flag = 'S'
2159 WHERE NVL(match_status_flag, 'N') = 'N'
2160 AND D.invoice_id = p_invoice_id
2161 AND D.invoice_line_number = p_line_number;
2162
2163
2164 --Bug 6963908
2165 UPDATE ap_self_assessed_tax_dist_all D
2166 SET match_status_flag = 'S'
2167 WHERE NVL(match_status_flag, 'N') = 'N'
2168 AND D.invoice_id = p_invoice_id
2169 AND D.invoice_line_number = p_line_number;
2170 --Bug 6963908
2171
2172 ELSE
2173
2174 l_debug_info := 'Run Option: All: Set new distribution flag to S';
2175 Print_Debug (l_debug_loc,l_debug_info);
2176
2177 UPDATE ap_invoice_distributions_all D
2178 SET match_status_flag = 'S'
2179 WHERE NVL(match_status_flag, '!') <> 'A'
2180 AND D.invoice_id = p_invoice_id;
2181
2182 --Bug 6963908
2183 UPDATE ap_self_assessed_tax_dist_all D
2184 SET match_status_flag = 'S'
2185 WHERE NVL(match_status_flag, '!') <> 'A'
2186 AND D.invoice_id = p_invoice_id;
2187 --Bug 6963908
2188
2189 END IF;
2190
2191 EXCEPTION
2192 WHEN OTHERS THEN
2193 IF (SQLCODE <> -20001) THEN
2194 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
2195 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
2196 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
2197 FND_MESSAGE.SET_TOKEN('PARAMETERS',
2198 'Invoice_id = '|| to_char(p_invoice_id)
2199 || 'Run Option = ' || p_run_option);
2200 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
2201 END IF;
2202 APP_EXCEPTION.RAISE_EXCEPTION;
2203 END Update_Inv_Dists_To_Selected;
2204
2205
2206 /*=============================================================================
2207 | PUBLIC PROCEDURE Check_Insufficient_Line_Data
2208 |
2209 | DESCRIPTION:
2210 | Check all the line information before Distribution generated
2211 | PARAMETERS
2212 | p_inv_line_rec
2213 | p_system_user
2214 | p_holds
2215 | p_holds_count
2216 | p_release_count
2217 | p_insufficent_data_exist - boolean indicates if a hold is existing
2218 | p_calling_sequence
2219 |
2220 | PROGRAM FLOW
2221 | Check for Sufficient Line Data in a priliminary level
2222 | KNOWN ISSUES:
2223 |
2224 | NOTES:
2225 |
2226 | MODIFICATION HISTORY
2227 | Date Author Description of Change
2228 |
2229 *============================================================================*/
2230
2231 PROCEDURE Check_Insufficient_Line_Data(
2232 p_inv_line_rec IN AP_INVOICES_PKG.r_invoice_line_rec,
2233 p_system_user IN NUMBER,
2234 p_holds IN OUT NOCOPY HOLDSARRAY,
2235 p_holds_count IN OUT NOCOPY COUNTARRAY,
2236 p_release_count IN OUT NOCOPY COUNTARRAY,
2237 p_insufficient_data_exist OUT NOCOPY BOOLEAN,
2238 p_calling_mode IN VARCHAR2,
2239 p_calling_sequence IN VARCHAR2)
2240 IS
2241
2242 CURSOR Alloc_Rule_Cur IS
2243 SELECT ALOC.rule_type
2244 FROM ap_invoice_lines AIL,
2245 ap_allocation_rules ALOC
2246 WHERE AIL.invoice_id = p_inv_line_rec.invoice_id
2247 AND AIL.line_number = p_inv_line_rec.line_number
2248 AND AIL.invoice_id = ALOC.invoice_id
2249 AND AIL.line_number = ALOC.chrg_invoice_line_number(+);
2250
2251 l_debug_loc VARCHAR2(30) := 'Check_Insufficient_Line_Data';
2252 l_curr_calling_sequence VARCHAR2(2000);
2253 l_debug_info VARCHAR2(1000);
2254 l_ret_val BOOLEAN;
2255 l_should_have_hold VARCHAR2(1) := 'N';
2256 l_alloc_rule_type ap_allocation_rules.rule_type%TYPE;
2257 l_product_registered BOOLEAN;
2258 l_dummy VARCHAR2(100);
2259
2260 BEGIN
2261
2262 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||
2263 '<-'||p_calling_sequence;
2264
2265 p_insufficient_data_exist := FALSE;
2266
2267 OPEN Alloc_Rule_Cur;
2268 FETCH Alloc_Rule_Cur INTO l_alloc_rule_type;
2269 IF (Alloc_Rule_Cur%NOTFOUND) THEN
2270 l_alloc_rule_type := NULL;
2271 END IF;
2272 CLOSE Alloc_Rule_Cur;
2273
2274 IF (Is_Product_Registered(
2275 P_application_id => p_inv_line_rec.application_id,
2276 X_registration_api => l_dummy,
2277 X_registration_view => l_dummy,
2278 P_calling_sequence => l_curr_calling_sequence)) THEN
2279 l_product_registered := TRUE;
2280 ELSE
2281 l_product_registered := FALSE;
2282 END IF;
2283
2284 ----
2285 l_debug_info := 'processing info for line number: '||p_inv_line_rec.line_number
2286 ||' l_alloc_rule_type: '||l_alloc_rule_type
2287 || ' project_id: '||p_inv_line_rec.project_id
2288 ||' generate_dists: '||p_inv_line_rec.generate_dists;
2289 Print_Debug(l_debug_loc, l_debug_info);
2290 ----
2291
2292 IF (p_inv_line_rec.generate_dists = 'Y'
2293 and p_inv_line_rec.distribution_set_id IS NULL
2294 and p_inv_line_rec.default_dist_ccid IS NULL
2295 and l_alloc_rule_type IS NULL
2296 and p_inv_line_rec.project_id IS NULL
2297 and NOT l_product_registered) THEN
2298
2299 l_debug_info := 'should have hold for line: '||p_inv_line_rec.line_number;
2300 Print_Debug(l_debug_loc, l_debug_info);
2301
2302 l_should_have_hold := 'Y';
2303 p_insufficient_data_exist := TRUE;
2304 END IF;
2305
2306 IF (p_calling_mode = 'PERMANENT_DISTRIBUTIONS') THEN
2307 Process_Inv_Hold_Status(
2308 p_inv_line_rec.invoice_id,
2309 null,
2310 null,
2311 'INSUFFICIENT LINE INFO',
2312 l_should_have_hold,
2313 null,
2314 p_system_user,
2315 p_holds,
2316 p_holds_count,
2317 p_release_count,
2318 l_curr_calling_sequence);
2319 END IF;
2320
2321 EXCEPTION
2322 WHEN OTHERS THEN
2323 IF (SQLCODE <> -20001) THEN
2324 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
2325 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
2326 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
2327 FND_MESSAGE.SET_TOKEN('PARAMETERS',
2328 'Invoice_id = '|| to_char(p_inv_line_rec.invoice_id));
2329 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
2330 END IF;
2331
2332 IF ( Alloc_Rule_Cur%ISOPEN ) THEN
2333 CLOSE Alloc_Rule_Cur;
2334 END IF;
2335
2336 APP_EXCEPTION.RAISE_EXCEPTION;
2337 END Check_Insufficient_Line_Data;
2338
2339
2340 /*=============================================================================
2341 | PUBLIC PROCEDURE Execute_Dist_Generation_Check
2342 |
2343 | DESCRIPTION:
2344 | Call API to generate Distribution from distribution set or
2345 | generate distribution based on allocation/default account
2346 | information. Handle the error code detected during dist.
2347 | generation. Process/Release corresponding Hold.
2348 | PARAMETERS
2349 | p_batch_id
2350 | p_invoice_date
2351 | p_vendor_id
2352 | p_invoice_currency
2353 | p_exchange_rate
2354 | p_exchange_rate_type
2355 | p_exchange_date
2356 | p_inv_line_rec
2357 | p_system_user
2358 | p_holds
2359 | p_holds_count
2360 | p_release_count
2361 | p_curr_calling_sequence
2362 |
2363 | PROGRAM FLOW
2364 |
2365 | KNOWN ISSUES
2366 |
2367 | NOTES:
2368 |
2369 | MODIFICATION HISTORY
2370 | Date Author Description of Change
2371 |
2372 *============================================================================*/
2373
2374 FUNCTION Execute_Dist_Generation_Check(
2375 p_batch_id IN NUMBER,
2376 p_invoice_date IN DATE,
2377 p_vendor_id IN NUMBER,
2378 p_invoice_currency IN VARCHAR2,
2379 p_exchange_rate IN NUMBER,
2380 p_exchange_rate_type IN VARCHAR2,
2381 p_exchange_date IN DATE,
2382 p_inv_line_rec IN AP_INVOICES_PKG.r_invoice_line_rec,
2383 p_system_user IN NUMBER,
2384 p_holds IN OUT NOCOPY HOLDSARRAY,
2385 p_holds_count IN OUT NOCOPY COUNTARRAY,
2386 p_release_count IN OUT NOCOPY COUNTARRAY,
2387 p_generate_permanent IN VARCHAR2,
2388 p_calling_mode IN VARCHAR2 ,
2389 p_error_code OUT NOCOPY VARCHAR2,
2390 p_curr_calling_sequence IN VARCHAR2) RETURN BOOLEAN
2391 IS
2392
2393 CURSOR Alloc_Rule_Cur IS
2394 SELECT ALOC.rule_type
2395 FROM ap_invoice_lines AIL,
2396 ap_allocation_rules ALOC
2397 WHERE AIL.invoice_id = p_inv_line_rec.invoice_id
2398 AND AIL.line_number = p_inv_line_rec.line_number
2399 AND AIL.invoice_id = ALOC.invoice_id
2400 AND AIL.line_number = ALOC.chrg_invoice_line_number(+);
2401
2402 l_debug_loc VARCHAR2(30) := 'Execute_Dist_Generation_Check';
2403 l_curr_calling_sequence VARCHAR2(2000);
2404 l_debug_info VARCHAR2(2000);
2405 l_alloc_rule_type ap_allocation_rules.rule_type%TYPE;
2406
2407 l_debug_context VARCHAR2(2000);
2408 l_msg_application VARCHAR2(25);
2409 l_error_code VARCHAR2(4000);
2410 l_msg_data VARCHAR2(30);
2411 l_hold_code VARCHAR2(30);
2412 l_success BOOLEAN := FALSE;
2413 l_gen_dist_hold_exists VARCHAR2(1) := 'N';
2414
2415 --Bugfix:4673607
2416 l_registration_api VARCHAR2(1000);
2417 l_registration_view VARCHAR2(1000);
2418 l_reference_key1 ap_invoice_lines_all.reference_key1%type;
2419 l_reference_key2 ap_invoice_lines_all.reference_key2%type;
2420 l_reference_key3 ap_invoice_lines_all.reference_key3%type;
2421 l_reference_key4 ap_invoice_lines_all.reference_key4%type;
2422 l_reference_key5 ap_invoice_lines_all.reference_key5%type;
2423 l_err varchar2(2000);
2424
2425 BEGIN
2426
2427 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
2428 p_curr_calling_sequence;
2429
2430 ----------------------------------------------------------------------
2431 l_debug_info := 'Input Parameters: '||' invoice id: ' ||p_inv_line_rec.invoice_id
2432 ||' line_number: ' ||p_inv_line_rec.line_number
2433 ||' generate_dists: ' ||p_inv_line_rec.generate_dists
2434 ||' distribution_set_id: '||p_inv_line_rec.distribution_set_id
2435 ||' accouting_date: ' ||p_inv_line_rec.accounting_date
2436 ||' period_name: ' ||p_inv_line_rec.period_name;
2437 Print_Debug(l_debug_loc, l_debug_info);
2438 ----------------------------------------------------------------------
2439
2440 IF (Is_Product_Registered(P_application_id => p_inv_line_rec.application_id,
2441 X_registration_api => l_registration_api,
2442 X_registration_view => l_registration_view,
2443 P_calling_sequence => l_curr_calling_sequence)) THEN
2444
2445 ----------------------------------------------------------------------
2446 l_debug_info := 'Call the api that will create the distributions '||
2447 'based on the other products registered view/api';
2448 Print_Debug(l_debug_loc, l_debug_info);
2449 ----------------------------------------------------------------------
2450
2451 l_success := Gen_Dists_From_Registration(
2452 P_Batch_Id => p_batch_id,
2453 P_Invoice_Line_Rec => p_inv_line_rec,
2454 P_Registration_Api => l_registration_api,
2455 P_Registration_View => l_registration_view,
2456 P_Generate_Permanent => p_generate_permanent,
2457 X_Error_Code => l_error_code,
2458 P_Calling_Sequence => l_curr_calling_sequence);
2459
2460
2461 ELSIF ( p_inv_line_rec.distribution_set_id is not null) THEN
2462
2463 /*-----------------------------------------------------------------+
2464 | CASE 1 - Generate distribution from distribution set |
2465 +-----------------------------------------------------------------*/
2466
2467 l_debug_info := 'Execute_Dist_Generation_Check - insert from dist set';
2468 Print_Debug(l_debug_loc, l_debug_info);
2469
2470 l_success := AP_INVOICE_LINES_PKG.Insert_From_Dist_Set(
2471 X_invoice_id => p_inv_line_rec.invoice_id,
2472 X_line_number => p_inv_line_rec.line_number,
2473 X_GL_Date => p_inv_line_rec.accounting_date,
2474 X_Period_Name => p_inv_line_rec.period_name,
2475 X_Skeleton_Allowed => 'Y', -- Bug 4928285
2476 X_Generate_Dists => p_inv_line_rec.generate_dists,
2477 X_Generate_Permanent => p_generate_permanent,
2478 X_Error_Code => l_error_code,
2479 X_Debug_Info => l_debug_info,
2480 X_Debug_Context => l_debug_context,
2481 X_Msg_Application => l_msg_application,
2482 X_Msg_Data => l_msg_data,
2483 X_calling_sequence => l_curr_calling_sequence);
2484
2485 IF ( NOT l_success ) THEN
2486
2487 IF ( l_error_code is not null ) THEN
2488
2489 IF (p_calling_mode = 'PERMANENT_DISTRIBUTIONS') THEN
2490
2491 CASE l_error_code
2492 WHEN 'AP_VEN_DIST_SET_INVALID' THEN
2493 l_hold_code := 'DISTRIBUTION SET INACTIVE';
2494 WHEN 'AP_CANT_USE_SKELETON_DIST_SET' THEN
2495 l_hold_code := 'SKELETON DISTRIBUTION SET';
2496 WHEN 'AP_CANNOT_OVERLAY' THEN
2497 l_hold_code := 'CANNOT OVERLAY ACCOUNT';
2498 WHEN 'AP_INVALID_CCID' THEN
2499 l_hold_code := 'INVALID DEFAULT ACCOUNT';
2500 ELSE
2501 l_hold_code := null;
2502 END CASE;
2503
2504 ELSIF (p_calling_mode = 'CANDIDATE_DISTRIBUTIONS') THEN
2505
2506 p_error_code := l_error_code;
2507
2508 END IF;
2509
2510 l_debug_info := 'Execute_Dist_Generation_Check: Error Code: ' || l_error_code;
2511 Print_Debug(l_debug_loc, l_debug_info);
2512
2513 ELSE
2514
2515 IF (p_calling_mode = 'CANDIDATE_DISTRIBUTIONS') THEN
2516 p_error_code := l_debug_info;
2517
2518 END IF;
2519
2520 END IF; /*l_error_code is not null*/
2521
2522 END IF; -- end of check l_success
2523
2524 ELSE
2525
2526 /*-----------------------------------------------------------------+
2527 | CASE 2 - Generate distribution without distribution set info |
2528 +-----------------------------------------------------------------*/
2529
2530 OPEN Alloc_Rule_Cur;
2531 FETCH Alloc_Rule_Cur INTO l_alloc_rule_type;
2532 IF (Alloc_Rule_Cur%NOTFOUND) THEN
2533 l_alloc_rule_type := NULL;
2534 END IF;
2535 CLOSE Alloc_Rule_Cur;
2536
2537 IF ( p_inv_line_rec.line_type_lookup_code in ('FREIGHT', 'MISCELLANEOUS' ) and
2538 l_alloc_rule_type is not null ) THEN
2539
2540 /*-----------------------------------------------------------------+
2541 | CASE 2.1 - Generate distribution for charge line if there is an |
2542 | allocation rule |
2543 +-----------------------------------------------------------------*/
2544
2545 l_debug_info := 'Execute_Dist_Generation_Check - charge line with an allocation rule';
2546 Print_Debug(l_debug_loc, l_debug_info);
2547
2548 l_success := AP_INVOICE_DISTRIBUTIONS_PKG.Insert_Charge_From_Alloc(
2549 X_invoice_id => p_inv_line_rec.invoice_id,
2550 X_line_number => p_inv_line_rec.line_number,
2551 X_Generate_Permanent => p_generate_permanent,
2552 X_Validate_Info => TRUE,
2553 X_Error_Code => l_error_code,
2554 X_Debug_Info => l_debug_info,
2555 X_Debug_Context => l_debug_context,
2556 X_Msg_Application => l_msg_application,
2557 X_Msg_Data => l_msg_data,
2558 X_Calling_Sequence => l_curr_calling_sequence );
2559
2560 IF ( NOT l_success ) THEN
2561 IF ( l_error_code is not null ) THEN
2562
2563 IF (p_calling_mode = 'PERMANENT_DISTRIBUTIONS') THEN
2564 IF ( l_error_code IN ( 'AP_NO_ALLOCATION_RULE_FOUND',
2565 'AP_ALLOCATION_ALREADY_EXECUTED',
2566 'AP_NON_FULL_INVOICE',
2567 'AP_UNDISTRIBUTED_LINE_EXISTS',
2568 'AP_IMPROPER_LINE_IN_ALLOC_RULE',
2569 'AP_CANNOT_READ_EXP_DATE',
2570 'AP_INVALID_ACCOUNT',
2571 'AP_CANNOT_OVERLAY',
2572 'AP_NO_OPEN_PERIOD',
2573 'AP_GL_DATE_PA_NOT_OPEN' ) ) THEN
2574 l_hold_code := 'CANNOT EXECUTE ALLOCATION';
2575 ELSE
2576 l_hold_code := null;
2577 END IF;
2578
2579 ELSIF (p_calling_mode = 'CANDIDATE_DISTRIBUTIONS') THEN
2580 p_error_code := l_error_code;
2581 END IF;
2582
2583 l_debug_info := 'Execute_Dist_Generation_Check - ' ||
2584 'Insert_Charge_From_Alloc error ' || l_error_code;
2585 Print_Debug (l_debug_loc, l_debug_info);
2586
2587 END IF; -- end of check l_error_code
2588 END IF; -- end of check l_success
2589
2590 ELSE
2591
2592 /*-----------------------------------------------------------------+
2593 | CASE 2.2 - Generate distribution for non-match item line or no |
2594 | allocation rule charge line |
2595 +-----------------------------------------------------------------*/
2596
2597 l_debug_info := 'Execute_Dist_Generation_Check - Insert_Single_Dist_From_Line';
2598 Print_Debug(l_debug_loc, l_debug_info);
2599
2600 l_success := AP_INVOICE_DISTRIBUTIONS_PKG.Insert_Single_Dist_From_Line(
2601 X_batch_id => p_batch_id,
2602 X_invoice_id => p_inv_line_rec.invoice_id,
2603 X_invoice_date => p_invoice_date,
2604 X_vendor_id => p_vendor_id,
2605 X_invoice_currency => p_invoice_currency,
2606 X_exchange_rate => p_exchange_rate,
2607 X_exchange_rate_type => p_exchange_rate_type,
2608 X_exchange_date => p_exchange_date,
2609 X_line_number => p_inv_line_rec.line_number,
2610 X_invoice_lines_rec => NULL,
2611 X_line_source => 'VALIDATION',
2612 X_Generate_Permanent => p_generate_permanent,
2613 X_Validate_Info => TRUE,
2614 X_Error_Code => l_error_code,
2615 X_Debug_Info => l_debug_info,
2616 X_Debug_Context => l_debug_context,
2617 X_Msg_Application => l_msg_application,
2618 X_Msg_Data => l_msg_data,
2619 X_Calling_Sequence => l_curr_calling_sequence);
2620
2621 IF ( NOT l_success ) THEN
2622 IF ( l_error_code is not null ) THEN
2623
2624 IF (p_calling_mode = 'PERMANENT_DISTRIBUTIONS') THEN
2625
2626 CASE l_error_code
2627 WHEN 'INVALID_ACCOUNT' THEN
2628 l_hold_code := 'INVALID DEFAULT ACCT';
2629 WHEN 'CANNOT_OVERLAY' THEN
2630 l_hold_code := 'CANNOT OVERLAY ACCOUNT';
2631 WHEN 'NOT_OPEN_PERIOD' THEN
2632 -- attention: need to confirm later
2633 l_hold_code := 'PERIOD CLOSED';
2634 WHEN 'GL_DATE_PA_NOT_OPEN' THEN
2635 l_hold_code := 'PROJECT GL DATE CLOSED';
2636 ELSE
2637 l_hold_code := null;
2638 END CASE;
2639
2640 ELSIF (p_calling_mode = 'CANDIDATE_DISTRIBUTIONS') THEN
2641
2642 p_error_code := l_error_code;
2643
2644 END IF; /*p_calling_mode = 'PERMANENT_DISTRIBUTIONS' */
2645
2646 l_debug_info := 'Execute_Dist_Generation_Check-insert from dist'
2647 || ' set has error - ' || l_error_code ;
2648 Print_Debug(l_debug_loc, l_debug_info);
2649
2650 END IF; -- end of check l_error_code
2651 END IF; -- end of check l_success
2652 END IF; -- end of p_inv_line_rec.line_type_lookup_code check
2653 END IF; -- end of p_inv_line_rec.distribution_set_id check
2654
2655 /*-----------------------------------------------------------------+
2656 | To process the error code and the put hold if necessary |
2657 +-----------------------------------------------------------------*/
2658
2659 IF ( NOT l_success and l_hold_code is not null ) THEN
2660 l_gen_dist_hold_exists := 'Y';
2661
2662 l_debug_info := 'Execute_Dist_Generation_Check - Process hold code';
2663 Print_Debug(l_debug_loc, l_debug_info);
2664
2665 --BUGFIX:5685469
2666 --Need to release the holds (related to distribution generation) placed in earlier calls of
2667 --validation
2668 ELSIF (p_calling_mode = 'PERMANENT_DISTRIBUTIONS' AND l_success AND l_hold_code IS NULL) THEN
2669
2670 BEGIN
2671
2672 l_debug_info := 'Release any holds related to distribution generation which were placed earlier';
2673 Print_Debug(l_debug_loc, l_debug_info);
2674
2675 IF ( p_inv_line_rec.distribution_set_id is not null) THEN
2676
2677 SELECT hold_lookup_code
2678 INTO l_hold_code
2679 FROM ap_holds_all
2680 WHERE invoice_id = p_inv_line_rec.invoice_id
2681 AND hold_lookup_code in ('DISTRIBUTION SET INACTIVE','SKELETON DISTRIBUTION SET',
2682 'CANNOT OVERLAY ACCOUNT','INVALID DEFAULT ACCOUNT')
2683 AND release_lookup_code IS NULL;
2684
2685 ELSIF ( p_inv_line_rec.line_type_lookup_code in ('FREIGHT', 'MISCELLANEOUS' ) and
2686 l_alloc_rule_type is not null ) THEN
2687
2688 SELECT hold_lookup_code
2689 INTO l_hold_code
2690 FROM ap_holds_all
2691 WHERE invoice_id = p_inv_line_rec.invoice_id
2692 AND hold_lookup_code = 'CANNOT EXECUTE ALLOCATION'
2693 AND release_lookup_code IS NULL;
2694
2695 ELSE
2696
2697 SELECT hold_lookup_code
2698 INTO l_hold_code
2699 FROM ap_holds_all
2700 WHERE invoice_id = p_inv_line_rec.invoice_id
2701 AND hold_lookup_code in ('CANNOT OVERLAY ACCOUNT','INVALID DEFAULT ACCOUNT',
2702 'PERIOD CLOSED','PROJECT GL DATE CLOSED')
2703 AND release_lookup_code IS NULL;
2704
2705 END IF;
2706
2707 EXCEPTION WHEN OTHERS THEN
2708 /* l_err := sqlerrm;
2709 l_debug_info := 'in others exception '||l_err;
2710 Print_Debug(l_debug_loc, l_debug_info); */
2711
2712 NULL;
2713 END ;
2714
2715 END IF;
2716
2717
2718 --Etax: Validation. Added the IF condition so that when this
2719 --procedure is called from funds_check, we not process any holds.
2720 IF (p_calling_mode = 'PERMANENT_DISTRIBUTIONS') THEN
2721 Process_Inv_Hold_Status(
2722 p_inv_line_rec.invoice_id,
2723 null,
2724 null,
2725 l_hold_code,
2726 l_gen_dist_hold_exists,
2727 null,
2728 p_system_user,
2729 p_holds,
2730 p_holds_count,
2731 p_release_count,
2732 l_curr_calling_sequence);
2733 END IF;
2734
2735 RETURN ( l_success );
2736
2737 EXCEPTION
2738 WHEN OTHERS THEN
2739 IF (SQLCODE <> -20001) THEN
2740 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
2741 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
2742 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
2743 FND_MESSAGE.SET_TOKEN('PARAMETERS',
2744 'Invoice_id = '|| to_char(p_inv_line_rec.invoice_id));
2745 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
2746 END IF;
2747
2748 IF ( Alloc_Rule_Cur%ISOPEN ) THEN
2749 CLOSE Alloc_Rule_Cur;
2750 END IF;
2751 APP_EXCEPTION.RAISE_EXCEPTION;
2752
2753 END Execute_Dist_Generation_Check;
2754
2755
2756 /*=============================================================================
2757 | PROCEDURE EXECUTE_GENERAL_CHECKS
2758 | Procedure that checks general information hold at invoice level and
2759 | invoice distribution level.
2760 |
2761 | PARAMETER
2762 | p_invoice_id
2763 | p_set_of_books_id
2764 | p_base_currency_code
2765 | p_invoice_amount
2766 | p_base_amount
2767 | p_invoice_currency_code
2768 | p_invoice_amount_limit
2769 | p_hold_future_payments_flag
2770 | p_system_user
2771 | p_holds
2772 | p_holds_count
2773 | p_release_count
2774 | p_calling_sequence
2775 |
2776 | PROGRAM FLOW
2777 | 1. Check for Invalid Dist Acct - set or release hold
2778 | 2. Check for PO Required - set or release hold
2779 | 3. Check for Missing Exchange Rate - set or release hold
2780 | 4. Check for UnOpen Future Period - set or release hold
2781 | 5. Check for Invoice Limit and vendor holds - set or release hold
2782 | 6. Check for project information
2783 | 7. Check for AWT manual segment - comment out for now
2784 | 8. Check for Prepayment amount - comment out for now
2785 |
2786 | KNOWN ISSUES:
2787 |
2788 | NOTES:
2789 |
2790 | MODIFICATION HISTORY
2791 | Date Author Description of Change
2792 ============================================================================*/
2793
2794
2795 PROCEDURE Execute_General_Checks(
2796 p_invoice_id IN NUMBER,
2797 p_set_of_books_id IN NUMBER,
2798 p_base_currency_code IN VARCHAR2,
2799 p_invoice_amount IN NUMBER,
2800 p_base_amount IN NUMBER,
2801 p_invoice_currency_code IN VARCHAR2,
2802 p_invoice_amount_limit IN NUMBER,
2803 p_hold_future_payments_flag IN VARCHAR2,
2804 p_system_user IN NUMBER,
2805 p_holds IN OUT NOCOPY HOLDSARRAY,
2806 p_holds_count IN OUT NOCOPY COUNTARRAY,
2807 p_release_count IN OUT NOCOPY COUNTARRAY,
2808 p_calling_sequence IN VARCHAR2) IS
2809
2810 l_debug_loc VARCHAR2(30) := 'Execute_General_Checks';
2811 l_curr_calling_sequence VARCHAR2(2000);
2812 l_debug_info VARCHAR2(1000);
2813
2814 BEGIN
2815
2816 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
2817 p_calling_sequence;
2818
2819 ---------------------------------------------------
2820 l_debug_info := 'Execute_General_Checks: '
2821 ||' invoice id: ' ||p_invoice_id
2822 ||' set of books id: ' ||p_set_of_books_id
2823 ||' base currency code: ' ||p_base_currency_code
2824 ||' invoice amount: ' ||p_invoice_amount
2825 ||' inv base amount: ' ||p_base_amount
2826 ||' inv currency code: ' ||p_invoice_currency_code
2827 ||' invoice amount limit: '||p_invoice_amount_limit
2828 ||' hold future pay flag: '||p_hold_future_payments_flag;
2829
2830 Print_Debug(l_debug_loc, l_debug_info);
2831 ---------------------------------------------------
2832
2833 -- Bug 7158219
2834 ---------------------------------------------------
2835 l_debug_info := 'Check Invalid Distribution Account';
2836 Print_Debug(l_debug_loc, l_debug_info);
2837 ---------------------------------------------------
2838
2839 Check_Invalid_Dist_Acct(
2840 p_invoice_id,
2841 p_system_user,
2842 p_holds,
2843 p_holds_count,
2844 p_release_count,
2845 l_curr_calling_sequence);
2846
2847 ---------------------------------------------------
2848 l_debug_info := 'Check PO Required';
2849 Print_Debug(l_debug_loc, l_debug_info);
2850 ---------------------------------------------------
2851 Check_PO_Required(
2852 p_invoice_id,
2853 p_system_user,
2854 p_holds,
2855 p_holds_count,
2856 p_release_count,
2857 l_curr_calling_sequence);
2858
2859 ---------------------------------------------------
2860 l_debug_info := 'Check for Missing Exchange Rate';
2861 Print_Debug(l_debug_loc, l_debug_info);
2862 ---------------------------------------------------
2863 Check_No_Rate(
2864 p_invoice_id,
2865 p_base_currency_code,
2866 p_system_user,
2867 p_holds,
2868 p_holds_count,
2869 p_release_count,
2870 l_curr_calling_sequence);
2871
2872 ---------------------------------------------------
2873 l_debug_info := 'Check for invoice limit and vendor holds';
2874 Print_Debug(l_debug_loc, l_debug_info);
2875 ---------------------------------------------------
2876 Check_invoice_vendor(
2877 p_invoice_id,
2878 p_base_currency_code,
2879 p_invoice_amount,
2880 p_base_amount,
2881 p_invoice_currency_code,
2882 p_invoice_amount_limit,
2883 p_hold_future_payments_flag,
2884 p_system_user,
2885 p_holds,
2886 p_holds_count,
2887 p_release_count,
2888 l_curr_calling_sequence);
2889
2890 ---------------------------------------------------
2891 l_debug_info := 'Check Prepaid Amount Exceeds Invoice Amount';
2892 Print_Debug(l_debug_loc, l_debug_info);
2893 ---------------------------------------------------
2894 Check_Prepaid_Amount(
2895 p_invoice_id,
2896 p_system_user,
2897 p_holds,
2898 p_holds_count,
2899 p_release_count,
2900 l_curr_calling_sequence);
2901
2902 EXCEPTION
2903 WHEN OTHERS THEN
2904 IF (SQLCODE <> -20001) THEN
2905 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
2906 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
2907 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
2908 FND_MESSAGE.SET_TOKEN('PARAMETERS',
2909 'Invoice_id = '|| to_char(p_invoice_id)
2910 ||', Set of Books Id = '|| to_char(p_set_of_books_id)
2911 ||', Base Currency Code = '|| p_base_currency_code);
2912 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
2913 END IF;
2914 APP_EXCEPTION.RAISE_EXCEPTION;
2915 END Execute_General_Checks;
2916
2917 /*=============================================================================
2918 | PROCEDURE CHECK_INVALID_DIST_ACCT
2919 | Procedure that checks whether an invoice has a distribution with an
2920 | invalid distribution account and places or releases the
2921 | DIST ACCT INVALID hold depending on the condition.
2922 |
2923 | PARAMETER
2924 | p_invoice_id
2925 | p_system_user
2926 | p_holds
2927 | p_holds_count
2928 | p_release_count
2929 | p_calling_sequence
2930 |
2931 | PROGRAM FLOW
2932 |
2933 | KNOWN ISSUES:
2934 |
2935 | NOTES:
2936 |
2937 | MODIFICATION HISTORY
2938 | Date Author Description of Change
2939 ============================================================================*/
2940
2941 PROCEDURE Check_Invalid_Dist_Acct(
2942 p_invoice_id IN NUMBER,
2943 p_system_user IN NUMBER,
2944 p_holds IN OUT NOCOPY HOLDSARRAY,
2945 p_holds_count IN OUT NOCOPY COUNTARRAY,
2946 p_release_count IN OUT NOCOPY COUNTARRAY,
2947 p_calling_sequence IN VARCHAR2) IS
2948
2949 CURSOR Invalid_Dist_Acct_Cur IS
2950 SELECT D.dist_code_combination_id, D.accounting_date
2951 FROM ap_invoice_distributions D
2952 WHERE D.invoice_id = p_invoice_id
2953 AND D.posted_flag||'' in ('N', 'P')
2954 AND ((EXISTS (select 'x'
2955 from gl_code_combinations C
2956 where D.dist_code_combination_id = C.code_combination_id (+)
2957 and (C.code_combination_id is null
2958 or C.detail_posting_allowed_flag = 'N'
2959 or C.start_date_active > D.accounting_date
2960 or C.end_date_active < D.accounting_date
2961 or C.template_id is not null
2962 or C.enabled_flag <> 'Y'
2963 or C.summary_flag <> 'N'
2964 )))
2965 OR (D.dist_code_combination_id = -1))
2966 AND ROWNUM = 1;
2967
2968 CURSOR Alternate_Account_Cur (c_ccid NUMBER, c_acct_date DATE) IS
2969 SELECT 'Y'
2970 FROM gl_code_combinations glcc
2971 WHERE glcc.code_combination_id = c_ccid
2972 AND glcc.alternate_code_combination_id IS NOT NULL
2973 AND EXISTS
2974 (
2975 SELECT 'Account Valid'
2976 FROM gl_code_combinations a
2977 WHERE a.code_combination_id = glcc.alternate_code_combination_id
2978 AND a.enabled_flag = 'Y'
2979 AND a.detail_posting_allowed_flag = 'Y'
2980 AND c_acct_date BETWEEN NVL(a.start_date_active, c_acct_date)
2981 AND NVL(a.end_date_active, c_acct_date)
2982 );
2983
2984 l_ccid AP_INVOICE_DISTRIBUTIONS_ALL.dist_code_combination_id%TYPE;
2985 l_accounting_date AP_INVOICE_DISTRIBUTIONS_ALL.accounting_date%TYPE;
2986 l_alt_exists VARCHAR2(50) := 'N';
2987 l_invalid_dist_ccid_exists VARCHAR2(1) := 'N';
2988 l_test_var VARCHAR2(50);
2989 l_debug_loc VARCHAR2(30) := 'Check_Invalid_Dist';
2990 l_curr_calling_sequence VARCHAR2(2000);
2991 l_debug_info VARCHAR2(1000);
2992
2993 BEGIN
2994
2995 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
2996 p_calling_sequence;
2997
2998 IF (g_debug_mode = 'Y') THEN
2999 l_debug_info := 'General check - check invalid dist account';
3000 AP_Debug_Pkg.Print(g_debug_mode, l_debug_info );
3001 AP_Debug_Pkg.Print(g_debug_mode, 'invoice id :'||
3002 to_char(p_invoice_id) );
3003 END IF;
3004
3005 OPEN Invalid_Dist_Acct_Cur;
3006 LOOP
3007 FETCH Invalid_Dist_Acct_Cur INTO l_ccid, l_accounting_date;
3008 EXIT WHEN Invalid_DIst_Acct_Cur%NOTFOUND;
3009
3010 IF (g_debug_mode = 'Y') THEN
3011 l_debug_info := 'Inside loop of curser - Invalid_Dist_Acct_Cur';
3012 AP_Debug_Pkg.Print(g_debug_mode, l_debug_info );
3013 AP_Debug_Pkg.Print(g_debug_mode, 'invalid dist ccid hold'||
3014 l_invalid_dist_ccid_exists);
3015 END IF;
3016
3017 --
3018 -- Per discussion with Shelley/Enda we will not place a hold
3019 -- when the distribution account is invalid and there is a
3020 -- valid alternate account defined in GL.
3021 -- Create Accounting will use the alternate account to
3022 -- generate the journal entries. The invoice distribution
3023 -- will not be stamped back with the alternate account.
3024 --
3025 OPEN Alternate_Account_Cur(l_ccid, l_accounting_date);
3026 FETCH Alternate_Account_Cur
3027 INTO l_alt_exists;
3028 CLOSE Alternate_Account_Cur;
3029
3030 IF (g_debug_mode = 'Y') THEN
3031 AP_Debug_Pkg.Print(g_debug_mode, 'Alternate Account Exists: '||
3032 l_alt_exists);
3033 END IF;
3034
3035 IF l_alt_exists = 'Y' THEN
3036 l_invalid_dist_ccid_exists := 'N';
3037 ELSE
3038 l_invalid_dist_ccid_exists := 'Y';
3039 END IF;
3040
3041 END LOOP;
3042 CLOSE Invalid_Dist_Acct_Cur;
3043
3044 IF (g_debug_mode = 'Y') THEN
3045 l_debug_info := 'Process DIST ACCT INVALID hold status on invoice';
3046 AP_Debug_Pkg.Print(g_debug_mode, l_debug_info );
3047 END IF;
3048
3049 Process_Inv_Hold_Status(
3050 p_invoice_id,
3051 null,
3052 null,
3053 'DIST ACCT INVALID',
3054 l_invalid_dist_ccid_exists,
3055 null,
3056 p_system_user,
3057 p_holds,
3058 p_holds_count,
3059 p_release_count,
3060 l_curr_calling_sequence);
3061
3062 EXCEPTION
3063 WHEN OTHERS THEN
3064 IF (SQLCODE <> -20001) THEN
3065 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
3066 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
3067 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
3068 FND_MESSAGE.SET_TOKEN('PARAMETERS',
3069 'Invoice_id = '|| to_char(p_invoice_id));
3070 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
3071 END IF;
3072
3073 IF ( Invalid_Dist_Acct_Cur%ISOPEN ) THEN
3074 CLOSE Invalid_Dist_Acct_Cur;
3075 END IF;
3076
3077 APP_EXCEPTION.RAISE_EXCEPTION;
3078 END Check_Invalid_Dist_Acct;
3079
3080 /*=============================================================================
3081 | PROCEDURE CHECK_PO_REQUIRED
3082 | Procedure that checks whether an invoice has a PO REQUIRED
3083 | condition and places or releases the hold depending on the condition
3084 | For those distribution lines which have "pa_additon_flag" = 'T', means
3085 | they are transferred from projects; Payables does not enforce po
3086 | information requirment.
3087 |
3088 | PARAMETER
3089 | p_invoice_id
3090 | p_system_user
3091 | p_holds
3092 | p_holds_count
3093 | p_release_count
3094 | p_calling_sequence
3095 |
3096 | PROGRAM FLOW
3097 |
3098 | KNOWN ISSUES:
3099 |
3100 | NOTES:
3101 |
3102 | MODIFICATION HISTORY
3103 | Date Author Description of Change
3104 ============================================================================*/
3105
3106 PROCEDURE Check_PO_Required(
3107 p_invoice_id IN NUMBER,
3108 p_system_user IN NUMBER,
3109 p_holds IN OUT NOCOPY HOLDSARRAY,
3110 p_holds_count IN OUT NOCOPY COUNTARRAY,
3111 p_release_count IN OUT NOCOPY COUNTARRAY,
3112 p_calling_sequence IN VARCHAR2) IS
3113
3114 CURSOR PO_Required_Cur IS
3115 -- Perf bug 5058995
3116 -- Modify below SQL to go to base tables : AP_INVOICES_ALL,
3117 -- AP_INVOICE_DISTRIBUTIONS_ALL and
3118 -- AP_SUPPLIER_SITES(instead of po_vendor_sites)
3119 /* Added the Hint index(apd AP_INVOICE_DISTRIBUTIONS_U1) for bug#7270053 */
3120 SELECT 'PO REQUIRED'
3121 FROM ap_invoices_all api, ap_supplier_sites pov
3122 WHERE EXISTS (select /*+ index(apd AP_INVOICE_DISTRIBUTIONS_U1) */ 'X'
3123 from ap_invoice_distributions_all apd
3124 where apd.invoice_id = api.invoice_id
3125 and apd.line_type_lookup_code in ( 'ITEM', 'ACCRUAL')
3126 and apd.po_distribution_id is null
3127 and apd.pa_addition_flag <> 'T'
3128 group by apd.dist_code_combination_id
3129 HAVING sum(apd.amount) <> 0)
3130 AND nvl(pov.hold_unmatched_invoices_flag, 'X') = 'Y'
3131 AND api.invoice_type_lookup_code not in ('PREPAYMENT', 'INTEREST')
3132 AND api.vendor_site_id = pov.vendor_site_id
3133 AND api.invoice_id = p_invoice_id;
3134
3135 l_po_required_exists VARCHAR2(1) := 'N';
3136 l_test_var VARCHAR2(30) :='';
3137 l_debug_loc VARCHAR2(30) := 'Check_PO_Required';
3138 l_curr_calling_sequence VARCHAR2(2000);
3139 l_debug_info VARCHAR2(1000);
3140
3141 BEGIN
3142
3143 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
3144 p_calling_sequence;
3145
3146 OPEN PO_Required_Cur;
3147 FETCH PO_Required_Cur INTO l_test_var;
3148 CLOSE PO_Required_Cur;
3149
3150 IF ( l_test_var is not NULL ) THEN
3151 l_po_required_exists := 'Y';
3152
3153 ---------------------------------------------------
3154 l_debug_info := 'PO REQUIRED hold placed. Invoice_ID: '||p_invoice_id;
3155 Print_Debug(l_debug_loc, l_debug_info);
3156 ---------------------------------------------------
3157 END IF;
3158
3159 Process_Inv_Hold_Status(
3160 p_invoice_id,
3161 null,
3162 null,
3163 'PO REQUIRED',
3164 l_po_required_exists,
3165 null,
3166 p_system_user,
3167 p_holds,
3168 p_holds_count,
3169 p_release_count,
3170 l_curr_calling_sequence);
3171
3172 EXCEPTION
3173 WHEN OTHERS THEN
3174 IF (SQLCODE <> -20001) THEN
3175 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
3176 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
3177 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
3178 FND_MESSAGE.SET_TOKEN('PARAMETERS',
3179 'Invoice_id = '|| to_char(p_invoice_id));
3180 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
3181 END IF;
3182 IF ( PO_Required_Cur%ISOPEN ) THEN
3183 CLOSE PO_Required_Cur;
3184 END IF;
3185 APP_EXCEPTION.RAISE_EXCEPTION;
3186 END Check_PO_Required;
3187
3188 /*=============================================================================
3189 | PROCEDURE CHECK_NO_RATE
3190 | Procedure that checks if an invoice is a foreign invoice, missing an
3191 | exchange rate and places or releases the NO RATE' hold depending on
3192 | the condition.
3193 |
3194 | PARAMETER
3195 | p_invoice_id
3196 | p_base_currency_code
3197 | p_system_user
3198 | p_holds
3199 | p_holds_count
3200 | p_release_count
3201 | p_calling_sequence
3202 |
3203 | PROGRAM FLOW
3204 |
3205 | KNOWN ISSUES:
3206 |
3207 | NOTES:
3208 |
3209 | MODIFICATION HISTORY
3210 | Date Author Description of Change
3211 ============================================================================*/
3212 PROCEDURE Check_No_Rate(
3213 p_invoice_id IN NUMBER,
3214 p_base_currency_code IN VARCHAR2,
3215 p_system_user IN NUMBER,
3216 p_holds IN OUT NOCOPY HOLDSARRAY,
3217 p_holds_count IN OUT NOCOPY COUNTARRAY,
3218 p_release_count IN OUT NOCOPY COUNTARRAY,
3219 p_calling_sequence IN VARCHAR2) IS
3220
3221 CURSOR No_Rate_Cur IS
3222 SELECT 'Foreign Invoice without exchange rate'
3223 FROM ap_invoices I
3224 WHERE I.invoice_id = p_invoice_id
3225 AND I.invoice_currency_code <> p_base_currency_code
3226 AND I.exchange_rate is null;
3227
3228 l_no_rate_exists VARCHAR2(1) := 'N';
3229 l_test_var VARCHAR2(50) := '';
3230 l_debug_loc VARCHAR2(30) := 'Check_No_Rate';
3231 l_curr_calling_sequence VARCHAR2(2000);
3232 l_debug_info VARCHAR2(1000);
3233
3234 BEGIN
3235
3236 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
3237 p_calling_sequence;
3238
3239 OPEN No_Rate_Cur;
3240 FETCH No_Rate_Cur INTO l_test_var;
3241 CLOSE No_Rate_Cur;
3242
3243 IF ( l_test_var is not NULL ) THEN
3244 l_no_rate_exists := 'Y';
3245
3246 ---------------------------------------------------
3247 l_debug_info := 'NO RATE hold placed. Invoice_ID: '||p_invoice_id;
3248 Print_Debug(l_debug_loc, l_debug_info);
3249 ---------------------------------------------------
3250 END IF;
3251
3252 Process_Inv_Hold_Status(
3253 p_invoice_id,
3254 null,
3255 null,
3256 'NO RATE',
3257 l_no_rate_exists,
3258 null,
3259 p_system_user,
3260 p_holds,
3261 p_holds_count,
3262 p_release_count,
3263 l_curr_calling_sequence);
3264
3265 EXCEPTION
3266 WHEN OTHERS THEN
3267 IF (SQLCODE <> -20001) THEN
3268 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
3269 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
3270 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
3271 FND_MESSAGE.SET_TOKEN('PARAMETERS',
3272 'Invoice_id = '|| to_char(p_invoice_id)
3273 ||', Base Currency Code = '|| p_base_currency_code);
3274 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
3275 END IF;
3276
3277 IF ( No_Rate_Cur%ISOPEN ) THEN
3278 CLOSE No_Rate_Cur;
3279 END IF;
3280
3281 APP_EXCEPTION.RAISE_EXCEPTION;
3282 END Check_No_Rate;
3283
3284 /*=============================================================================
3285 | PROCEDURE CHECK_DIST_VARIANCE
3286 | Procedure that checks whether an invoice has a DIST VARIANCE condition,
3287 | i.e. distribution total does not equal to its invoice line amount and
3288 | places or releases the hold depending on the condition.
3289 |
3290 | PARAMETER
3291 | p_invoice_id
3292 | p_invoice_line_number
3293 | p_system_user
3294 | p_holds
3295 | p_holds_count
3296 | p_release_count
3297 | p_distribution_variance_exist
3298 | p_calling_sequence
3299 |
3300 | KNOWN ISSUES:
3301 |
3302 | NOTES:
3303 |
3304 | MODIFICATION HISTORY
3305 | Date Author Description of Change
3306 ============================================================================*/
3307
3308 PROCEDURE Check_Dist_Variance(
3309 p_invoice_id IN NUMBER,
3310 p_invoice_line_number IN NUMBER,
3311 p_system_user IN NUMBER,
3312 p_holds IN OUT NOCOPY HOLDSARRAY,
3313 p_holds_count IN OUT NOCOPY COUNTARRAY,
3314 p_release_count IN OUT NOCOPY COUNTARRAY,
3315 p_distribution_variance_exist OUT NOCOPY BOOLEAN,
3316 p_calling_sequence IN VARCHAR2) IS
3317
3318 CURSOR Dist_Var_Cur IS
3319 /* Modified by epajaril to fix bug 6729934 */
3320 SELECT 'Distribution needs to be verified. '
3321 FROM DUAL
3322 WHERE EXISTS (
3323 SELECT 'Dist Total <> Invoice Line Amount'
3324 FROM ap_invoice_lines_all AIL, ap_invoice_distributions_all D
3325 -- WHERE AIL.invoice_id = D.invoice_id
3326 WHERE AIL.invoice_id = D.invoice_id(+)
3327 AND AIL.line_number = nvl(p_invoice_line_number, AIL.line_number) --bug6661773
3328 AND AIL.invoice_id = p_invoice_id
3329 -- AND AIL.line_number = D.invoice_line_number
3330 AND AIL.line_number = D.invoice_line_number(+)
3331 -- AND (D.line_type_lookup_code <> 'RETAINAGE'
3332 AND (NVL(D.line_type_lookup_code, 'ITEM') <> 'RETAINAGE'
3333 OR (AIL.line_type_lookup_code = 'RETAINAGE RELEASE'
3334 and D.line_type_lookup_code = 'RETAINAGE'))
3335 AND (AIL.line_type_lookup_code
3336 NOT IN ('ITEM', 'RETAINAGE RELEASE')
3337 or (AIL.line_type_lookup_code
3338 IN ('ITEM', 'RETAINAGE RELEASE')
3339 and (D.prepay_distribution_id IS NULL
3340 or (D.prepay_distribution_id IS NOT NULL
3341 and D.line_type_lookup_code NOT IN ('PREPAY', 'REC_TAX', 'NONREC_TAX')))))
3342 /*
3343 AND (ail.line_type_lookup_code <> 'ITEM'
3344 OR (d.line_type_lookup_code <> 'PREPAY'
3345 and d.prepay_tax_parent_id IS NULL)
3346 )
3347 */
3348 GROUP BY AIL.invoice_id, AIL.line_number, AIL.amount
3349 HAVING AIL.amount <> nvl(SUM(nvl(D.amount,0)),0));
3350
3351 l_dist_var_exists VARCHAR2(1) := 'N';
3352 l_debug_loc VARCHAR2(30) := 'Check_Dist_Variance';
3353 l_curr_calling_sequence VARCHAR2(2000);
3354 l_debug_info VARCHAR2(1000);
3355 l_test_var VARCHAR2(50);
3356 l_inv_amount AP_INVOICES_ALL.INVOICE_AMOUNT%TYPE;
3357 l_dist_count NUMBER;
3358
3359 BEGIN
3360
3361 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||
3362 '<-'||p_calling_sequence;
3363
3364
3365 l_dist_count := 0;
3366 l_inv_amount := 0;
3367 p_distribution_variance_exist := FALSE;
3368
3369 -- Bug 4539514
3370 SELECT invoice_amount
3371 INTO l_inv_amount
3372 FROM ap_invoices_all ai
3373 WHERE ai.invoice_id = p_invoice_id;
3374
3375 SELECT count(*) INTO l_dist_count
3376 FROM ap_invoice_distributions_all aid
3377 WHERE aid.invoice_id = p_invoice_id
3378 AND ((aid.line_type_lookup_code <> 'PREPAY'
3379 AND aid.prepay_tax_parent_id IS NULL)
3380 OR nvl(invoice_includes_prepay_flag,'N') = 'Y')
3381 AND rownum =1; --Perf 6759699
3382
3383 IF (l_dist_count = 0 AND l_inv_amount <> 0) Then
3384 l_dist_var_exists := 'Y';
3385 p_distribution_variance_exist := TRUE;
3386
3387 --------------------------------------------------------
3388 l_debug_info := 'Distribution Variance Exists 1: '||l_dist_var_exists;
3389 Print_Debug(l_debug_loc, l_debug_info);
3390 --------------------------------------------------------
3391
3392 -- END IF;
3393 -- Perf 6759699
3394 -- If the variables l_dist_var_exists and p_distribution_variance_exists
3395 -- are set in the above if block then there is no need to open the
3396 -- cursor Dist_Var_Cur.
3397
3398 else
3399
3400 OPEN Dist_Var_Cur;
3401 FETCH Dist_Var_Cur
3402 INTO l_test_var;
3403
3404 IF (Dist_Var_Cur%ROWCOUNT > 0) THEN
3405 l_dist_var_exists := 'Y';
3406 p_distribution_variance_exist := TRUE;
3407
3408 --------------------------------------------------------
3409 l_debug_info := 'Distribution Variance Exists 2: '||l_dist_var_exists;
3410 Print_Debug(l_debug_loc, l_debug_info);
3411 --------------------------------------------------------
3412
3413 END IF;
3414 CLOSE Dist_Var_Cur;
3415 end if; -- l_dist_count Bug 6759699
3416
3417 Process_Inv_Hold_Status(p_invoice_id,
3418 null,
3419 null,
3420 'DIST VARIANCE',
3421 l_dist_var_exists,
3422 null,
3423 p_system_user,
3424 p_holds,
3425 p_holds_count,
3426 p_release_count,
3427 l_curr_calling_sequence);
3428
3429 EXCEPTION
3430 WHEN OTHERS THEN
3431 IF (SQLCODE <> -20001) THEN
3432 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
3433 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
3434 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
3435 FND_MESSAGE.SET_TOKEN('PARAMETERS',
3436 'Invoice_id = '|| to_char(p_invoice_id));
3437 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
3438 END IF;
3439
3440 IF ( Dist_Var_Cur%ISOPEN ) THEN
3441 CLOSE Dist_Var_Cur;
3442 END IF;
3443
3444 APP_EXCEPTION.RAISE_EXCEPTION;
3445 END Check_Dist_Variance;
3446
3447 /*=============================================================================
3448 | PROCEDURE CHECK_LINE_VARIANCE
3449 | Procedure that checks whether an invoice has a LINE VARIANCE condition,
3450 | i.e. lines total does not equal to invoice amount and places or
3451 | releases the hold depending on the condition.
3452 |
3453 | PARAMETER
3454 | p_invoice_id
3455 | p_system_user
3456 | p_holds
3457 | p_holds_count
3458 | p_release_count
3459 | p_line_variance_hold_exist
3460 | p_calling_sequence
3461 |
3462 | KNOWN ISSUES:
3463 |
3464 | NOTES:
3465 |
3466 | MODIFICATION HISTORY
3467 | Date Author Description of Change
3468 ============================================================================*/
3469
3470 PROCEDURE Check_Line_Variance(
3471 p_invoice_id IN NUMBER,
3472 p_system_user IN NUMBER,
3473 p_holds IN OUT NOCOPY HOLDSARRAY,
3474 p_holds_count IN OUT NOCOPY COUNTARRAY,
3475 p_release_count IN OUT NOCOPY COUNTARRAY,
3476 p_line_variance_hold_exist OUT NOCOPY BOOLEAN,
3477 p_calling_sequence IN VARCHAR2,
3478 p_base_currency_code IN VARCHAR2) IS --bug7271262
3479
3480
3481 CURSOR Line_Var_Cur IS
3482 SELECT 'Line Total <> Invoice Amount'
3483 FROM ap_invoice_lines_all AIL, ap_invoices_all A
3484 WHERE AIL.invoice_id = A.invoice_id
3485 AND AIL.invoice_id = p_invoice_id
3486 AND ((AIL.line_type_lookup_code <> 'TAX'
3487 and (AIL.line_type_lookup_code NOT IN ('AWT','PREPAY')
3488 or NVL(AIL.invoice_includes_prepay_flag,'N') = 'Y') OR
3489 (AIL.line_type_lookup_code = 'TAX'
3490 /* bug 5222316 */
3491 and (AIL.prepay_invoice_id IS NULL
3492 or (AIL.prepay_invoice_id is not null
3493 and NVL(AIL.invoice_includes_prepay_flag, 'N') = 'Y')))))
3494 -- and AIL.prepay_invoice_id IS NULL)))
3495 GROUP BY A.invoice_id, A.invoice_amount, A.net_of_retainage_flag
3496 HAVING A.invoice_amount <>
3497 nvl(SUM(nvl(AIL.amount,0) + decode(A.net_of_retainage_flag,
3498 'Y', nvl(AIL.retained_amount,0),0)),0);
3499
3500 l_line_var_exists VARCHAR2(1) := 'N';
3501 l_test_var VARCHAR2(50);
3502 l_debug_loc VARCHAR2(30) := 'Check_Line_Variance';
3503 l_curr_calling_sequence VARCHAR2(2000);
3504 l_debug_info VARCHAR2(1000);
3505 l_inv_cur_code ap_invoices.invoice_currency_code%type;
3506 l_inv_amount ap_invoices_all.invoice_amount%TYPE;
3507 l_line_count number;
3508 l_org_id ap_invoices_all.org_id%TYPE; --bug 7271262
3509 l_set_of_books_id ap_invoices_all.set_of_books_id%TYPE; --bug 7271262
3510 l_return_code VARCHAR2(100); --bug 7271262
3511 l_return_message VARCHAR2(1000); --bug 7271262
3512
3513 BEGIN
3514
3515 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||
3516 '<-'||p_calling_sequence;
3517
3518 p_line_variance_hold_exist := FALSE;
3519 l_line_count := 0;
3520 l_inv_amount := 0;
3521
3522 --Bugfix:4539514, added the below code so that we place
3523 --LINE VARIANCE hold when the user validates a invoice
3524 --with no lines in it.
3525
3526 --Bug 7271262 Added the org_id and set_of_books_id parameters in the below
3527 --select, to pass as parameters for JAI hook jai_ap_tolerance_pkg.inv_holds_check
3528
3529 SELECT invoice_amount,org_id,set_of_books_id
3530 INTO l_inv_amount,l_org_id,l_set_of_books_id
3531 FROM ap_invoices ai
3532 WHERE ai.invoice_id = p_invoice_id;
3533
3534 --Added the below code hook for India Localization as part of bug7271262
3535
3536 l_debug_info := 'Calling code hook jai_ap_tolerance_pkg.inv_holds_check';
3537
3538 IF (p_base_currency_code = 'INR') Then
3539 jai_ap_tolerance_pkg.inv_holds_check(
3540 p_invoice_id => p_invoice_id,
3541 p_org_id => l_org_id,
3542 p_set_of_books_id => l_set_of_books_id,
3543 p_invoice_amount => l_inv_amount,
3544 p_invoice_currency_code => p_base_currency_code,
3545 p_return_code => l_return_code,
3546 p_return_message => l_return_message);
3547 End IF;
3548
3549 /* End of Bug 7271262 */
3550
3551 SELECT count(*)
3552 INTO l_line_count
3553 FROM ap_invoice_lines ail
3554 WHERE ail.invoice_id = p_invoice_id
3555 AND (ail.line_type_lookup_code NOT IN ('PREPAY','AWT')
3556 OR nvl(invoice_includes_prepay_flag,'N') = 'Y');
3557
3558 IF (l_line_count = 0 AND l_inv_amount <> 0) Then
3559 l_line_var_exists := 'Y';
3560 p_line_variance_hold_exist := TRUE;
3561 END IF;
3562
3563 --
3564
3565 OPEN Line_Var_Cur;
3566 FETCH Line_Var_Cur
3567 INTO l_test_var;
3568
3569 IF ( Line_Var_Cur%ROWCOUNT > 0 ) THEN
3570 l_line_var_exists := 'Y';
3571 p_line_variance_hold_exist := TRUE;
3572 END IF;
3573
3574 CLOSE Line_Var_Cur;
3575
3576 --------------------------------------------------------
3577 l_debug_info := 'Line Variance Exists: '||l_line_var_exists;
3578 Print_Debug(l_debug_loc, l_debug_info);
3579 --------------------------------------------------------
3580
3581 Process_Inv_Hold_Status(
3582 p_invoice_id,
3583 null,
3584 null,
3585 'LINE VARIANCE',
3586 l_line_var_exists,
3587 null,
3588 p_system_user,
3589 p_holds,
3590 p_holds_count,
3591 p_release_count,
3592 l_curr_calling_sequence);
3593
3594 EXCEPTION
3595 WHEN OTHERS THEN
3596 IF (SQLCODE <> -20001) THEN
3597 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
3598 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
3599 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
3600 FND_MESSAGE.SET_TOKEN('PARAMETERS',
3601 'Invoice_id = '|| to_char(p_invoice_id));
3602 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
3603 END IF;
3604 IF ( Line_Var_Cur%ISOPEN ) THEN
3605 CLOSE Line_Var_Cur;
3606 END IF;
3607
3608 APP_EXCEPTION.RAISE_EXCEPTION;
3609 END Check_Line_Variance;
3610
3611 /*=============================================================================
3612 | PROCEDURE Line_BASE_AMOUNT_CALCULATION
3613 |
3614 | DESCRIPTION
3615 | Calculate the functional amount for all the lines which were not
3616 | partiallly or fully accounted. Populate the rounding amount for lines
3617 |
3618 | PARAMETERS
3619 | p_invoice_id
3620 | p_invoice_currency_code
3621 | p_base_currency_code
3622 | p_exchange_rate
3623 | p_need_to_round_flag
3624 | p_calling_sequence
3625 |
3626 | PROGRAM FLOW
3627 |
3628 | KNOWN ISSUES:
3629 |
3630 | NOTES:
3631 |
3632 | MODIFICATION HISTORY
3633 | Date Author Description of Change
3634 |
3635 *============================================================================*/
3636
3637 PROCEDURE Line_Base_Amount_Calculation(
3638 p_invoice_id IN NUMBER,
3639 p_invoice_currency_code IN VARCHAR2,
3640 p_base_currency_code IN VARCHAR2,
3641 p_exchange_rate IN NUMBER,
3642 p_need_to_round_flag IN VARCHAR2 DEFAULT 'N',
3643 p_calling_sequence IN VARCHAR2) IS
3644
3645 l_rounded_line_num ap_invoice_lines.line_number%TYPE;
3646 l_rounded_amt NUMBER;
3647 l_round_amt_exist BOOLEAN := FALSE;
3648 l_key_value NUMBER;
3649
3650 l_debug_loc VARCHAR2(30) := 'Line_Base_Amount_Calculation';
3651 l_curr_calling_sequence VARCHAR2(2000);
3652 l_debug_info VARCHAR2(100);
3653 l_debug_context VARCHAR2(2000);
3654
3655 l_modified_line_rounding_amt NUMBER; --6892789
3656 l_base_amt NUMBER; --6892789
3657 l_round_inv_line_numbers AP_INVOICES_UTILITY_PKG.inv_line_num_tab_type; --6892789
3658
3659 BEGIN
3660
3661 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||
3662 '<-'||p_calling_sequence;
3663
3664 -----------------------------------------------------
3665 l_debug_info := 'Update Invoice Lines Base Amount';
3666 Print_Debug(l_debug_loc, l_debug_info);
3667 -----------------------------------------------------
3668
3669 UPDATE AP_INVOICE_LINES AIL
3670 SET AIL.base_amount = DECODE(p_base_currency_code, p_invoice_currency_code,
3671 NULL,
3672 ap_utilities_pkg.ap_round_currency(
3673 amount * p_exchange_rate,
3674 p_base_currency_code)),
3675 AIL.last_update_date = SYSDATE,
3676 AIL.last_updated_by = FND_GLOBAL.user_id,
3677 AIL.last_update_login = FND_GLOBAL.login_id
3678 WHERE AIL.invoice_id = p_invoice_id
3679 -- Bug 6621883
3680 AND (EXISTS ( SELECT 'NOT POSTED'
3681 FROM ap_invoice_distributions_all D
3682 WHERE D.invoice_id = AIL.invoice_id
3683 AND D.invoice_line_number = AIL.line_number
3684 AND NVL(D.posted_flag, 'N') = 'N' )
3685 OR NOT EXISTS (SELECT 'DIST DOES NOT EXIST'
3686 FROM ap_invoice_distributions_all D1
3687 WHERE D1.invoice_id = AIL.invoice_id
3688 AND D1.invoice_line_number = AIL.line_number
3689 AND AIL.amount IS NOT NULL
3690 )
3691 )
3692 --Retropricing: Adjustment Correction lines on the PPA should be
3693 -- excluded. Base amounts on zero amount adjustment lines adjustment
3694 -- correction lines on the PPA is handled while creating PPA Docs.
3695 --Bugfix:4625349, modified the AND clause
3696 AND
3697 ( line_type_lookup_code <> 'RETROITEM' OR
3698 (line_type_lookup_code = 'RETROITEM' and
3699 match_type <> 'ADJUSTMENT_CORRECTION')
3700 );
3701
3702 -----------------------------------------------------
3703 l_debug_info := 'Round Invoice Lines Base Amount';
3704 Print_Debug(l_debug_loc, l_debug_info);
3705 -----------------------------------------------------
3706
3707 IF ( NVL(p_need_to_round_flag, 'N') = 'Y' ) THEN
3708 --Retropricing: Max of the largest invoice line should exclude
3709 -- Adjustment Correction lines on the PPA as well as the
3710 -- Zero Amt Adjustment line on the Original Invoice.
3711 -- Change needs to be done in apinvutb.pls.
3712
3713 /* modifying following code as per the bug 6892789 as there is a chance
3714 that line base amt goes to -ve value (line amount being +ve) so in such
3715 case, adjust line base amount upto zero and adjust the remaing amount in
3716 another line having next max amount */
3717
3718 -- get the lines which can be adjusted
3719 l_round_amt_exist := AP_INVOICES_UTILITY_PKG.round_base_amts(
3720 X_Invoice_Id => p_invoice_id,
3721 X_Reporting_Ledger_Id => NULL,
3722 X_Rounded_Line_Numbers => l_round_inv_line_numbers,
3723 X_Rounded_Amt => l_rounded_amt,
3724 X_Debug_Info => l_debug_info,
3725 X_Debug_Context => l_debug_context,
3726 X_Calling_sequence => l_curr_calling_sequence);
3727
3728 --adjustment required and there exists line numbers that can be adjusted
3729 IF ( l_round_amt_exist AND l_round_inv_line_numbers.count > 0 ) THEN
3730 -- iterate throgh lines until there is no need to adjust
3731 for i in 1 .. l_round_inv_line_numbers.count
3732 loop
3733 IF l_rounded_amt <> 0 THEN
3734 -- get the existing base amount for the selected line
3735 select base_amount
3736 INTO l_base_amt
3737 FROM AP_INVOICE_LINES
3738 WHERE invoice_id = p_invoice_id
3739 AND line_number = l_round_inv_line_numbers(i);
3740
3741 -- get the calculated adjusted base amount and rounding amount
3742 -- get rounding amount for the next line if required
3743 l_base_amt := AP_APPROVAL_PKG.get_adjusted_base_amount(
3744 p_base_amount => l_base_amt,
3745 p_rounding_amt => l_modified_line_rounding_amt,
3746 p_next_line_rounding_amt => l_rounded_amt);
3747
3748 -- update the calculatd base amount, rounding amount
3749 UPDATE AP_INVOICE_LINES
3750 SET base_amount = l_base_amt,
3751 rounding_amt = ABS( NVL(l_modified_line_rounding_amt, 0) ),
3752 last_update_date = SYSDATE,
3753 last_updated_by = FND_GLOBAL.user_id,
3754 last_update_login = FND_GLOBAL.login_id
3755 WHERE invoice_id = p_invoice_id
3756 AND line_number = l_round_inv_line_numbers(i);
3757 ELSE--adjustment not required or there are no lines that can be adjusted
3758 EXIT;
3759 END IF;
3760 end loop;
3761 END IF;
3762 END IF;
3763
3764 EXCEPTION
3765 WHEN OTHERS THEN
3766 IF (SQLCODE <> -20001) THEN
3767 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
3768 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
3769 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
3770 FND_MESSAGE.SET_TOKEN('PARAMETERS',
3771 'Invoice_id = '|| to_char(p_invoice_id));
3772 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
3773 END IF;
3774 APP_EXCEPTION.RAISE_EXCEPTION;
3775 END Line_Base_Amount_Calculation;
3776
3777 /*=============================================================================
3778 | PROCEDURE Dist_BASE_AMOUNT_CALCULATION
3779 |
3780 | DESCRIPTION
3781 | Calculate the functional amount for all the lines and distributions
3782 | which were not partiallly or fully accounted. Populate the rounding
3783 | amount for lines and distribuitons
3784 |
3785 | PARAMETERS
3786 | p_invoice_id
3787 | p_invoice_line_number
3788 | p_invoice_currency_code
3789 | p_base_currency_code
3790 | p_invoice_exchange_rate
3791 |
3792 | p_calling_sequence
3793 |
3794 | PROGRAM FLOW
3795 |
3796 | KNOWN ISSUES:
3797 |
3798 | NOTES:
3799 |
3800 | MODIFICATION HISTORY
3801 | Date Author Description of Change
3802 |
3803 *============================================================================*/
3804
3805 PROCEDURE Dist_Base_Amount_Calculation(
3806 p_invoice_id IN NUMBER,
3807 p_invoice_line_number IN NUMBER,
3808 p_invoice_currency_code IN VARCHAR2,
3809 p_base_currency_code IN VARCHAR2,
3810 p_invoice_exchange_rate IN NUMBER,
3811 p_need_to_round_flag IN VARCHAR2 DEFAULT 'N',
3812 p_calling_sequence IN VARCHAR2) IS
3813
3814
3815 l_round_amt_exists BOOLEAN := FALSE;
3816 l_rounded_amt NUMBER;
3817 l_rounded_dist_id ap_invoice_distributions.INVOICE_DISTRIBUTION_ID%TYPE;
3818 l_debug_loc VARCHAR2(30) := 'Dist_Base_Amount_Calculation';
3819 l_curr_calling_sequence VARCHAR2(2000);
3820 l_debug_info VARCHAR2(1000);
3821 l_debug_context VARCHAR2(2000);
3822
3823 l_base_amt NUMBER; --6892789
3824 l_modified_dist_rounding_amt NUMBER; --6892789
3825 l_round_dist_id_list AP_INVOICE_LINES_PKG.distribution_id_tab_type; --6892789
3826
3827 BEGIN
3828
3829 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||
3830 '<-'||p_calling_sequence;
3831
3832 ------------------------------------------------------
3833 l_debug_info := 'Update Distribution Base Amounts';
3834 Print_Debug(l_debug_loc, l_debug_info);
3835 ------------------------------------------------------
3836
3837 --Bugfix:4625771
3838 --Added the AND clause so as to not to overwrite the
3839 --base_amounts calculated on matched distributions
3840 --which either have an IPV or ERV or both, during the
3841 --earlier call to exec_matched_variance_checks.
3842 UPDATE AP_INVOICE_DISTRIBUTIONS
3843 SET base_amount = DECODE(p_base_currency_code, p_invoice_currency_code,
3844 NULL, ap_utilities_pkg.ap_round_currency(
3845 amount * p_invoice_exchange_rate,
3846 p_base_currency_code)),
3847 last_update_date = SYSDATE,
3848 last_updated_by = FND_GLOBAL.user_id,
3849 last_update_login = FND_GLOBAL.login_id
3850 WHERE invoice_id = p_invoice_id
3851 AND invoice_line_number = p_invoice_line_number
3852 AND NVL(posted_flag,'N') = 'N'
3853 --Bugfix:4625771
3854 AND related_id IS NULL;
3855
3856 ------------------------------------------------------
3857 l_debug_info := 'Round Distribution Base Amounts';
3858 Print_Debug(l_debug_loc, l_debug_info);
3859 ------------------------------------------------------
3860
3861 IF ( NVL(p_need_to_round_flag, 'N') = 'Y' ) THEN
3862
3863 /* modifying following code as per the bug 6892789 as there is a chance that
3864 distribution base amt goes to -ve value (amount being +ve) so in such case,
3865 adjust dist base amount upto zero and adjust the remaing amount in another
3866 distribution having next max amount */
3867
3868 -- get the distributions which can be adjusted
3869 l_round_amt_exists := AP_INVOICE_LINES_PKG.round_base_amts(
3870 x_invoice_id => p_invoice_id,
3871 x_line_number => p_invoice_line_number,
3872 x_reporting_ledger_id => NULL,
3873 x_round_dist_id_list => l_round_dist_id_list,
3874 x_rounded_amt => l_rounded_amt,
3875 x_debug_info => l_debug_info,
3876 x_debug_context => l_debug_context,
3877 x_calling_sequence => l_curr_calling_sequence);
3878
3879 -- adjustment required and there exists dists that can be adjusted
3880 IF ( l_round_amt_exists AND l_round_dist_id_list.count > 0 ) THEN
3881 -- iterate through dists till there is no need to adjust
3882 for i in 1 .. l_round_dist_id_list.count
3883 loop
3884 IF l_rounded_amt <> 0 THEN
3885
3886 -- get the existing base amount for the selected distribution
3887 select base_amount
3888 INTO l_base_amt
3889 FROM AP_INVOICE_DISTRIBUTIONS
3890 WHERE invoice_id = p_invoice_id
3891 AND invoice_line_number = p_invoice_line_number
3892 AND invoice_distribution_id = l_round_dist_id_list(i);
3893
3894 -- get the calculated adjusted base amount and rounding amount
3895 -- get rounding amount for the next dist, if required
3896 l_base_amt := AP_APPROVAL_PKG.get_adjusted_base_amount(
3897 p_base_amount => l_base_amt,
3898 p_rounding_amt => l_modified_dist_rounding_amt,
3899 p_next_line_rounding_amt => l_rounded_amt);
3900
3901 -- update the calculatd base amount, rounding amount
3902 UPDATE AP_INVOICE_DISTRIBUTIONS
3903 SET base_amount = l_base_amt,
3904 rounding_amt = ABS( l_modified_dist_rounding_amt ),
3905 last_update_date = SYSDATE,
3906 last_updated_by = FND_GLOBAL.user_id,
3907 last_update_login = FND_GLOBAL.login_id
3908 WHERE invoice_distribution_id = l_round_dist_id_list(i);
3909
3910 ELSE
3911 --adjustment not required or there are no dists that can be adjusted
3912 EXIT;
3913 END IF;
3914 end loop;
3915 END IF;
3916 END IF;
3917
3918 EXCEPTION
3919 WHEN OTHERS THEN
3920 IF (SQLCODE <> -20001) THEN
3921 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
3922 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
3923 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
3924 FND_MESSAGE.SET_TOKEN('PARAMETERS',
3925 'Invoice_id = '|| to_char(p_invoice_id));
3926 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
3927 END IF;
3928 APP_EXCEPTION.RAISE_EXCEPTION;
3929 END Dist_Base_Amount_Calculation;
3930
3931 /*=============================================================================
3932 | PROCEDURE GENERATE_ACCOUNT_EVENT
3933 |
3934 | DESCRIPTION:
3935 | Generate Accounting Event
3936 |
3937 | PARAMETERS
3938 | p_invoice_id
3939 | p_calling_sequence
3940 |
3941 | KNOWN ISSUES:
3942 |
3943 | NOTES:
3944 | Events Project 5
3945 | Before creating new events, we need to check if there are any
3946 | events which have been created with the status 'INCOMPLETE'. If
3947 | there are, and the holds have now been removed, we may want to
3948 | change the status from 'INCOMPLETE' to 'CREATED' rather than
3949 | creating a new event.
3950 |
3951 | MODIFICATION HISTORY
3952 | Date Author Description of Change
3953 |
3954 *============================================================================*/
3955
3956 PROCEDURE Generate_Account_Event(
3957 p_invoice_id IN NUMBER,
3958 p_calling_sequence IN VARCHAR2) IS
3959
3960 l_accounting_event_id NUMBER; -- Events Project - 1
3961 l_null_event_id NUMBER; -- Events Project - 4
3962
3963 l_debug_loc VARCHAR2(30) := 'Generate_Account_Event';
3964 l_curr_calling_sequence VARCHAR2(2000);
3965 l_debug_info VARCHAR2(1000);
3966
3967 BEGIN
3968
3969 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
3970 p_calling_sequence;
3971
3972 -------------------------------------------------
3973 l_debug_info := 'Accounting Event Generation';
3974 Print_Debug(l_debug_loc, l_debug_info);
3975 -------------------------------------------------
3976
3977 SELECT count(*)
3978 INTO l_null_event_id
3979 FROM ap_invoice_distributions aid
3980 WHERE aid.invoice_id = P_invoice_id
3981 AND aid.accounting_event_id is NULL;
3982
3983
3984 AP_ACCOUNTING_EVENTS_PKG.Update_Invoice_Events_Status(
3985 p_invoice_id => p_invoice_id,
3986 p_calling_sequence => l_curr_calling_sequence);
3987
3988 IF l_null_event_id > 0 then
3989
3990 -------------------------------------------------
3991 l_debug_info := 'Accounting Event - create event for null event rows';
3992 Print_Debug(l_debug_loc, l_debug_info);
3993 -------------------------------------------------
3994
3995 AP_Accounting_Events_Pkg.Create_Events(
3996 p_event_type => 'INVOICES',
3997 p_doc_type => NULL,
3998 p_doc_id => p_invoice_id,
3999 p_accounting_date => NULL,
4000 p_accounting_event_id => l_accounting_event_id,
4001 p_checkrun_name => NULL,
4002 p_calling_sequence => l_curr_calling_sequence);
4003
4004 END IF;
4005
4006 EXCEPTION
4007 WHEN OTHERS THEN
4008 IF (SQLCODE <> -20001) THEN
4009 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
4010 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
4011 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
4012 FND_MESSAGE.SET_TOKEN('PARAMETERS',
4013 'Invoice_id = '|| to_char(p_invoice_id));
4014 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
4015 END IF;
4016 APP_EXCEPTION.RAISE_EXCEPTION;
4017 END Generate_Account_Event;
4018
4019 /*=============================================================================
4020 | PROCEDURE CHECK_PREPAID_AMOUNT
4021 | Procedure that checks whether the invoice amount is more than
4022 | the prepaid amount
4023 |
4024 | PARAMETERS
4025 | p_invoice_id
4026 | p_system_user
4027 | p_holds
4028 | p_holds_count
4029 | p_release_count
4030 | p_calling_sequence
4031 |
4032 | KNOWN ISSUES:
4033 |
4034 | NOTES:
4035 |
4036 | MODIFICATION HISTORY
4037 | Date Author Description of Change
4038 |
4039 *============================================================================*/
4040
4041 PROCEDURE Check_Prepaid_Amount(
4042 p_invoice_id IN NUMBER,
4043 p_system_user IN NUMBER,
4044 p_holds IN OUT NOCOPY HOLDSARRAY,
4045 p_holds_count IN OUT NOCOPY COUNTARRAY,
4046 p_release_count IN OUT NOCOPY COUNTARRAY,
4047 p_calling_sequence IN VARCHAR2) IS
4048
4049 -- This select modified to use the lines table instead of distributions
4050 -- to get the prepaid_amount, only if the prepayments are not included
4051 -- in the invoice. The prepaid amount will include taxes.
4052
4053 CURSOR Prepay_Var_Cur IS
4054 SELECT AI.invoice_amount, (0 - sum(nvl(AIL.amount,0)))
4055 FROM ap_invoices_all AI, ap_invoice_lines_all AIL
4056 WHERE AI.invoice_id = p_invoice_id
4057 AND AIL.invoice_id = AI.invoice_id
4058 AND AIL.invoice_includes_prepay_flag = 'N'
4059 AND AIL.line_type_lookup_code IN ('PREPAY', 'TAX')
4060 AND AIL.prepay_invoice_id IS NOT NULL
4061 AND AIL.prepay_line_number IS NOT NULL
4062 GROUP BY AI.invoice_id, AI.invoice_amount
4063 Having sum(nvl(AIL.amount,0)) <>0; --Bug5724818
4064
4065 l_invoice_amount NUMBER;
4066 l_prepaid_amount NUMBER;
4067 l_prepay_var_exists VARCHAR2(1) := 'N';
4068 l_debug_loc VARCHAR2(30) := 'Check_Prepaid_Amount';
4069 l_debug_info VARCHAR2(1000);
4070 l_curr_calling_sequence VARCHAR2(2000);
4071
4072 BEGIN
4073
4074 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||
4075 '<-'||p_calling_sequence;
4076
4077 OPEN Prepay_Var_Cur;
4078 LOOP
4079 FETCH Prepay_Var_Cur
4080 INTO l_invoice_amount, l_prepaid_amount;
4081
4082 EXIT WHEN Prepay_Var_Cur%NOTFOUND;
4083
4084 IF l_invoice_amount < l_prepaid_amount THEN
4085 l_prepay_var_exists := 'Y';
4086
4087 -------------------------------------------------
4088 l_debug_info := 'PREPAY VARIANCE hold placed';
4089 Print_Debug(l_debug_loc, l_debug_info);
4090 -------------------------------------------------
4091 END IF;
4092 END LOOP;
4093 CLOSE Prepay_Var_Cur;
4094
4095 Process_Inv_Hold_Status(
4096 p_invoice_id,
4097 null,
4098 null,
4099 'PREPAID AMOUNT',
4100 l_prepay_var_exists,
4101 null,
4102 p_system_user,
4103 p_holds,
4104 p_holds_count,
4105 p_release_count,
4106 l_curr_calling_sequence);
4107
4108 EXCEPTION
4109 WHEN OTHERS THEN
4110 IF (SQLCODE <> -20001) THEN
4111 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
4112 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
4113 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
4114 FND_MESSAGE.SET_TOKEN('PARAMETERS',
4115 'Invoice_id = '|| to_char(p_invoice_id));
4116 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
4117 END IF;
4118 APP_EXCEPTION.RAISE_EXCEPTION;
4119 END Check_Prepaid_Amount;
4120
4121 /*=============================================================================
4122 | PROCEDURE CHECK_INVOICE_VENDOR
4123 | Procedure that checks if an invoice has any of the following
4124 | 1. Exceeds the invoice amount limit stated at the vendor site level
4125 | and places or releases the AMOUNT' hold
4126 | 2. The vendor site has set to hold future payments and places or
4127 | release the 'VENDOR' hold
4128 |
4129 | PARAMETERS
4130 | p_invoice_id
4131 | p_base_currency_code
4132 | p_invoice_amount
4133 | p_base_amount
4134 | p_invoice_currency_code
4135 | p_invoice_amount_limit
4136 | p_hold_future_payments_flag
4137 | p_system_user
4138 | p_holds
4139 | p_holds_count
4140 | p_release_count
4141 | p_calling_sequence
4142 |
4143 | KNOWN ISSUES:
4144 |
4145 | NOTES:
4146 |
4147 | MODIFICATION HISTORY
4148 | Date Author Description of Change
4149 |
4150 *============================================================================*/
4151
4152 PROCEDURE Check_invoice_vendor(
4153 p_invoice_id IN NUMBER,
4154 p_base_currency_code IN VARCHAR2,
4155 p_invoice_amount IN NUMBER,
4156 p_base_amount IN NUMBER,
4157 p_invoice_currency_code IN VARCHAR2,
4158 p_invoice_amount_limit IN NUMBER,
4159 p_hold_future_payments_flag IN VARCHAR2,
4160 p_system_user IN NUMBER,
4161 p_holds IN OUT NOCOPY HOLDSARRAY,
4162 p_holds_count IN OUT NOCOPY COUNTARRAY,
4163 p_release_count IN OUT NOCOPY COUNTARRAY,
4164 p_calling_sequence IN VARCHAR2) IS
4165
4166 l_amount_hold_required VARCHAR2(1) := 'N';
4167 l_debug_loc VARCHAR2(30) := 'Check_invoice_vendor';
4168 l_curr_calling_sequence VARCHAR2(2000);
4169 l_debug_info VARCHAR2(1000);
4170
4171 BEGIN
4172
4173
4174 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||
4175 '<-'||p_calling_sequence;
4176 /*-----------------------------------------------------------------+
4177 | Check invoice amount limit |
4178 +-----------------------------------------------------------------*/
4179
4180 IF (p_invoice_amount_limit is not null) THEN
4181
4182 IF ((p_invoice_currency_code = p_base_currency_code and
4183 p_invoice_amount > p_invoice_amount_limit) or
4184 (p_invoice_currency_code <> p_base_currency_code and
4185 p_base_amount > p_invoice_amount_limit)) THEN
4186 l_amount_hold_required := 'Y';
4187 ELSE
4188 l_amount_hold_required := 'N';
4189 END IF;
4190 END IF;
4191
4192 -------------------------------------------------------
4193 l_debug_info := 'AMOUNT hold placed: '||l_amount_hold_required;
4194 Print_Debug(l_debug_loc, l_debug_info);
4195 -------------------------------------------------------
4196
4197 Process_Inv_Hold_Status(
4198 p_invoice_id,
4199 null,
4200 null,
4201 'AMOUNT',
4202 l_amount_hold_required,
4203 null,
4204 p_system_user,
4205 p_holds,
4206 p_holds_count,
4207 p_release_count,
4208 l_curr_calling_sequence);
4209
4210 -------------------------------------------------------
4211 l_debug_info := 'Check_invoice_vendor - check hold future payment';
4212 Print_Debug(l_debug_loc, l_debug_info);
4213 -------------------------------------------------------
4214
4215 Process_Inv_Hold_Status(
4216 p_invoice_id,
4217 null,
4218 null,
4219 'VENDOR',
4220 p_hold_future_payments_flag,
4221 null,
4222 p_system_user,
4223 p_holds,
4224 p_holds_count,
4225 p_release_count,
4226 l_curr_calling_sequence);
4227
4228 EXCEPTION
4229 WHEN OTHERS THEN
4230 IF (SQLCODE <> -20001) THEN
4231 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
4232 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
4233 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
4234 FND_MESSAGE.SET_TOKEN('PARAMETERS',
4235 'Invoice_id = '|| to_char(p_invoice_id)
4236 ||', Base Currency Code = '|| p_base_currency_code
4237 ||', Invoice Currency Code = '|| p_invoice_currency_code
4238 ||', Invoice Amount = '|| to_char(p_invoice_amount)
4239 ||', Base Amount = '|| to_char(p_base_amount)
4240 ||', Invoice Amount Limit = '|| to_char(p_invoice_amount_limit)
4241 ||', Hold Future Payments Flag = '|| p_hold_future_payments_flag);
4242 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
4243 END IF;
4244 APP_EXCEPTION.RAISE_EXCEPTION;
4245 END Check_invoice_vendor;
4246
4247
4248 /*=============================================================================
4249 | PROCEDURE Check_Manual_AWT_Segments
4250 | Procedure that checks AWT Account segments
4251 |
4252 |
4253 | PARAMETERS
4254 | p_invoice_id
4255 | p_system_user
4256 | p_holds
4257 | p_holds_count
4258 | p_release_count
4259 | p_calling_sequence
4260 |
4261 | KNOWN ISSUES:
4262 |
4263 | NOTES:
4264 | FOR NON-AWT LINES
4265 | 1. Excluding the tax line on the prepayment from the distributions
4266 | 2. Including the Prepayment and Prepayment Tax if
4267 | invoice_includes_prepay_flag = 'Y'
4268 | MODIFICATION HISTORY
4269 | Date Author Description of Change
4270 |
4271 *============================================================================*/
4272
4273 PROCEDURE Check_Manual_AWT_Segments(
4274 p_invoice_id IN NUMBER,
4275 p_system_user IN NUMBER,
4276 p_holds IN OUT NOCOPY HOLDSARRAY,
4277 p_holds_count IN OUT NOCOPY COUNTARRAY,
4278 p_release_count IN OUT NOCOPY COUNTARRAY,
4279 p_calling_sequence IN VARCHAR2) IS
4280
4281 CURSOR c_manual_awt_dist_segs is
4282 SELECT ap_utilities_pkg.get_auto_offsets_segments(
4283 aid.dist_code_combination_id)
4284 FROM ap_invoice_distributions aid
4285 WHERE aid.invoice_id = p_invoice_id
4286 AND aid.line_type_lookup_code = 'AWT'
4287 AND aid.awt_flag = 'M';
4288
4289 -- eTax Uptake. This select modified to use the
4290 -- prepay_distribution_id column to determine if a distribution
4291 -- is not created by a prepayment application
4292 -- and include the lines table to know if the prepayment was included
4293 -- in the invoice
4294 CURSOR c_non_awt_dists_segs is
4295 SELECT ap_utilities_pkg.get_auto_offsets_segments(
4296 aid.dist_code_combination_id)
4297 FROM ap_invoice_distributions_all aid, ap_invoice_lines_all ail
4298 WHERE ail.invoice_id = p_invoice_id
4299 AND ail.invoice_id = aid.invoice_id
4300 AND ail.line_number = aid.invoice_line_number
4301 AND ((aid.line_type_lookup_code not in ('AWT','PREPAY')
4302 AND aid.prepay_distribution_id IS NULL)
4303 OR NVL(ail.invoice_includes_prepay_flag,'N') = 'Y');
4304
4305
4306 l_manual_awt_dist_segs VARCHAR2(100);
4307 l_non_awt_dist_segs VARCHAR2(100);
4308 p_dist_segs_hold_required VARCHAR2(1);
4309 l_curr_calling_sequence VARCHAR2(2000);
4310 l_debug_info VARCHAR2(1000);
4311
4312
4313 BEGIN
4314
4315 l_curr_calling_sequence := 'AP_APPROVAL_PKG.Check_Manual_AWT_Segments'||'<-'
4316 ||p_calling_sequence;
4317
4318 OPEN c_manual_awt_dist_segs;
4319 LOOP
4320 FETCH c_manual_awt_dist_segs into l_manual_awt_dist_segs;
4321 EXIT WHEN c_manual_awt_dist_segs%NOTFOUND ;
4322 OPEN c_non_awt_dists_segs;
4323 LOOP
4324 FETCH c_non_awt_dists_segs into l_non_awt_dist_segs;
4325 EXIT WHEN c_non_awt_dists_segs%NOTFOUND ;
4326
4327 IF ( l_non_awt_dist_segs = l_manual_awt_dist_segs ) THEN
4328 p_dist_segs_hold_required := 'N' ;
4329 EXIT;
4330 ELSE
4331 p_dist_segs_hold_required := 'Y';
4332 END IF;
4333 END LOOP;
4334 CLOSE c_non_awt_dists_segs;
4335 END LOOP;
4336 CLOSE c_manual_awt_dist_segs;
4337
4338 /*-----------------------------------------------------------------+
4339 | Process Invoice Hold FUTURE PERIOD |
4340 +-----------------------------------------------------------------*/
4341
4342 Process_Inv_Hold_Status(
4343 p_invoice_id,
4344 null,
4345 null,
4346 'AWT ACCT INVALID',
4347 p_dist_segs_hold_required,
4348 null,
4349 p_system_user,
4350 p_holds,
4351 p_holds_count,
4352 p_release_count,
4353 l_curr_calling_sequence);
4354
4355 END Check_Manual_AWT_Segments;
4356
4357 /*=============================================================================
4358 | PROCEDURE GET_INV_MATCHED_STATUS
4359 | Function given an invoice_id returns TRUE ifthe invoice has any matched
4360 | distribution lines, otherwise FALSE
4361 |
4362 | PARAMETERS
4363 | p_invoice_id
4364 | p_calling_sequence
4365 |
4366 | KNOWN ISSUES:
4367 |
4368 | NOTES:
4369 |
4370 | MODIFICATION HISTORY
4371 | Date Author Description of Change
4372 |
4373 *============================================================================*/
4374
4375 FUNCTION Get_Inv_Matched_Status(
4376 p_invoice_id IN NUMBER,
4377 p_calling_sequence IN VARCHAR2) RETURN BOOLEAN
4378 IS
4379
4380 l_matched_count NUMBER;
4381 l_debug_loc VARCHAR2(30) := 'Get_Inv_Matched_Status';
4382 l_curr_calling_sequence VARCHAR2(2000);
4383 l_debug_info VARCHAR2(1000);
4384
4385 BEGIN
4386
4387 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
4388 p_calling_sequence;
4389
4390 SELECT count(*)
4391 INTO l_matched_count
4392 FROM ap_invoice_distributions
4393 WHERE invoice_id = p_invoice_id
4394 AND po_distribution_id is not null
4395 AND line_type_lookup_code in ( 'ITEM', 'ACCRUAL', 'IPV');
4396
4397 IF (l_matched_count > 0) THEN
4398 return(TRUE);
4399 ELSE
4400 return(FALSE);
4401 END IF;
4402
4403 EXCEPTION
4404 WHEN NO_DATA_FOUND THEN
4405 return(FALSE);
4406 WHEN OTHERS THEN
4407 IF (SQLCODE <> -20001) THEN
4408 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
4409 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
4410 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
4411 FND_MESSAGE.SET_TOKEN('PARAMETERS',
4412 'Invoice_id = '|| to_char(p_invoice_id));
4413 END IF;
4414 APP_EXCEPTION.RAISE_EXCEPTION;
4415 END Get_Inv_Matched_Status;
4416
4417
4418 /* ============================================================================
4419 | WITHHOLD_TAX_ON:
4420 |
4421 | Procedure that calls the withholding tax package on an invoice and checks
4422 | for any errors. Depending on whether an error exists or not, a hold gets
4423 | placed or released.
4424 |
4425 | Parameters:
4426 |
4427 | p_invoice_id : Invoice Id
4428 | p_gl_date_from_receipt : GL Date From Receipt Flag system option
4429 | p_last_updated_by : Column Who Info
4430 | p_last_update_login : Column Who Info
4431 | p_program_application_id : Column Who Info
4432 | p_program_id : Column Who Info
4433 | p_request_id : Column Who Info
4434 | p_system_user : Approval Program User Id
4435 | p_holds : Hold Array
4436 | p_holds_count : Holds Count Array
4437 | p_release_count : Release Count Array
4438 | p_calling_sequence : Debugging string to indicate path of module
4439 | calls to be printed out upon error.
4440 |
4441 | Program Flow:
4442 | -------------
4443 |
4444 | Check if okay to call Withholding Routine
4445 | invoice has at lease on distribution with a withholding tax group
4446 | invoice has not already been withheld by the system
4447 | invoice has no user non-releaseable holds (ther than AWT ERROR)
4448 | invoice has no manual withholding lines
4449 | IF okay then call AP_DO_WITHHOLDING package on the invoice
4450 | Depending on whether withholding is successful or not, place or
4451 | or release the 'AWT ERROR' with the new error reason.
4452 | (If the invoice already has the hold we want to release the old one and
4453 | replace the hold with the new error reason)
4454 |============================================================================ */
4455
4456 PROCEDURE Withhold_Tax_On(
4457 p_invoice_id IN NUMBER,
4458 p_gl_date_from_receipt IN VARCHAR2,
4459 p_last_updated_by IN NUMBER,
4460 p_last_update_login IN NUMBER,
4461 p_program_application_id IN NUMBER,
4462 p_program_id IN NUMBER,
4463 p_request_id IN NUMBER,
4464 p_system_user IN NUMBER,
4465 p_holds IN OUT NOCOPY HOLDSARRAY,
4466 p_holds_count IN OUT NOCOPY COUNTARRAY,
4467 p_release_count IN OUT NOCOPY COUNTARRAY,
4468 p_calling_sequence IN VARCHAR2)
4469 IS
4470 l_ok_to_withhold VARCHAR2(30);
4471 l_withholding_amount NUMBER;
4472 l_withholding_date DATE;
4473 l_invoice_num VARCHAR2(50);
4474 l_return_string VARCHAR2(2000);
4475 l_withhold_error_exists VARCHAR2(1);
4476 l_debug_loc VARCHAR2(30) := 'Withhold_Tax_On';
4477 l_curr_calling_sequence VARCHAR2(2000);
4478 l_debug_info VARCHAR2(1000);
4479 l_calling_sequence VARCHAR2(20);
4480 BEGIN
4481
4482 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
4483
4484 l_withhold_error_exists := 'N';
4485
4486 ----------------------------------------------------
4487 -- Execute Core Withholding Tax Calculation Routine
4488 ----------------------------------------------------
4489
4490 IF (NOT Ap_Extended_Withholding_Pkg.Ap_Extended_Withholding_Active) THEN
4491 BEGIN
4492 ------------------------------------------------------------------------
4493 l_debug_info := 'Check if okay to call Withholding Routine - Core';
4494 ------------------------------------------------------------------------
4495 -- invoice has at least one distribution with a withholding tax group --
4496 -- invoice has not already been withheld by the system --
4497 -- invoice has no user non-releaseable holds (ther than AWT ERROR) --
4498 -- invoice has no manual withholding lines --
4499 ------------------------------------------------------------------------
4500 -- Perf bug 5058995
4501 -- Modify below SQL to go to base tables : AP_INVOICES_ALL and
4502 -- AP_INVOICE_DISTRIBUTIONS_ALL
4503 SELECT 'OK to call Withholding Routine',
4504 (AI.invoice_amount * NVL(AI.exchange_rate, 1)),
4505 AI.invoice_num
4506 INTO l_ok_to_withhold,
4507 l_withholding_amount,
4508 l_invoice_num
4509 FROM ap_invoices_all AI
4510 WHERE AI.invoice_id = p_invoice_id
4511 AND EXISTS (SELECT 'At least 1 dist has an AWT Group'
4512 FROM ap_invoice_distributions_all AID1
4513 WHERE AID1.invoice_id = AI.invoice_id
4514 AND AID1.awt_group_id IS NOT NULL)
4515 AND NOT EXISTS (SELECT 'Unreleased System holds exist'
4516 FROM ap_holds AH,
4517 ap_hold_codes AHC
4518 WHERE AH.invoice_id = AI.invoice_id
4519 AND AH.release_lookup_code IS NULL
4520 AND AH.hold_lookup_code <> 'AWT ERROR'
4521 AND AH.hold_lookup_code = AHC.hold_lookup_code
4522 AND AHC.user_releaseable_flag = 'N')
4523 AND NOT EXISTS (SELECT 'Manual AWT lines exist'
4524 FROM ap_invoice_distributions_all AID
4525 WHERE AID.invoice_id = AI.invoice_id
4526 AND AID.line_type_lookup_code = 'AWT'
4527 AND AID.awt_flag IN ('M', 'O'));
4528
4529 /* SELECT MAX(accounting_date)
4530 INTO l_withholding_date
4531 FROM ap_invoice_distributions
4532 WHERE invoice_id = p_invoice_id
4533 AND awt_group_id IS NOT NULL; */
4534 /* 5886500 */
4535 SELECT invoice_date
4536 INTO l_withholding_date
4537 FROM ap_invoices
4538 WHERE invoice_id = p_invoice_id;
4539
4540 EXCEPTION
4541 WHEN NO_DATA_FOUND THEN
4542 RETURN;
4543 END;
4544
4545 --------------------------------------------------
4546 l_debug_info := 'Call the Withholding API - Core';
4547 --------------------------------------------------
4548
4549 AP_WITHHOLDING_PKG.AP_DO_WITHHOLDING(
4550 p_invoice_id,
4551 l_withholding_date,
4552 'AUTOAPPROVAL',
4553 l_withholding_amount,
4554 NULL,
4555 NULL,
4556 p_last_updated_by,
4557 p_last_update_login,
4558 p_program_application_id,
4559 p_program_id,
4560 p_request_id,
4561 l_return_string);
4562 ELSE
4563
4564 ---------------------------------------------------------
4565 -- Execute Extended Withholding Tax Calculation Routine
4566 ---------------------------------------------------------
4567
4568 BEGIN
4569 ------------------------------------------------------------------------
4570 l_debug_info := 'Check if okay to call Withholding Routine - Extended';
4571 ------------------------------------------------------------------------
4572 -- invoice has at least one distribution with a withholding tax group --
4573 -- invoice has not already been withheld by the system --
4574 -- invoice has no user non-releaseable holds (ther than AWT ERROR) --
4575 -- invoice has no manual withholding lines --
4576 ------------------------------------------------------------------------
4577
4578 -- Perf bug 5058995
4579 -- Modify below SQL to go to base tables : AP_INVOICES_ALL and
4580 -- AP_INVOICE_DISTRIBUTIONS_ALL
4581 SELECT 'OK to call Withholding Routine',
4582 (AI.invoice_amount * NVL(AI.exchange_rate,1)),
4583 AI.invoice_num
4584 INTO l_ok_to_withhold,
4585 l_withholding_amount,
4586 l_invoice_num
4587 FROM ap_invoices_all AI
4588 WHERE AI.invoice_id = p_invoice_id
4589 AND NOT EXISTS (SELECT 'Unreleased System holds exist'
4590 FROM ap_holds AH,
4591 ap_hold_codes AHC
4592 WHERE AH.invoice_id = AI.invoice_id
4593 AND AH.release_lookup_code IS NULL
4594 AND AH.hold_lookup_code <> 'AWT ERROR'
4595 AND AH.hold_lookup_code = AHC.hold_lookup_code
4596 AND AHC.user_releaseable_flag = 'N')
4597 AND NOT EXISTS (SELECT 'Manual AWT lines exist'
4598 FROM ap_invoice_distributions_all AID
4599 WHERE AID.invoice_id = AI.invoice_id
4600 AND AID.line_type_lookup_code = 'AWT'
4601 AND AID.awt_flag IN ('M', 'O'));
4602
4603 SELECT MAX(accounting_date)
4604 INTO l_withholding_date
4605 FROM ap_invoice_distributions
4606 WHERE invoice_id = p_invoice_id;
4607
4608 EXCEPTION
4609 WHEN NO_DATA_FOUND THEN
4610 RETURN;
4611 END;
4612
4613 ------------------------------------------------------
4614 l_debug_info := 'Call the Withholding API - Extended';
4615 ------------------------------------------------------
4616
4617 IF INSTR(p_calling_sequence, 'AP_CANCEL_PKG') > 0 THEN
4618 l_calling_sequence := 'INVOICE CANCEL';
4619 ELSE
4620 l_calling_sequence := 'AUTOAPPROVAL';
4621 END IF;
4622
4623 AP_WITHHOLDING_PKG.AP_DO_WITHHOLDING(
4624 p_invoice_id,
4625 l_withholding_date,
4626 l_calling_sequence,
4627 l_withholding_amount,
4628 NULL,
4629 NULL,
4630 p_last_updated_by,
4631 p_last_update_login,
4632 p_program_application_id,
4633 p_program_id,
4634 p_request_id,
4635 l_return_string);
4636
4637 END IF;
4638
4639 ----------------------------------------
4640 l_debug_info := 'Process Return String';
4641 ----------------------------------------
4642
4643 IF (l_return_string <> 'SUCCESS') THEN
4644
4645 l_withhold_error_exists := 'Y';
4646
4647 END IF;
4648
4649 -------------------------------------------------------------
4650 l_debug_info := 'Process Invoice Hold Status for AWT ERROR';
4651 -------------------------------------------------------------
4652
4653 Process_Inv_Hold_Status(
4654 p_invoice_id,
4655 NULL,
4656 NULL,
4657 'AWT ERROR',
4658 l_withhold_error_exists,
4659 l_return_string,
4660 p_system_user,
4661 p_holds,
4662 p_holds_count,
4663 p_release_count,
4664 p_calling_sequence);
4665
4666 EXCEPTION
4667 WHEN OTHERS THEN
4668 IF (SQLCODE <> -20001) THEN
4669 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
4670 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
4671 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
4672 FND_MESSAGE.SET_TOKEN('PARAMETERS',
4673 'Invoice_id = '|| to_char(p_invoice_id)
4674 ||', Dist_line_num = '|| p_gl_date_from_receipt
4675 ||', Packet_id = '|| p_last_updated_by
4676 ||', Fundscheck mode = '|| p_last_update_login
4677 ||', Dist_line_num = '|| to_char(p_program_application_id)
4678 ||', Dist_line_num = '|| to_char(p_program_id)
4679 ||', Dist_line_num = '|| to_char(p_request_id));
4680 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
4681 END IF;
4682 APP_EXCEPTION.RAISE_EXCEPTION;
4683 END Withhold_Tax_On;
4684
4685
4686 /*=============================================================================
4687 | PROCEDURE UPDATE_INV_DISTS_TO_APPROVED
4688 | Procedure that updates the invoice distribution match_status_flag to
4689 | 'A' if encumbered or has no postable holds or is a reversal line,
4690 | otherwise if the invoice has postable holds then the match_status_flag
4691 | remains a 'T'.
4692 |
4693 | PARAMETERS
4694 | p_invoice_id
4695 | p_user_id
4696 | p_calling_sequence
4697 |
4698 | KNOWN ISSUES:
4699 |
4700 | NOTES:
4701 |
4702 | MODIFICATION HISTORY
4703 | Date Author Description of Change
4704 |
4705 *============================================================================*/
4706
4707 PROCEDURE Update_Inv_Dists_To_Approved(
4708 p_invoice_id IN NUMBER,
4709 p_user_id IN NUMBER,
4710 p_calling_sequence IN VARCHAR2) IS
4711
4712 l_debug_loc VARCHAR2(30) := 'Update_Inv_Dists_To_Approved';
4713 l_curr_calling_sequence VARCHAR2(2000);
4714 l_debug_info VARCHAR2(1000);
4715
4716 l_dbi_key_value_list1 ap_dbi_pkg.r_dbi_key_value_arr;
4717 l_dbi_key_value_list2 ap_dbi_pkg.r_dbi_key_value_arr;
4718
4719 BEGIN
4720
4721
4722 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
4723 p_calling_sequence;
4724
4725 ------------------------------------------------------------
4726 l_debug_info := 'Set selected dists match_status_flag to tested';
4727 Print_Debug(l_debug_loc, l_debug_info);
4728 ------------------------------------------------------------
4729
4730 UPDATE ap_invoice_distributions D
4731 SET match_status_flag = 'T',
4732 last_update_date = SYSDATE,
4733 last_updated_by = p_user_id,
4734 program_application_id = decode(fnd_global.prog_appl_id,
4735 -1,null,
4736 fnd_global.prog_appl_id),
4737 request_id = decode(fnd_global.conc_request_id,
4738 -1,null, fnd_global.conc_request_id),
4739 program_id = decode(fnd_global.conc_program_id,
4740 -1,null, fnd_global.conc_program_id),
4741 program_update_date = decode(fnd_global.conc_program_id,
4742 -1,null, SYSDATE)
4743 WHERE match_status_flag = 'S'
4744 AND D.invoice_id = p_invoice_id;
4745
4746 --Bug6963908
4747 UPDATE ap_self_assessed_tax_dist_all D
4748 SET match_status_flag = 'T',
4749 last_update_date = SYSDATE,
4750 last_updated_by = p_user_id,
4751 program_application_id = decode(fnd_global.prog_appl_id,
4752 -1,null,
4753 fnd_global.prog_appl_id),
4754 request_id = decode(fnd_global.conc_request_id,
4755 -1,null, fnd_global.conc_request_id),
4756 program_id = decode(fnd_global.conc_program_id,
4757 -1,null, fnd_global.conc_program_id),
4758 program_update_date = decode(fnd_global.conc_program_id,
4759 -1,null, SYSDATE)
4760 WHERE match_status_flag = 'S'
4761 AND D.invoice_id = p_invoice_id;
4762 --Bug6963908
4763
4764
4765 AP_DBI_PKG.Maintain_DBI_Summary
4766 (p_table_name => 'AP_INVOICE_DISTRIBUTIONS',
4767 p_operation => 'U',
4768 p_key_value1 => p_invoice_id,
4769 p_key_value_list => l_dbi_key_value_list1,
4770 p_calling_sequence => l_curr_calling_sequence);
4771
4772 ------------------------------------------------------------
4773 l_debug_info := 'Set Tested dists to Approved if no unpostable holds';
4774 Print_Debug(l_debug_loc, l_debug_info);
4775 ------------------------------------------------------------
4776
4777 -- BUG 4340061
4778 -- For the AWT lines we have encumbered_flag set to N in invoice-dist.
4779
4780 UPDATE ap_invoice_distributions D
4781 SET match_status_flag = 'A',
4782 packet_id = ''
4783 WHERE match_status_flag = 'T'
4784 AND D.invoice_id = p_invoice_id
4785 AND ((NOT EXISTS
4786 (SELECT invoice_id
4787 FROM ap_holds H, ap_hold_codes C
4788 WHERE H.invoice_id = D.invoice_id
4789 AND H.hold_lookup_code = C.hold_lookup_code
4790 AND ((H.release_lookup_code IS NULL) AND
4791 ((C.postable_flag = 'N') OR
4792 (C.postable_flag = 'X')))))
4793 OR (D.line_type_lookup_code<>'AWT' and
4794 (nvl(D.encumbered_flag, 'N') in ('Y','W','D','X','R','T')))
4795 OR (D.line_type_lookup_code='AWT' and
4796 (nvl(D.encumbered_flag, 'N') in ('Y','W','D','X','R')))); -- BUG 4340061
4797
4798
4799 --Bug6963908
4800 UPDATE ap_self_assessed_tax_dist_all D
4801 SET match_status_flag = 'A',
4802 packet_id = ''
4803 WHERE match_status_flag = 'T'
4804 AND D.invoice_id = p_invoice_id
4805 AND ((NOT EXISTS
4806 (SELECT invoice_id
4807 FROM ap_holds H, ap_hold_codes C
4808 WHERE H.invoice_id = D.invoice_id
4809 AND H.hold_lookup_code = C.hold_lookup_code
4810 AND ((H.release_lookup_code IS NULL) AND
4811 ((C.postable_flag = 'N') OR
4812 (C.postable_flag = 'X')))))
4813 OR (D.line_type_lookup_code<>'AWT' and
4814 (nvl(D.encumbered_flag, 'N') in ('Y','W','D','X','R','T')))
4815 OR (D.line_type_lookup_code='AWT' and
4816 (nvl(D.encumbered_flag, 'N') in ('Y','W','D','X','R')))); -- BUG 4340061
4817 --Bug6963908
4818
4819 EXCEPTION
4820 WHEN OTHERS THEN
4821 IF (SQLCODE <> -20001) THEN
4822 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
4823 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
4824 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
4825 FND_MESSAGE.SET_TOKEN('PARAMETERS',
4826 'Invoice_id = '|| to_char(p_invoice_id)
4827 || 'Run Option = ' || p_user_id);
4828 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
4829 END IF;
4830 APP_EXCEPTION.RAISE_EXCEPTION;
4831 END Update_Inv_Dists_To_Approved;
4832
4833 --============================================================================
4834 -- HOLD Processing Routines
4835 --============================================================================
4836
4837 /*=============================================================================
4838 | PROCEDURE PROCESS_INV_HOLD_STATUS
4839 | Procedure that process and invoice hold status. Determines whether to
4840 | place or release a given hold.
4841 |
4842 | PARAMETERS
4843 | p_invoice_id
4844 | p_line_location_id: Line Location Id
4845 | p_rcv_tansaction_id: rcv transaction id it is matched to
4846 | p_hold_lookup_code: Hold Lookup Code
4847 | p_should_have_hold: ('Y' or 'N') to indicate whether the invoice
4848 | should have the hold (previous parameter)
4849 | p_hold_reason: AWT ERROR parameter. The only hold whose hold reason
4850 | is not static.
4851 | p_system_user: Approval Program User Id
4852 | p_holds: Holds Array
4853 | p_holds_count: Holds Count Array
4854 | p_release_count: Release Count Array
4855 | p_calling_sequence: Debugging string to indicate path of module calls
4856 | to be printed out upon error.
4857 |
4858 | PROGRAM FLOW:
4859 | Retrieve current hold_status for current hold
4860 | IF already_on_hold
4861 | IF shoould_not_have_hold OR if p_hold_reason is different from the
4862 | exists hold reason
4863 | Release the hold
4864 | ELSIF should_have_hold and hold_status <> Released By User
4865 | IF p_hold_reason is null or existing_hold_reason id different from
4866 | p_hold_reason
4867 | Place the hold on the invoice
4868 |
4869 | KNOWN ISSUES:
4870 |
4871 | NOTES:
4872 |
4873 | MODIFICATION HISTORY
4874 | Date Author Description of Change
4875 |
4876 *============================================================================*/
4877
4878 PROCEDURE Process_Inv_Hold_Status(
4879 p_invoice_id IN NUMBER,
4880 p_line_location_id IN NUMBER,
4881 p_rcv_transaction_id IN NUMBER,
4882 p_hold_lookup_code IN VARCHAR2,
4883 p_should_have_hold IN VARCHAR2,
4884 p_hold_reason IN VARCHAR2,
4885 p_system_user IN NUMBER,
4886 p_holds IN OUT NOCOPY HOLDSARRAY,
4887 p_holds_count IN OUT NOCOPY COUNTARRAY,
4888 p_release_count IN OUT NOCOPY COUNTARRAY,
4889 p_calling_sequence IN VARCHAR2)IS
4890 l_inv_hold_status VARCHAR2(20);
4891 l_existing_hold_reason VARCHAR2(240);
4892 l_user_id NUMBER;
4893 l_resp_id NUMBER;
4894 l_debug_loc VARCHAR2(30) := 'Process_Inv_Hold_Status';
4895 l_curr_calling_sequence VARCHAR2(2000);
4896 l_debug_info VARCHAR2(1000);
4897 BEGIN
4898
4899 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
4900 p_calling_sequence;
4901
4902 l_debug_info := 'p_hold_lookup_code,p_should_have_hold,p_hold_reason,p_system_user '||p_hold_lookup_code||','||p_should_have_hold||','||p_hold_reason||','||p_system_user;
4903 Print_Debug(l_debug_loc, l_debug_info);
4904
4905
4906 Get_Hold_Status(
4907 p_invoice_id,
4908 p_line_location_id,
4909 p_rcv_transaction_id,
4910 p_hold_lookup_code,
4911 p_system_user,
4912 l_inv_hold_status,
4913 l_existing_hold_reason,
4914 l_user_id,
4915 l_resp_id,
4916 l_curr_calling_sequence);
4917
4918 IF (l_inv_hold_status = 'ALREADY ON HOLD') THEN
4919
4920 IF (p_should_have_hold = 'N') OR ((p_hold_reason IS NOT NULL) AND
4921 (l_existing_hold_reason <> p_hold_reason)) THEN
4922
4923 -------------------------------------------
4924 l_debug_info := 'Release hold if on hold and should not be on hold';
4925 Print_Debug(l_debug_loc, l_debug_info);
4926 -------------------------------------------
4927
4928 IF ( check_hold_batch_releaseable(
4929 p_hold_lookup_code,
4930 p_calling_sequence) = 'Y' ) THEN
4931
4932 Release_Hold(
4933 p_invoice_id,
4934 p_line_location_id,
4935 p_rcv_transaction_id,
4936 p_hold_lookup_code,
4937 p_holds,
4938 p_release_count,
4939 l_curr_calling_sequence);
4940 END IF;
4941 END IF;
4942
4943 ELSIF ((p_should_have_hold = 'Y') AND
4944 ((l_inv_hold_status <> 'RELEASED BY USER') OR
4945 ((p_hold_lookup_code = 'INSUFFICIENT FUNDS') AND
4946 (l_inv_hold_status <> 'ALREADY ON HOLD')))) THEN
4947
4948 -------------------------------------------
4949 l_debug_info := 'Set hold if it is not user released and needs hold';
4950 Print_Debug(l_debug_loc, l_debug_info);
4951 -------------------------------------------
4952
4953 IF ((p_hold_reason IS NULL) OR
4954 (nvl(l_existing_hold_reason,'dummy') <> p_hold_reason)) THEN
4955 IF (p_hold_lookup_code = 'INSUFFICIENT FUNDS') THEN
4956
4957 -------------------------------------------
4958 l_debug_info := 'Erase responsibility id from old insuff funds holds';
4959 Print_Debug(l_debug_loc, l_debug_info);
4960 -------------------------------------------
4961
4962 UPDATE ap_holds
4963 SET responsibility_id = NULL
4964 WHERE invoice_id = p_invoice_id
4965 AND hold_lookup_code = 'INSUFFICIENT FUNDS';
4966
4967 END IF;
4968
4969 -------------------------------------------
4970 l_debug_info := 'Set Hold';
4971 Print_Debug(l_debug_loc, l_debug_info);
4972 -------------------------------------------
4973
4974 Set_Hold(
4975 p_invoice_id,
4976 p_line_location_id,
4977 p_rcv_transaction_id,
4978 p_hold_lookup_code,
4979 p_hold_reason,
4980 p_holds,
4981 p_holds_count,
4982 l_curr_calling_sequence);
4983
4984 END IF; -- end of check p_hold_reason
4985 END IF; -- end of l_inv_hold_status
4986
4987 EXCEPTION
4988 WHEN OTHERS THEN
4989 IF (SQLCODE <> -20001) THEN
4990 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
4991 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
4992 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
4993 FND_MESSAGE.SET_TOKEN('PARAMETERS',
4994 'Invoice_id = '|| to_char(p_invoice_id)
4995 ||', Line_Location_id = '|| to_char(p_line_location_id)
4996 ||', Hold_code = '|| p_hold_lookup_code
4997 ||', Hold_reason = '|| p_hold_reason
4998 ||', Should_have_hold = '|| p_should_have_hold);
4999 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
5000 END IF;
5001 APP_EXCEPTION.RAISE_EXCEPTION;
5002 END Process_Inv_Hold_Status;
5003
5004 /*=============================================================================
5005 | PROCEDURE GET_HOLD_STATUS
5006 | Procedure to return the hold information and status of an invoice,
5007 | whether it is ALREADY ON HOLD, RELEASED BY USER or NOT ON HOLD.
5008 |
5009 | PARAMETERS
5010 | p_invoice_id
5011 | p_line_location_id: Line Location Id
5012 | p_rcv_transaction_id
5013 | p_hold_lookup_code
5014 | p_system_user
5015 | p_status
5016 | p_return_hold_reason
5017 | p_user_id
5018 | p_resp_id
5019 | p_calling_sequence: Debugging string to indicate path of module calls
5020 | to be printed out upon error.
5021 |
5022 | KNOWN ISSUES:
5023 |
5024 | NOTES:
5025 |
5026 | MODIFICATION HISTORY
5027 | Date Author Description of Change
5028 |
5029 *============================================================================*/
5030 PROCEDURE Get_Hold_Status(p_invoice_id IN NUMBER,
5031 p_line_location_id IN NUMBER,
5032 p_rcv_transaction_id IN NUMBER,
5033 p_hold_lookup_code IN VARCHAR2,
5034 p_system_user IN NUMBER,
5035 p_status IN OUT NOCOPY VARCHAR2,
5036 p_return_hold_reason IN OUT NOCOPY VARCHAR2,
5037 p_user_id IN OUT NOCOPY VARCHAR2,
5038 p_resp_id IN OUT NOCOPY VARCHAR2,
5039 p_calling_sequence IN VARCHAR2) IS
5040
5041 l_debug_loc VARCHAR2(30) := 'Get_Hold_Status';
5042 l_curr_calling_sequence VARCHAR2(2000);
5043
5044 BEGIN
5045
5046 -- Update the calling sequence --
5047
5048 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
5049
5050 p_status := 'NOT ON HOLD';
5051
5052 if g_holds_tab.count > 0 then
5053
5054 for i in g_holds_tab.first..g_holds_tab.last
5055 loop
5056 if (p_hold_lookup_code <> 'INSUFFICIENT FUNDS') then
5057
5058 if (g_holds_tab(i).invoice_id = p_invoice_id and
5059 g_holds_tab(i).hold_lookup_code = p_hold_lookup_code) then
5060
5061 if (p_line_location_id is null
5062 or g_holds_tab(i).line_location_id = p_line_location_id) and
5063 (p_rcv_transaction_id is null
5064 or g_holds_tab(i).rcv_transaction_id = p_rcv_transaction_id) and
5065 (g_holds_tab(i).release_lookup_code is null
5066 or (g_holds_tab(i).release_lookup_code is not null
5067 and g_holds_tab(i).last_updated_by <> p_system_user)) then
5068
5069 p_status := g_holds_tab(i).hold_status;
5070 p_return_hold_reason := g_holds_tab(i).hold_reason;
5071 p_user_id := g_holds_tab(i).last_updated_by;
5072 p_resp_id := g_holds_tab(i).responsibility_id;
5073
5074 end if;
5075 end if;
5076 else
5077 if (g_holds_tab(i).invoice_id = p_invoice_id and
5078 g_holds_tab(i).hold_lookup_code = p_hold_lookup_code) then
5079
5080 if (p_line_location_id is null
5081 or g_holds_tab(i).line_location_id = p_line_location_id) and
5082 (g_holds_tab(i).release_lookup_code is null
5083 or (g_holds_tab(i).release_lookup_code is not null
5084 and g_holds_tab(i).last_updated_by <> p_system_user
5085 and g_holds_tab(i).responsibility_id is not null)) then
5086
5087 p_status := g_holds_tab(i).hold_status;
5088 p_return_hold_reason := g_holds_tab(i).hold_reason;
5089 p_user_id := g_holds_tab(i).last_updated_by;
5090 p_resp_id := g_holds_tab(i).responsibility_id;
5091
5092 end if;
5093 end if;
5094 end if;
5095 end loop;
5096 end if;
5097
5098 EXCEPTION
5099 WHEN OTHERS THEN
5100 IF (SQLCODE <> -20001) THEN
5101 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
5102 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
5103 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
5104 FND_MESSAGE.SET_TOKEN('PARAMETERS',
5105 'Invoice_id = '|| to_char(p_invoice_id)
5106 ||', Line Location Id = '|| to_char(p_line_location_id)
5107 ||', System_User_id = '|| to_char(p_system_user)
5108 ||', Hold Code = '|| p_hold_lookup_code);
5109 END IF;
5110 APP_EXCEPTION.RAISE_EXCEPTION;
5111 END Get_Hold_Status;
5112
5113
5114 /*=============================================================================
5115 | PROCEDURE RELEASE_HOLD
5116 | Procedure to release a hold from an invoice and update the release
5117 | count array.
5118 |
5119 | PARAMETERS
5120 | p_invoice_id
5121 | p_line_location_id: Line Location Id
5122 | p_rcv_transaction_id
5123 | p_hold_lookup_code
5124 | p_holds
5125 | p_release_count
5126 | p_calling_sequence: Debugging string to indicate path of module calls
5127 | to be printed out upon error.
5128 |
5129 | KNOWN ISSUES:
5130 |
5131 | NOTES:
5132 |
5133 | MODIFICATION HISTORY
5134 | Date Author Description of Change
5135 |
5136 *============================================================================*/
5137
5138 PROCEDURE Release_Hold(
5139 p_invoice_id IN NUMBER,
5140 p_line_location_id IN NUMBER,
5141 p_rcv_transaction_id IN NUMBER,
5142 p_hold_lookup_code IN VARCHAR2,
5143 p_holds IN OUT NOCOPY HOLDSARRAY,
5144 p_release_count IN OUT NOCOPY COUNTARRAY,
5145 p_calling_sequence IN VARCHAR2) IS
5146 l_release_lookup_code VARCHAR2(30);
5147 l_debug_loc VARCHAR2(30) := 'Release_Hold';
5148 l_curr_calling_sequence VARCHAR2(2000);
5149 l_debug_info VARCHAR2(1000);
5150 BEGIN
5151
5152 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
5153 p_calling_sequence;
5154
5155 -------------------------------------------
5156 l_debug_info := 'Getting Release Info For Hold';
5157 Print_Debug(l_debug_loc, l_debug_info);
5158 -------------------------------------------
5159
5160 Get_Release_Lookup_For_Hold(
5161 p_hold_lookup_code,
5162 l_release_lookup_code,
5163 l_curr_calling_sequence);
5164
5165 -------------------------------------------
5166 l_debug_info := 'Updating AP_HOLDS with release info';
5167 Print_Debug(l_debug_loc, l_debug_info);
5168 -------------------------------------------
5169
5170 UPDATE ap_holds
5171 SET release_lookup_code = l_release_lookup_code,
5172 release_reason = (SELECT description
5173 FROM ap_lookup_codes
5174 WHERE lookup_code = l_release_lookup_code
5175 AND lookup_type = 'HOLD CODE'),
5176 last_update_date = sysdate,
5177 last_updated_by = 5,
5178 status_flag = 'R'
5179 WHERE invoice_id = p_invoice_id
5180 AND nvl(line_location_id, -1) = nvl(p_line_location_id, -1)
5181 AND nvl(rcv_transaction_id, -1) = nvl(rcv_transaction_id, -1)
5182 AND hold_lookup_code = p_hold_lookup_code
5183 AND nvl(status_flag, 'x') <> 'x';
5184
5185 -------------------------------------------
5186 l_debug_info := 'Adjust the Release Count';
5187 Print_Debug(l_debug_loc, l_debug_info);
5188 -------------------------------------------
5189
5190 IF (sql%rowcount >0) THEN
5191 Count_Org_Hold(
5192 p_org_id => g_org_id
5193 ,p_hold_lookup_code => p_hold_lookup_code
5194 ,p_place_or_release => 'R'
5195 ,p_calling_sequence => l_curr_calling_sequence);
5196
5197 END IF;
5198
5199 -------------------------------------------
5200 l_debug_info := 'Sync Invoice Holds Cache';
5201 Print_Debug(l_debug_loc, l_debug_info);
5202 -------------------------------------------
5203
5204 initialize_invoice_holds
5205 (p_invoice_id => p_invoice_id,
5206 p_calling_sequence => l_curr_calling_sequence);
5207
5208 AP_DBI_PKG.Maintain_DBI_Summary
5209 (p_table_name => 'AP_HOLDS',
5210 p_operation => 'U',
5211 p_key_value1 => p_invoice_id,
5212 p_calling_sequence => l_curr_calling_sequence);
5213
5214 EXCEPTION
5215 WHEN OTHERS THEN
5216 IF (SQLCODE <> -20001) THEN
5217 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
5218 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
5219 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
5220 FND_MESSAGE.SET_TOKEN('PARAMETERS',
5221 'Invoice_id = '|| to_char(p_invoice_id)
5222 ||', Hold_Code = '|| p_hold_lookup_code
5223 ||', Line Location Id = '|| (p_line_location_id));
5224 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
5225 END IF;
5226 APP_EXCEPTION.RAISE_EXCEPTION;
5227 END Release_Hold;
5228
5229 /*=============================================================================
5230 | PROCEDURE SET_HOLD
5231 | Procedure to Set an Invoice on Hold and update the hold count array.
5232 |
5233 | PARAMETERS
5234 | p_invoice_id
5235 | p_line_location_id: Line Location Id
5236 | p_rcv_transaction_id
5237 | p_hold_lookup_code
5238 | p_hold_reason
5239 | p_holds
5240 | p_hold_count
5241 | p_calling_sequence: Debugging string to indicate path of module calls
5242 | to be printed out upon error.
5243 |
5244 | KNOWN ISSUES:
5245 |
5246 | NOTES:
5247 |
5248 | MODIFICATION HISTORY
5249 | Date Author Description of Change
5250 |
5251 *============================================================================*/
5252
5253 PROCEDURE Set_Hold(
5254 p_invoice_id IN NUMBER,
5255 p_line_location_id IN NUMBER,
5256 p_rcv_transaction_id IN NUMBER,
5257 p_hold_lookup_code IN VARCHAR2,
5258 p_hold_reason IN VARCHAR2,
5259 p_holds IN OUT NOCOPY HOLDSARRAY,
5260 p_holds_count IN OUT NOCOPY COUNTARRAY,
5261 p_calling_sequence IN VARCHAR2) IS
5262 l_debug_loc VARCHAR2(30) := 'Set_Hold';
5263 l_curr_calling_sequence VARCHAR2(2000);
5264 l_debug_info VARCHAR2(1000);
5265 l_hold_id NUMBER(15);
5266 l_user_releaseable_flag VARCHAR2(1);
5267 l_initiate_workflow_flag VARCHAR2(1);
5268
5269 BEGIN
5270
5271 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
5272 p_calling_sequence;
5273
5274 -------------------------------------------
5275 l_debug_info := 'Inserting Into AP_HOLDS';
5276 Print_Debug(l_debug_loc, l_debug_info);
5277 -------------------------------------------
5278
5279 SELECT ap_holds_s.nextval
5280 INTO l_hold_id
5281 FROM DUAL;
5282
5283 INSERT INTO ap_holds (
5284 invoice_id,
5285 line_location_id,
5286 rcv_transaction_id,
5287 hold_lookup_code,
5288 last_update_date,
5289 last_updated_by,
5290 creation_date,
5291 created_by,
5292 held_by,
5293 hold_date,
5294 hold_reason,
5295 status_flag,
5296 org_id, /* Bug 3700128. MOAC Project */
5297 hold_id) -- added for Negotiation Project
5298 (SELECT p_invoice_id,
5299 p_line_location_id,
5300 p_rcv_transaction_id,
5301 p_hold_lookup_code,
5302 sysdate,
5303 5,
5304 sysdate,
5305 5,
5306 5,
5307 sysdate,
5308 substrb(nvl(p_hold_reason, description),1,240),
5309 'S',
5310 g_org_id, /* Bug 3700128. MOAC Project */
5311 l_hold_id -- Added for Negotiation.
5312 FROM ap_lookup_codes
5313 WHERE lookup_code = p_hold_lookup_code
5314 AND lookup_type = 'HOLD CODE');
5315
5316 --
5317 -- Added for Negotiation Workflow
5318 -- The Holds workflow will be initiated if the placed hold is a system
5319 -- placed user releaseable hold.
5320 -- Check if the hold placed is a user releaseable hold
5321 --
5322
5323 -------------------------------------------
5324 l_debug_info := 'Select to see if the hold is user releaseable hold';
5325 Print_Debug(l_debug_loc, l_debug_info);
5326 -------------------------------------------
5327
5328 SELECT user_releaseable_flag,
5329 initiate_workflow_flag
5330 INTO l_user_releaseable_flag,
5331 l_initiate_workflow_flag
5332 FROM ap_hold_codes
5333 WHERE hold_lookup_code = p_hold_lookup_code;
5334
5335 --
5336 -- If the hold is a user releaseable hold then we will start the
5337 -- holds workflow.
5338 --
5339
5340 IF (l_user_releaseable_flag = 'Y' AND
5341 l_initiate_workflow_flag = 'Y') THEN
5342
5343 -------------------------------------------
5344 l_debug_info := 'Start the Holds Workflow';
5345 Print_Debug(l_debug_loc, l_debug_info);
5346 -------------------------------------------
5347
5348 AP_WORKFLOW_PKG.create_hold_wf_process(l_hold_id);
5349
5350 -------------------------------------------
5351 l_debug_info := 'Started the Holds Workflow';
5352 Print_Debug(l_debug_loc, l_debug_info);
5353 -------------------------------------------
5354
5355 END IF;
5356
5357 AP_DBI_PKG.Maintain_DBI_Summary
5358 (p_table_name => 'AP_HOLDS',
5359 p_operation => 'I',
5360 p_key_value1 => p_invoice_id,
5361 p_calling_sequence => l_curr_calling_sequence);
5362
5363 -------------------------------------------
5364 l_debug_info := 'Adjust the Holds Count';
5365 Print_Debug(l_debug_loc, l_debug_info);
5366 -------------------------------------------
5367 Count_Org_Hold(
5368 p_org_id => g_org_id
5369 ,p_hold_lookup_code => p_hold_lookup_code
5370 ,p_place_or_release => 'P'
5371 ,p_calling_sequence => l_curr_calling_sequence);
5372
5373 -------------------------------------------
5374 l_debug_info := 'Sync Invoice Holds Cache';
5375 Print_Debug(l_debug_loc, l_debug_info);
5376 -------------------------------------------
5377 initialize_invoice_holds
5378 (p_invoice_id => p_invoice_id,
5379 p_calling_sequence => l_curr_calling_sequence);
5380
5381
5382 EXCEPTION
5383 WHEN OTHERS THEN
5384 IF (SQLCODE <> -20001) THEN
5385 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
5386 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
5387 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
5388 FND_MESSAGE.SET_TOKEN('PARAMETERS',
5389 'Invoice_id = '|| to_char(p_invoice_id)
5390 ||', Hold_Code = '|| p_hold_lookup_code
5391 ||', Hold_Reason = '|| p_hold_reason);
5392 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
5393 END IF;
5394 APP_EXCEPTION.RAISE_EXCEPTION;
5395 END Set_Hold;
5396
5397 /*=============================================================================
5398 | PROCEDURE COUNT_HOLD
5399 | Procedure given the hold_array and count_array, increments the
5400 | count for a given hold
5401 |
5402 | PARAMETERS
5403 | p_hold_lookup_code
5404 | p_holds
5405 | p_count
5406 | p_calling_sequence: Debugging string to indicate path of module calls
5407 | to be printed out upon error.
5408 |
5409 | KNOWN ISSUES:
5410 |
5411 | NOTES:
5412 |
5413 | MODIFICATION HISTORY
5414 | Date Author Description of Change
5415 |
5416 *============================================================================*/
5417
5418 PROCEDURE Count_Hold(
5419 p_hold_lookup_code IN VARCHAR2,
5420 p_holds IN OUT NOCOPY HOLDSARRAY,
5421 p_count IN OUT NOCOPY COUNTARRAY,
5422 p_calling_sequence IN VARCHAR2) IS
5423 l_num NUMBER;
5424 l_debug_loc VARCHAR2(30) := 'Count_Hold';
5425 l_curr_calling_sequence VARCHAR2(2000);
5426 l_debug_info VARCHAR2(1000);
5427 BEGIN
5428
5429 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
5430 p_calling_sequence;
5431
5432 FOR num IN 1..100 LOOP
5433
5434 IF ((p_holds(num) IS NULL) OR (p_holds(num) = p_hold_lookup_code)) THEN
5435
5436 l_num := to_number(num);
5437
5438 EXIT;
5439 END IF;
5440
5441 END LOOP;
5442
5443 p_holds(l_num) := p_hold_lookup_code;
5444 p_count(l_num) := nvl(p_count(l_num), 0) + 1;
5445
5446 EXCEPTION
5447 WHEN OTHERS THEN
5448 IF (SQLCODE <> -20001) THEN
5449 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
5450 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
5451 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
5452 FND_MESSAGE.SET_TOKEN('PARAMETERS',
5453 'Hold Code = '|| p_hold_lookup_code);
5454 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
5455 END IF;
5456 APP_EXCEPTION.RAISE_EXCEPTION;
5457 END Count_Hold;
5458
5459
5460 /*=============================================================================
5461 | PROCEDURE GET_RELEASE_LOOKUP_FOR_HOLD
5462 | Procedure given a hold_lookup_code retunrs the associated
5463 | return_lookup_code
5464 |
5465 | PARAMETERS
5466 | p_hold_lookup_code
5467 | p_release_lookup_code
5468 | p_calling_sequence: Debugging string to indicate path of module calls
5469 | to be printed out upon error.
5470 |
5471 | KNOWN ISSUES:
5472 |
5473 | NOTES:
5474 |
5475 | MODIFICATION HISTORY
5476 | Date Author Description of Change
5477 |
5478 *============================================================================*/
5479
5480 PROCEDURE Get_Release_Lookup_For_Hold(
5481 p_hold_lookup_code IN VARCHAR2,
5482 p_release_lookup_code IN OUT NOCOPY VARCHAR2,
5483 p_calling_sequence IN VARCHAR2) IS
5484
5485 l_debug_loc VARCHAR2(30) := 'Get_Release_Lookup_For_Hold';
5486 l_curr_calling_sequence VARCHAR2(2000);
5487 l_debug_info VARCHAR2(1000);
5488 invalid_hold EXCEPTION;
5489 BEGIN
5490
5491 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
5492 p_calling_sequence;
5493
5494 -------------------------------------------
5495 l_debug_info := 'Check hold_code to retrieve release code';
5496 Print_Debug(l_debug_loc, l_debug_info);
5497 -------------------------------------------
5498
5499
5500 --added the lookup code MILESTONE in the if statement to
5501 --release the MILESTONE hold when PO quantity or amount
5502 --matched properly and invoice validated or when HOLD released manually
5503 --as per bug6768401
5504
5505
5506 IF (p_hold_lookup_code in ('CANT CLOSE PO', 'CANT TRY PO CLOSE',
5507 'PO REQUIRED', 'QTY ORD', 'QTY REC',
5508 'AMT ORD','AMT REC',
5509 'PRICE', 'QUALITY', 'CURRENCY DIFFERENCE',
5510 'TAX DIFFERENCE', 'REC EXCEPTION',
5511 'PO NOT APPROVED', 'MAX QTY ORD',
5512 'MAX QTY REC', 'MAX AMT ORD',
5513 'MAX AMT REC','FINAL MATCHING',
5514 'MAX SHIP AMOUNT', 'MAX RATE AMOUNT',
5515 'MAX TOTAL AMOUNT','MILESTONE')) THEN
5516
5517 p_release_lookup_code := 'MATCHED';
5518
5519 ELSIF (p_hold_lookup_code = 'CANT FUNDS CHECK') THEN
5520
5521 p_release_lookup_code := 'CAN FUNDS CHECK';
5522
5523 ELSIF (p_hold_lookup_code = 'INSUFFICIENT FUNDS') THEN
5524
5525 p_release_lookup_code := 'FUNDS NOW AVAILABLE';
5526
5527 ELSIF (p_hold_lookup_code = 'AWT ERROR') THEN
5528
5529 p_release_lookup_code := 'AWT OK';
5530
5531 ELSIF (p_hold_lookup_code in ('TAX VARIANCE', 'DIST VARIANCE',
5532 'TAX AMOUNT RANGE', 'LINE VARIANCE')) THEN
5533
5534 p_release_lookup_code := 'VARIANCE CORRECTED';
5535
5536 ELSIF (p_hold_lookup_code = 'NATURAL ACCOUNT TAX') THEN
5537
5538 p_release_lookup_code := 'NATURAL ACCOUNT TAX OK';
5539
5540 ELSIF (p_hold_lookup_code = 'NO RATE') THEN
5541
5542 p_release_lookup_code := 'RATE EXISTS';
5543
5544 ELSIF (p_hold_lookup_code = 'FUTURE PERIOD') THEN
5545
5546 p_release_lookup_code := 'FUTURE OPEN';
5547
5548 ELSIF (p_hold_lookup_code = 'DIST ACCT INVALID') THEN
5549
5550 p_release_lookup_code := 'DIST ACCT VALID';
5551
5552 ELSIF (p_hold_lookup_code = 'ERV ACCT INVALID') THEN
5553
5554 p_release_lookup_code := 'ERV ACCT VALID';
5555
5556 ELSIF (p_hold_lookup_code = 'AWT ACCT INVALID') THEN
5557
5558 p_release_lookup_code := 'AWT ACCT VALID';
5559
5560 ELSIF (p_hold_lookup_code in ('AMOUNT','PREPAID AMOUNT')) THEN
5561
5562 p_release_lookup_code := 'AMOUNT LOWERED';
5563
5564 ELSIF (p_hold_lookup_code = 'VENDOR') THEN
5565
5566 p_release_lookup_code := 'VENDOR UPDATED';
5567
5568 ELSIF (p_hold_lookup_code = 'PROJECT GL DATE CLOSED') THEN
5569
5570 p_release_lookup_code := 'PROJECT GL DATE OPENED';
5571
5572 ELSIF (p_hold_lookup_code in ( 'INSUFFICIENT LINE INFO',
5573 'INVALID DEFAULT ACCOUNT',
5574 'DISTRIBUTION SET INACTIVE',
5575 'SKELETON DISTRIBUTION SET',
5576 'CANNOT OVERLAY ACCOUNT',
5577 'CANNOT EXECUTE ALLOCATION' ) ) THEN
5578 p_release_lookup_code := 'APPROVED';
5579
5580 -- 7299826 EnC Project
5581 ELSIF (p_hold_lookup_code IN ('Pay When Paid', 'PO Deliverable')) THEN
5582
5583 p_release_lookup_code := 'Automatic Release';
5584
5585 ELSE
5586 -------------------------------------------
5587 l_debug_info := 'Invalid Hold Code';
5588 Print_Debug(l_debug_loc, l_debug_info);
5589 -------------------------------------------
5590
5591 Raise Invalid_Hold;
5592 END IF;
5593
5594 EXCEPTION
5595 WHEN Invalid_Hold THEN
5596 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
5597 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
5598 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
5599 FND_MESSAGE.SET_TOKEN('PARAMETERS',
5600 'Hold Code = '|| p_hold_lookup_code
5601 ||', Release Code = '|| p_release_lookup_code);
5602 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
5603 APP_EXCEPTION.RAISE_EXCEPTION;
5604 WHEN OTHERS THEN
5605 IF (SQLCODE <> -20001) THEN
5606 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
5607 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
5608 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
5609 FND_MESSAGE.SET_TOKEN('PARAMETERS',
5610 'Hold Code = '|| p_hold_lookup_code
5611 ||', Release Code = '|| p_release_lookup_code);
5612 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
5613 END IF;
5614 APP_EXCEPTION.RAISE_EXCEPTION;
5615 END Get_Release_Lookup_For_Hold;
5616
5617
5618 /*=============================================================================
5619 | PROCEDURE GET_INVOICE_STATUSES:
5620 | Procedure given a hold_lookup_code retunrs the associated
5621 | return_lookup_code
5622 |
5623 | PARAMETERS
5624 | p_invoice_id
5625 | p_holds_count
5626 | p_approval_status
5627 | p_calling_sequence: Debugging string to indicate path of module calls
5628 | to be printed out upon error.
5629 |
5630 | KNOWN ISSUES:
5631 |
5632 | NOTES:
5633 |
5634 | MODIFICATION HISTORY
5635 | Date Author Description of Change
5636 |
5637 *============================================================================*/
5638
5639 PROCEDURE Get_Invoice_Statuses(
5640 p_invoice_id IN NUMBER,
5641 p_holds_count IN OUT NOCOPY NUMBER,
5642 p_approval_status IN OUT NOCOPY VARCHAR2,
5643 p_calling_sequence IN VARCHAR2) IS
5644
5645 CURSOR Invoice_Status_Cur IS
5646 SELECT AP_INVOICES_PKG.Get_Holds_Count(invoice_id),
5647 AP_INVOICES_PKG.Get_Approval_Status(
5648 invoice_id,
5649 invoice_amount,
5650 payment_status_flag,
5651 invoice_type_lookup_code)
5652 FROM ap_invoices
5653 WHERE invoice_id = p_invoice_id;
5654
5655 l_debug_loc VARCHAR2(30) := 'Get_Invoice_Statuses';
5656 l_curr_calling_sequence VARCHAR2(2000);
5657 l_debug_info VARCHAR2(1000);
5658 BEGIN
5659
5660 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||
5661 p_calling_sequence;
5662
5663 -------------------------------------------
5664 l_debug_info := 'Retrieving new invoice statuses';
5665 Print_Debug(l_debug_loc, l_debug_info);
5666 -------------------------------------------
5667
5668 OPEN Invoice_Status_Cur;
5669 Fetch Invoice_Status_Cur
5670 INTO p_holds_count,
5671 p_approval_status;
5672
5673 CLOSE Invoice_Status_Cur;
5674
5675 EXCEPTION
5676 WHEN OTHERS THEN
5677 IF (SQLCODE <> -20001) THEN
5678 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
5679 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
5680 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
5681 FND_MESSAGE.SET_TOKEN('PARAMETERS',
5682 'Hold Code = '|| to_char(p_invoice_id));
5683 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
5684 END IF;
5685 APP_EXCEPTION.RAISE_EXCEPTION;
5686 END Get_Invoice_Statuses;
5687
5688
5689 /*=============================================================================
5690 | PROCEDURE Check_hold_batch_releaseable
5691 | Function that returns if the hold batch is releasable.
5692 |
5693 | PARAMETERS
5694 | p_hold_name
5695 | p_calling_sequence: Debugging string to indicate path of module calls
5696 | to be printed out upon error.
5697 |
5698 | KNOWN ISSUES:
5699 |
5700 | NOTES:
5701 |
5702 | MODIFICATION HISTORY
5703 | Date Author Description of Change
5704 |
5705 *============================================================================*/
5706
5707 FUNCTION Check_hold_batch_releaseable(
5708 p_hold_name IN VARCHAR2,
5709 p_calling_sequence IN VARCHAR2) RETURN VARCHAR2
5710 IS
5711
5712 l_curr_calling_sequence VARCHAR2(2000);
5713
5714 BEGIN
5715
5716 IF ( p_hold_name = 'VENDOR' and
5717 p_calling_sequence like '%APXAPRVL%' ) THEN
5718 RETURN 'N';
5719 ELSE
5720 RETURN 'Y';
5721 END IF;
5722
5723 END Check_hold_batch_releaseable;
5724
5725 PROCEDURE Update_Total_Dist_Amount(
5726 p_invoice_id IN NUMBER,
5727 p_calling_sequence IN VARCHAR2) IS
5728
5729 l_debug_info VARCHAR2(1000);
5730 l_curr_calling_sequence VARCHAR2(2000);
5731 l_debug_loc VARCHAR2(30) := 'Update_Total_Dist_Amount';
5732
5733 BEGIN
5734
5735 -------------------------------------------
5736 l_debug_info := 'Update Total Dist Amount';
5737 Print_Debug(l_debug_loc, l_debug_info);
5738 -------------------------------------------
5739
5740 -- Fix for Bug #5107865. Replaced bulk update with single update for
5741 -- performance reasons.
5742 UPDATE ap_invoice_distributions_all id1
5743 SET (id1.total_dist_amount,
5744 id1.total_dist_base_amount) = (SELECT SUM(NVL(id2.amount,0)),
5745 SUM(NVL(id2.base_amount,0))
5746 FROM ap_invoice_distributions_all id2
5747 WHERE id2.invoice_distribution_id =
5748 id1.invoice_distribution_id
5749 OR id2.related_id =
5750 id1.invoice_distribution_id)
5751 WHERE id1.invoice_id = p_invoice_id
5752 AND id1.line_type_lookup_code NOT IN ('IPV','ERV','TIPV','TRV','TERV');
5753
5754 EXCEPTION
5755 WHEN OTHERS THEN
5756 NULL;
5757
5758 END Update_Total_Dist_Amount;
5759
5760
5761 PROCEDURE Exclude_Tax_Freight_From_Disc(
5762 p_invoice_id IN NUMBER,
5763 p_exclude_tax_from_discount IN VARCHAR2,
5764 p_exclude_freight_from_disc IN VARCHAR2,
5765 p_invoice_type_lookup_code IN VARCHAR2,
5766 p_curr_calling_sequence IN VARCHAR2) IS
5767
5768 l_debug_loc VARCHAR2(100);
5769 l_curr_calling_sequence VARCHAR2(2000);
5770 l_debug_info VARCHAR2(1000);
5771 l_purpose VARCHAR2(30);
5772 l_payment_status VARCHAR2(1);
5773 l_prepayment_app_exists VARCHAR2(1);
5774 l_discountable_amount NUMBER;
5775 l_total_tax_amount NUMBER;
5776 l_total_freight_amount NUMBER;
5777 l_validated_amount NUMBER;
5778 l_terms_id NUMBER;
5779 l_last_updated_by NUMBER;
5780 l_created_by NUMBER;
5781 l_payment_priority NUMBER;
5782 l_batch_id NUMBER;
5783 l_terms_date DATE;
5784 l_invoice_amount NUMBER;
5785 l_pay_curr_invoice_amount NUMBER;
5786 l_payment_cross_rate NUMBER;
5787 l_payment_method VARCHAR2(30);
5788 l_invoice_curr_code VARCHAR2(15);
5789 l_pay_curr_code VARCHAR2(15);
5790 l_new_amount_to_adjust NUMBER;
5791 l_new_discountable_amount NUMBER;
5792 l_total_amount_positive VARCHAR(1);
5793 l_total_amount NUMBER ;
5794 l_records_exist BOOLEAN;
5795 j NUMBER;
5796 l_invoice_date DATE;
5797 l_tmp_invoice_amount NUMBER;
5798 l_tmp_base_amount NUMBER;
5799
5800 CURSOR Prepay_Distributions IS
5801 SELECT aid.invoice_id invoice_id,
5802 aid.amount*-1 amount,
5803 l_pay_curr_code pay_currency,
5804 aid.last_updated_by user_id,
5805 aid.last_update_login last_update_login,
5806 l_curr_calling_sequence calling_sequence
5807 FROM ap_invoice_distributions aid,
5808 ap_invoice_lines ail
5809 WHERE aid.invoice_id = p_invoice_id
5810 AND ail.invoice_id = aid.invoice_id
5811 AND ail.line_number = aid.invoice_line_number
5812 --bugfix:5609186
5813 AND ail.line_type_lookup_code = 'PREPAY'
5814 AND aid.amount <> 0
5815 AND (aid.line_type_lookup_code = 'PREPAY'
5816 OR aid.charge_applicable_to_dist_id in
5817 (SELECT invoice_distribution_id
5818 FROM ap_invoice_distributions
5819 WHERE line_type_lookup_code = 'PREPAY'
5820 AND invoice_id = p_invoice_id))
5821 AND NVL(aid.invoice_includes_prepay_flag, 'N') <> 'Y';
5822
5823 TYPE t_prepay_dist_rec IS TABLE OF Prepay_Distributions%ROWTYPE
5824 INDEX BY BINARY_INTEGER;
5825
5826 v_prepay_dist_rec t_prepay_dist_rec;
5827 l_prepay_excl_tax_amt number;
5828 BEGIN
5829
5830 l_debug_loc := 'Exclude_Tax_Freight_From_Disc';
5831 l_curr_calling_sequence := 'AP_APPROVAL_PKG.Exclude_Tax_From_Discount<-'||P_curr_calling_sequence;
5832
5833 l_payment_status := 'N';
5834 l_prepayment_app_exists := 'N';
5835 l_total_amount_positive := 'N';
5836 l_total_amount := 0;
5837 l_records_exist := FALSE;
5838 j :=1;
5839
5840 ------------------------------------------------------------
5841 l_debug_info := 'Verify the Parameters and set the purpose';
5842 ------------------------------------------------------------
5843 IF p_exclude_tax_from_discount = 'Y' OR p_exclude_freight_from_disc = 'Y' THEN
5844 l_purpose := 'EXCLUDE';
5845 ELSIF (p_invoice_type_lookup_code in ('PO PRICE ADJUST','ADJUSTMENT')) THEN
5846 l_purpose := 'RETROONLY';
5847 END IF;
5848
5849 IF l_purpose = 'EXCLUDE' THEN
5850 ------------------------------------------------------------
5851 l_debug_info := 'Check if the Invoice is Paid/partially Paid';
5852 ------------------------------------------------------------
5853 BEGIN
5854 SELECT 'Y'
5855 INTO l_payment_status
5856 FROM ap_invoice_payments
5857 WHERE invoice_id = p_invoice_id
5858 AND nvl(reversal_flag,'N') <> 'Y'
5859 AND rownum<2;
5860
5861 EXCEPTION
5862 WHEN OTHERS THEN
5863 l_payment_status := 'N';
5864 END;
5865
5866 IF l_payment_status <> 'N' THEN
5867 RETURN;
5868 END IF;
5869
5870 ------------------------------------------------------------
5871 l_debug_info := 'Check if Prepayment Application Exists';
5872 ------------------------------------------------------------
5873 BEGIN
5874 SELECT 'Y'
5875 INTO l_prepayment_app_exists
5876 FROM ap_invoice_lines
5877 WHERE invoice_id = p_invoice_id
5878 AND line_type_lookup_code = 'PREPAY'
5879 AND rownum < 2;
5880 EXCEPTION
5881 WHEN OTHERS THEN
5882 l_prepayment_app_exists := 'N';
5883 END;
5884
5885 ------------------------------------------------------------
5886 l_debug_info := 'Get Required Info From Invoice Header';
5887 ------------------------------------------------------------
5888
5889 BEGIN
5890 SELECT amount_applicable_to_discount,
5891 decode(p_exclude_tax_from_discount,
5892 'Y',nvl(total_tax_amount,0),0),
5893 nvl(validated_tax_amount,0),
5894 terms_id,
5895 last_updated_by,
5896 created_by,
5897 batch_id,
5898 terms_date,
5899 invoice_amount,
5900 nvl(pay_curr_invoice_amount, invoice_amount),
5901 payment_cross_rate,
5902 payment_method_code, --4552701
5903 invoice_currency_code,
5904 payment_currency_code,
5905 invoice_date
5906 INTO l_discountable_amount,
5907 l_total_tax_amount,
5908 l_validated_amount,
5909 l_terms_id,
5910 l_last_updated_by,
5911 l_created_by,
5912 l_batch_id,
5913 l_terms_date,
5914 l_invoice_amount,
5915 l_pay_curr_invoice_amount,
5916 l_payment_cross_rate,
5917 l_payment_method,
5918 l_invoice_curr_code,
5919 l_pay_curr_code,
5920 l_invoice_date
5921 FROM ap_invoices
5922 WHERE invoice_id = p_invoice_id;
5923
5924 EXCEPTION
5925 WHEN OTHERS THEN
5926 RETURN;
5927 END;
5928
5929 IF (p_exclude_freight_from_disc = 'Y') THEN
5930 SELECT NVL(SUM(nvl(ail.amount,0)),0)
5931 INTO l_total_freight_amount
5932 FROM ap_invoice_lines ail
5933 WHERE ail.invoice_id = p_invoice_id
5934 AND ail.line_type_lookup_code = 'FREIGHT'
5935 AND nvl(ail.discarded_flag,'N') <> 'Y';
5936 ELSE
5937 l_total_freight_amount := 0;
5938 END IF;
5939
5940 ------------------------------------------------------------
5941 l_debug_info := 'Get the net Tax Amount to Adjust';
5942 ------------------------------------------------------------
5943
5944 l_new_amount_to_adjust := (l_total_tax_amount+l_total_freight_amount) - l_validated_amount;
5945 IF l_new_amount_to_adjust <> 0 THEN
5946 ------------------------------------------------------------
5947 l_debug_info := 'Get new discountable Amount';
5948 ------------------------------------------------------------
5949 l_new_discountable_amount := l_discountable_amount
5950 - l_new_amount_to_adjust;
5951 ------------------------------------------------------------
5952 l_debug_info := 'Recreate the Payment Schedules';
5953 ------------------------------------------------------------
5954 /* bug 4931755. Procedure Create_Payment_Schedules was called before */
5955 AP_CREATE_PAY_SCHEDS_PKG.Ap_Create_From_Terms
5956 (p_invoice_id,
5957 l_terms_id,
5958 l_last_updated_by,
5959 l_created_by,
5960 null,
5961 l_batch_id,
5962 l_terms_date,
5963 l_invoice_amount,
5964 l_pay_curr_invoice_amount,
5965 l_payment_cross_rate,
5966 l_new_discountable_amount,
5967 l_payment_method,
5968 l_invoice_curr_code,
5969 l_pay_curr_code,
5970 l_curr_calling_sequence);
5971
5972 ---------------------------------------------------------------
5973 l_debug_info := 'Update Pay Schedules if Prepayment APP Exists';
5974 --------------------------------------------------------------
5975
5976 IF l_prepayment_app_exists = 'Y' THEN
5977
5978 OPEN Prepay_Distributions;
5979
5980 loop
5981 fetch Prepay_Distributions into v_prepay_dist_rec(j);
5982 exit when Prepay_Distributions%notfound;
5983 j:=j+1;
5984 end loop;
5985
5986 CLOSE Prepay_Distributions;
5987
5988 IF v_prepay_dist_rec.COUNT > 0 THEN
5989
5990 FOR i IN v_prepay_dist_rec.FIRST .. v_prepay_dist_rec.LAST LOOP
5991 l_total_amount := l_total_amount + v_prepay_dist_rec(i).amount;
5992 l_records_exist := TRUE;
5993 END LOOP;
5994
5995 IF l_records_exist THEN
5996
5997 --bugfix:5638734
5998 -- Get the exculusive tax amount for the prepay appln line.
5999 SELECT sum(aid.amount)
6000 INTO l_prepay_excl_tax_amt
6001 FROM ap_invoice_lines_all ail,ap_invoice_distributions_all aid
6002 WHERE ail.line_type_lookup_code='TAX'
6003 AND ail.invoice_id=p_invoice_id
6004 AND aid.invoice_id=ail.invoice_id
6005 AND aid.invoice_line_number=ail.line_number
6006 AND ail.prepay_line_number is not null;
6007
6008 l_total_amount:= l_total_amount - nvl(l_prepay_excl_tax_amt,0);
6009
6010 IF l_total_amount > 0 THEN
6011 l_total_amount_positive := 'Y';
6012 ELSE
6013 l_total_amount_positive := 'N';
6014 END IF;
6015
6016 IF l_total_amount <> 0 THEN
6017
6018 Update_Payment_Schedule_Prepay(
6019 p_invoice_id,
6020 l_total_amount,
6021 l_total_amount_positive,
6022 v_prepay_dist_rec(1).pay_currency,
6023 v_prepay_dist_rec(1).user_id,
6024 v_prepay_dist_rec(1).last_update_login,
6025 v_prepay_dist_rec(1).calling_sequence);
6026
6027 END IF;
6028
6029 END IF;
6030
6031 END IF;
6032
6033 END IF;
6034
6035 --Exclude the manual withholding tax from the payment schedules
6036 Manual_Withhold_tax( p_invoice_id,
6037 5,
6038 5,
6039 l_curr_calling_sequence);
6040
6041 --Bug 7393338 added the below call to update amount remaining on payment schedule
6042 Update_Pay_Sched_For_Awt( p_invoice_id,
6043 5,
6044 5,
6045 l_curr_calling_sequence);
6046 ------------------------------------------------------------
6047 l_debug_info := 'Update Invoice Header';
6048 ------------------------------------------------------------
6049
6050 UPDATE ap_invoices
6051 SET amount_applicable_to_discount = l_new_discountable_amount,
6052 validated_tax_amount = l_total_tax_amount+l_total_freight_amount
6053 WHERE invoice_id = p_invoice_id;
6054
6055
6056 END IF;
6057
6058 ELSE -- Retro Price Case
6059
6060 l_debug_info := 'Retro price case';
6061 Print_Debug(l_debug_loc,l_debug_info);
6062
6063 SELECT sum(nvl(amount,0)),
6064 sum(nvl(base_amount,0))
6065 INTO l_tmp_invoice_amount,
6066 l_tmp_base_amount
6067 FROM ap_invoice_distributions_all
6068 WHERE invoice_id = p_invoice_id
6069 AND ((line_type_lookup_code NOT IN ('PREPAY', 'AWT')
6070 AND prepay_distribution_id IS NULL)
6071 OR nvl(invoice_includes_prepay_flag,'N') = 'Y');
6072
6073 UPDATE ap_invoices
6074 SET invoice_amount = l_tmp_invoice_amount,
6075 amount_applicable_to_discount = l_tmp_invoice_amount,
6076 base_amount = l_tmp_base_amount,
6077 pay_curr_invoice_amount = decode(invoice_currency_code,
6078 nvl(payment_currency_code,invoice_currency_code), l_tmp_invoice_amount,
6079 gl_currency_api.convert_amount
6080 (invoice_currency_code,
6081 nvl(payment_currency_code,invoice_currency_code),
6082 payment_cross_rate_date,
6083 payment_cross_rate_type,
6084 l_tmp_invoice_amount))
6085 WHERE invoice_id = p_invoice_id;
6086
6087 ------------------------------------------------------------
6088 l_debug_info := 'Get Required Info From Invoice Header';
6089 ------------------------------------------------------------
6090 BEGIN
6091 SELECT amount_applicable_to_discount,
6092 nvl(total_tax_amount,0),
6093 nvl(validated_tax_amount,0),
6094 terms_id,
6095 last_updated_by,
6096 created_by,
6097 batch_id,
6098 terms_date,
6099 invoice_amount,
6100 pay_curr_invoice_amount,
6101 payment_cross_rate,
6102 payment_method_code, --4552701
6103 invoice_currency_code,
6104 payment_currency_code
6105 INTO l_discountable_amount,
6106 l_total_tax_amount,
6107 l_validated_amount,
6108 l_terms_id,
6109 l_last_updated_by,
6110 l_created_by,
6111 l_batch_id,
6112 l_terms_date,
6113 l_invoice_amount,
6114 l_pay_curr_invoice_amount,
6115 l_payment_cross_rate,
6116 l_payment_method,
6117 l_invoice_curr_code,
6118 l_pay_curr_code
6119 FROM ap_invoices
6120 WHERE invoice_id = p_invoice_id;
6121
6122 EXCEPTION
6123 WHEN OTHERS THEN
6124 RETURN;
6125 END;
6126
6127 ------------------------------------------------------------
6128 l_debug_info := 'Recreate the Payment Schedules: '|| l_invoice_amount;
6129 Print_Debug(l_debug_loc,l_debug_info);
6130 ------------------------------------------------------------
6131
6132 AP_CREATE_PAY_SCHEDS_PKG.AP_Create_From_Terms
6133 (p_invoice_id,
6134 l_terms_id,
6135 l_last_updated_by,
6136 l_created_by,
6137 null,
6138 l_batch_id,
6139 l_terms_date,
6140 l_invoice_amount,
6141 l_pay_curr_invoice_amount,
6142 l_payment_cross_rate,
6143 l_discountable_amount,
6144 l_payment_method,
6145 l_invoice_curr_code,
6146 l_pay_curr_code,
6147 l_curr_calling_sequence);
6148 END IF;
6149
6150 EXCEPTION
6151 WHEN OTHERS THEN
6152 IF (SQLCODE <> -20001) THEN
6153 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
6154 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
6155 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
6156 FND_MESSAGE.SET_TOKEN('PARAMETERS',
6157 ', Invoice Id = '|| to_char(p_invoice_id)
6158 ||', Exclude Tax from Discount = '|| p_exclude_tax_from_discount
6159 ||', Invoice Type = '|| p_invoice_type_lookup_code );
6160 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
6161 END IF;
6162 APP_EXCEPTION.RAISE_EXCEPTION;
6163
6164 END Exclude_Tax_Freight_From_Disc;
6165
6166
6167
6168 -------------------------------------------------------------------------------
6169 --This procedure update payment schedules automatically for invoices
6170 --where prepayment is applied. This will be called from the prcedure
6171 -- Exclude_Tax_Freight_From_Discount for the feature as described in the description of
6172 -- the former procedure. A similar procedure exists in prepayment package
6173 -- however due to some restriction we are creating the procedure here. This
6174 -- procedure will not update ap_invoices, but will update payment schedule.
6175 -------------------------------------------------------------------------------
6176
6177 PROCEDURE update_payment_schedule_prepay(
6178 p_invoice_id IN NUMBER,
6179 p_apply_amount IN NUMBER,
6180 p_amount_positive IN VARCHAR2,
6181 p_payment_currency_code IN VARCHAR2,
6182 p_user_id IN NUMBER,
6183 p_last_update_login IN NUMBER,
6184 p_calling_sequence IN VARCHAR2) AS
6185 l_debug_info VARCHAR2(1000);
6186 l_current_calling_sequence VARCHAR2(2000);
6187 l_apply_amount_remaining NUMBER;
6188 l_cursor_payment_num NUMBER;
6189 l_cursor_amount NUMBER;
6190
6191 CURSOR Schedules IS
6192 SELECT payment_num,
6193 DECODE(p_amount_positive,
6194 'N', gross_amount - amount_remaining,
6195 amount_remaining)
6196 --
6197 -- If unapplying prepayment, we want to get the amount paid, else
6198 -- we want to get amount remaining so we won't overapply.
6199 --
6200 FROM ap_payment_schedules
6201 WHERE invoice_id = p_invoice_id
6202 AND (payment_status_flag||'' = 'P'
6203 OR payment_status_flag||'' = DECODE(p_amount_positive, 'N', 'Y', 'N'))
6204 ORDER BY DECODE(p_amount_positive,
6205 'N', DECODE(payment_status_flag,'P',1,'Y',2,3),
6206 DECODE(NVL(hold_flag,'N'),'N',1,2)),
6207 DECODE(p_amount_positive,
6208 'N', due_date,
6209 NULL) DESC,
6210 DECODE(p_amount_positive,
6211 'Y', due_date,
6212 NULL),
6213 DECODE(p_amount_positive,
6214 'N', DECODE(hold_flag,'N',1,'Y',2,3),
6215 DECODE(NVL(payment_status_flag,'N'),'P',1,'N',2,3));
6216 BEGIN
6217 -- Update the calling sequence
6218 l_current_calling_sequence := 'update_payment_schedule_prepay<-'||
6219 p_calling_sequence;
6220 IF (p_invoice_id IS NULL OR
6221 p_apply_amount IS NULL OR
6222 p_amount_positive IS NULL OR
6223 p_payment_currency_code IS NULL) THEN
6224
6225 RAISE NO_DATA_FOUND;
6226 END IF;
6227 --
6228 -- l_amount_apply_remaining will keep track of the apply amount that is
6229 -- remaining to be factored into amount remaining.
6230 --
6231
6232 l_apply_amount_remaining := p_apply_amount;
6233 --
6234 -- Open schedule ,fetch payment_num and amount into local variable array
6235 --
6236 l_debug_info := 'Open Payment Schedule Cursor';
6237
6238 OPEN SCHEDULES;
6239 LOOP
6240 l_debug_info := 'Fetch Schedules into local variables';
6241
6242 FETCH SCHEDULES INTO l_cursor_payment_num, l_cursor_amount;
6243
6244 EXIT WHEN SCHEDULES%NOTFOUND;
6245
6246 if ((((l_apply_amount_remaining - l_cursor_amount) <= 0) AND
6247 (p_amount_positive = 'Y')) OR
6248 (((l_apply_amount_remaining + l_cursor_amount) >= 0) AND
6249 (p_amount_positive = 'N'))) then
6250
6251 /*-----------------------------------------------------------------------+
6252 * Case 1 for *
6253 * 1. In apply prepayment(amount_positive = 'Y'), the amount remaining *
6254 * is greater than apply amount remaining. *
6255 * 2. In unapply prepayment, the apply amount (actually unapply amount *
6256 * here) is greater than amount_paid (gross amount-amount remaining).*
6257 * *
6258 * It means that this schedule line has enough amount to apply(unapply) *
6259 * the whole apply_amount. *
6260 * *
6261 * Update the amount remaining for this payment schedule line so that: *
6262 * (amount remaining - apply amount remaining). *
6263 +-----------------------------------------------------------------------*/
6264
6265 l_debug_info := 'Update ap_payment_schedule for the invoice, case 1';
6266
6267 UPDATE ap_payment_schedules
6268 SET amount_remaining = (amount_remaining -
6269 ap_utilities_pkg.ap_round_currency(
6270 l_apply_amount_remaining,
6271 p_payment_currency_code)),
6272 payment_status_flag =
6273 DECODE(amount_remaining -
6274 ap_utilities_pkg.ap_round_currency(
6275 l_apply_amount_remaining,
6276 p_payment_currency_code),
6277 0,'Y',
6278 gross_amount, 'N',
6279 'P'),
6280 last_update_date = SYSDATE,
6281 last_updated_by = p_user_id,
6282 last_update_login = p_last_update_login
6283 WHERE invoice_id = p_invoice_id
6284 AND payment_num = l_cursor_payment_num;
6285
6286 EXIT;
6287
6288 /* No more amount left */
6289
6290 else
6291
6292 /*----------------------------------------------------------------------*
6293 *Case 2 for this line don't have enough amount to apply(unapply). *
6294 * *
6295 * Update the amount_remaining to 0 and amount_apply_remaining become *
6296 * (amount_apply - amount_remaining(this line)), then go to next *
6297 * schedule line. *
6298 *----------------------------------------------------------------------*/
6299
6300 l_debug_info := 'Update ap_payment_schedule for the invoice, case 2';
6301
6302 UPDATE ap_payment_schedules
6303 SET amount_remaining = DECODE(p_amount_positive,
6304 'Y', 0,
6305 gross_amount),
6306 payment_status_flag = DECODE(p_amount_positive,
6307 'Y', 'Y',
6308 'N'),
6309 last_update_date = SYSDATE,
6310 last_updated_by = p_user_id,
6311 last_update_login = p_last_update_login
6312 WHERE invoice_id = p_invoice_id
6313 AND payment_num = l_cursor_payment_num;
6314
6315 if (p_amount_positive = 'Y') then
6316 l_apply_amount_remaining := l_apply_amount_remaining - l_cursor_amount;
6317 else
6318 l_apply_amount_remaining := l_apply_amount_remaining + l_cursor_amount;
6319 end if;
6320
6321 end if;
6322
6323 END LOOP;
6324
6325 l_debug_info := 'Close Schedule Cursor';
6326
6327 CLOSE SCHEDULES;
6328
6329 --Bug 4539462 DBI logging
6330 AP_DBI_PKG.Maintain_DBI_Summary
6331 (p_table_name => 'AP_INVOICES',
6332 p_operation => 'U',
6333 p_key_value1 => P_invoice_id,
6334 p_calling_sequence => l_current_calling_sequence);
6335
6336 EXCEPTION
6337 WHEN OTHERS then
6338 if (SQLCODE <> -20001 ) then
6339 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
6340 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
6341 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',l_current_calling_sequence);
6342
6343 FND_MESSAGE.SET_TOKEN('PARAMETERS','Invoice_id = '||TO_CHAR(p_invoice_id)
6344 ||' Apply_amount = '||TO_CHAR(p_apply_amount)
6345 ||' Amount_positive = '||p_amount_positive
6346 ||' Apply_amount_remaining = '||
6347 TO_CHAR(l_apply_amount_remaining)
6348 ||' Cursor_amount = '||TO_CHAR(l_cursor_amount)
6349 ||' Cursor_Payment_num = '||TO_CHAR(l_cursor_payment_num)
6350 ||' User_id = '||TO_CHAR(p_user_id)
6351 ||' Last_update_login = '||TO_CHAR(p_last_update_login)
6352 ||' Payment_Currency_code = '||p_payment_currency_code);
6353
6354 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
6355
6356 end if;
6357
6358 APP_EXCEPTION.RAISE_EXCEPTION;
6359
6360 END update_payment_schedule_prepay;
6361
6362
6363 --============================================================================
6364 -- MANUAL_WITHHOLD_TAX: Procedure that update payment schedules
6365 -- to reflect the manual withholding amount
6366 --============================================================================
6367 PROCEDURE Manual_Withhold_Tax(p_invoice_id IN NUMBER,
6368 p_last_updated_by IN NUMBER,
6369 p_last_update_login IN NUMBER,
6370 p_calling_sequence IN VARCHAR2) IS
6371 l_manual_awt_amount ap_invoice_distributions.amount%TYPE :=0;
6372 l_payment_cross_rate ap_invoices.payment_cross_rate%TYPE;
6373 l_pay_curr_code ap_invoices.payment_currency_code%TYPE;
6374 l_num_payments NUMBER := 0;
6375 l_invoice_type ap_invoices.invoice_type_lookup_code%TYPE;--1724924
6376 l_inv_amt_remaining ap_payment_schedules.amount_remaining%TYPE := 0;
6377 l_gross_amount ap_payment_schedules.gross_amount%TYPE := 0;
6378 l_debug_loc VARCHAR2(30) := 'Manual_Withhold_Tax';
6379 l_curr_calling_sequence VARCHAR2(2000);
6380
6381 BEGIN
6382
6383 -- AP_LOGGING_PKG.AP_Begin_Block(l_debug_loc);
6384
6385 -- Update the calling sequence --
6386
6387 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
6388
6389 -- Initialize local variables
6390 -- BUG 4340061 : For the lines which have been already been validated but the invoice has been placed on hold.
6391
6392 SELECT sum( nvl(amount, 0) )
6393 INTO l_manual_awt_amount
6394 FROM ap_invoice_distributions
6395 WHERE invoice_id = p_invoice_id
6396 AND nvl(match_status_flag, 'N') in ('N','T') -- BUG 4340061
6397 AND line_type_lookup_code = 'AWT'
6398 AND awt_flag in ('M', 'O');
6399
6400
6401 SELECT sum(nvl(amount_remaining,0)), sum(nvl(gross_amount,0))
6402 INTO l_inv_amt_remaining, l_gross_amount
6403 FROM ap_payment_schedules
6404 WHERE invoice_id = p_invoice_id;
6405
6406 SELECT payment_cross_rate,
6407 payment_currency_code,
6408 invoice_type_lookup_code --Bug 1724924
6409 INTO l_payment_cross_rate,
6410 l_pay_curr_code,
6411 l_invoice_type --Bug 1724924
6412 FROM ap_invoices
6413 WHERE invoice_id = p_invoice_id;
6414
6415 --===================================================================
6416 --Prorate the manual AWT against the invoice amount remaining
6417 --===================================================================
6418 --Bug 1985604 - Modified if condition
6419
6420 -- Bug 2636774. Checking if the manual_awt_amount is <> 0 instead of
6421 -- not null. This check will ensure that the payment schedule will not
6422 -- be updated for cancelled invoices.
6423
6424 -- BUG 4344086 : if condition added. If l_gross_amount = 0 means, the
6425 -- invoice is either cancelled or is of 0$
6426 if l_gross_amount = 0
6427 then
6428 update ap_payment_schedules
6429 set amount_remaining = 0
6430 where invoice_id = p_invoice_id;
6431
6432 elsif ((l_inv_amt_remaining <> 0) and (nvl(l_manual_awt_amount,0) <> 0))
6433 then
6434
6435 update ap_payment_schedules
6436 set amount_remaining = (amount_remaining +
6437 ap_utilities_pkg.ap_round_currency(
6438 (amount_remaining * (l_manual_awt_amount/l_inv_amt_remaining)
6439 * l_payment_cross_rate), l_pay_curr_code ) )
6440 where invoice_id = p_invoice_id;
6441
6442 elsif ((l_inv_amt_remaining = 0) and (nvl(l_manual_awt_amount,0) <> 0))
6443 then
6444
6445 update ap_payment_schedules
6446 set amount_remaining =
6447 (amount_remaining +
6448 ap_utilities_pkg.ap_round_currency(
6449 (gross_amount * (l_manual_awt_amount/l_gross_amount)
6450 * l_payment_cross_rate), l_pay_curr_code) ),
6451 payment_status_flag = DECODE(payment_status_flag,
6452 'Y','P',payment_status_flag)
6453 where invoice_id = p_invoice_id;
6454
6455 update ap_invoices
6456 set payment_status_flag = DECODE(payment_status_flag,
6457 'Y','P',payment_status_flag)
6458 where invoice_id = p_invoice_id;
6459
6460 end if;
6461
6462
6463 EXCEPTION
6464 when OTHERS then
6465 IF (SQLCODE <> -20001) THEN
6466 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
6467 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
6468 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',p_calling_sequence);
6469 FND_MESSAGE.SET_TOKEN('PARAMETERS',
6470 ' Invoice Id = ' || to_char(P_Invoice_Id) ||
6471 ', Calling module = ' || 'Manual_withhold_tax' );
6472 END IF;
6473 APP_EXCEPTION.RAISE_EXCEPTION;
6474
6475 END Manual_Withhold_Tax;
6476
6477 /* Added the following procedure for 7393338 */
6478 --============================================================================
6479 -- Update_Pay_Sched_For_Awt: Procedure that update payment schedules
6480 -- to reflect the Automatic withholding amount
6481 --============================================================================
6482
6483
6484 PROCEDURE Update_Pay_Sched_For_Awt(p_invoice_id IN NUMBER,
6485 p_last_updated_by IN NUMBER,
6486 p_last_update_login IN NUMBER,
6487 p_calling_sequence IN VARCHAR2) IS
6488 CURSOR Update_payment_schedule IS
6489 SELECT payment_num,gross_amount,amount_remaining
6490 FROM ap_payment_schedules
6491 WHERE invoice_id=p_invoice_id;
6492 l_automatic_awt_amount ap_invoice_distributions.amount%TYPE :=0;
6493 l_payment_cross_rate ap_invoices.payment_cross_rate%TYPE;
6494 l_pay_curr_code ap_invoices.payment_currency_code%TYPE;
6495 l_num_payments NUMBER := 0;
6496 l_invoice_type ap_invoices.invoice_type_lookup_code%TYPE;
6497 l_inv_amt_remaining ap_payment_schedules.amount_remaining%TYPE := 0;
6498 l_gross_amount ap_payment_schedules.gross_amount%TYPE := 0;
6499 l_payment_num ap_payment_schedules.payment_num%TYPE;
6500 l_debug_loc VARCHAR2(30) := 'Update_Pay_Sched_For_Awt';
6501 l_curr_calling_sequence VARCHAR2(2000);
6502 l_wt_amt_to_subtract NUMBER := 0;
6503 BEGIN
6504
6505
6506 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
6507
6508
6509 SELECT (0 - sum(nvl(amount,0)))
6510 INTO l_automatic_awt_amount
6511 FROM ap_invoice_distributions
6512 WHERE invoice_id = p_invoice_id
6513 AND line_type_lookup_code = 'AWT'
6514 AND awt_flag = 'A';
6515
6516 IF l_automatic_awt_amount <> 0 then
6517
6518 SELECT payment_cross_rate,
6519 payment_currency_code,
6520 invoice_type_lookup_code
6521 INTO l_payment_cross_rate,
6522 l_pay_curr_code,
6523 l_invoice_type
6524 FROM ap_invoices
6525 WHERE invoice_id = p_invoice_id;
6526
6527
6528 OPEN Update_payment_schedule;
6529
6530 LOOP
6531 FETCH Update_payment_schedule into l_payment_num,l_gross_amount,l_inv_amt_remaining;
6532 EXIT WHEN Update_payment_schedule%NOTFOUND;
6533 SELECT nvl(ap_utilities_pkg.ap_round_currency(
6534 l_automatic_awt_amount*
6535 ai.payment_cross_rate,l_pay_curr_code),0)*
6536 l_gross_amount/decode(ai.pay_curr_invoice_amount, 0, 1,
6537 nvl(ai.pay_curr_invoice_amount, 1))
6538 into l_wt_amt_to_subtract
6539 from ap_invoices ai
6540 where ai.invoice_id=p_invoice_id;
6541
6542 --===================================================================
6543 --Prorate the automatic AWT against the invoice amount remaining
6544 --===================================================================
6545 if l_gross_amount = 0 then
6546 update ap_payment_schedules
6547 set amount_remaining = 0
6548 where invoice_id = p_invoice_id
6549 and payment_num=l_payment_num;
6550
6551 elsif ((l_inv_amt_remaining <> 0) and (nvl(l_wt_amt_to_subtract,0) <> 0))
6552 then
6553
6554 update ap_payment_schedules
6555 set amount_remaining = (amount_remaining -
6556 ap_utilities_pkg.ap_round_currency(
6557 (amount_remaining * ( l_wt_amt_to_subtract/l_inv_amt_remaining)
6558 * l_payment_cross_rate), l_pay_curr_code ) )
6559 where invoice_id = p_invoice_id
6560 and payment_num=l_payment_num;
6561
6562 End If;
6563 update ap_payment_schedules
6564 set payment_status_flag ='Y'
6565 where invoice_id = p_invoice_id
6566 and payment_num=l_payment_num
6567 and amount_remaining = 0
6568 and nvl(payment_status_flag,'N') <> 'Y';
6569 END LOOP;
6570 CLOSE Update_payment_schedule;
6571
6572 END IF;
6573
6574 EXCEPTION
6575 when OTHERS then
6576 IF (SQLCODE <> -20001) THEN
6577 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
6578 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
6579 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',p_calling_sequence);
6580 FND_MESSAGE.SET_TOKEN('PARAMETERS',
6581 ' Invoice Id = ' || to_char(P_Invoice_Id) ||
6582 ', Calling module = ' || 'Update_Pay_Sched_For_Awt' );
6583 END IF;
6584 APP_EXCEPTION.RAISE_EXCEPTION;
6585
6586 END Update_Pay_Sched_For_Awt;
6587
6588 --============================================================================
6589 -- createPaymentSchedules: Procedure that creates payment schedules
6590 -- for invoice (request) if not yet
6591 --============================================================================
6592 PROCEDURE createPaymentSchedules(p_invoice_id IN NUMBER,
6593 p_calling_sequence IN VARCHAR2) IS
6594 l_discountable_amount NUMBER;
6595 l_total_tax_amount NUMBER;
6596 l_total_freight_amount NUMBER;
6597 l_validated_amount NUMBER;
6598 l_terms_id NUMBER;
6599 l_last_updated_by NUMBER;
6600 l_created_by NUMBER;
6601 l_payment_priority NUMBER;
6602 l_batch_id NUMBER;
6603 l_terms_date DATE;
6604 l_invoice_amount NUMBER;
6605 l_pay_curr_invoice_amount NUMBER;
6606 l_payment_method VARCHAR2(30);
6607 l_payment_cross_rate ap_invoices.payment_cross_rate%TYPE;
6608 l_invoice_curr_code VARCHAR2(15);
6609 l_pay_curr_code VARCHAR2(15);
6610 l_debug_info VARCHAR2(200);
6611 l_debug_loc VARCHAR2(30) := 'createPaymentSchedules';
6612 l_schedule_count NUMBER := 0;
6613 l_curr_calling_sequence VARCHAR2(2000);
6614
6615 BEGIN
6616
6617 l_curr_calling_sequence := 'AP_APPROVAL_PKG.createPaymentSchedules <- '||P_calling_sequence;
6618
6619 select count(*)
6620 into l_schedule_count
6621 from ap_payment_schedules_all
6622 where invoice_id = p_invoice_id;
6623
6624 -------------------------------------------
6625 l_debug_info := 'createPaymentSchedules - payment schedule count = ' || l_schedule_count;
6626 Print_Debug(l_debug_loc, l_debug_info);
6627 -------------------------------------------
6628
6629 if ( l_schedule_count <= 0 ) then
6630
6631 -------------------------------------------
6632 l_debug_info := 'Get Required Info From Invoice Header';
6633 Print_Debug(l_debug_loc, l_debug_info);
6634 -------------------------------------------
6635
6636 BEGIN
6637 SELECT invoice_amount, -- TODO: amount_applicable_to_discount,
6638 terms_id,
6639 last_updated_by,
6640 created_by,
6641 batch_id,
6642 terms_date,
6643 invoice_amount,
6644 nvl(pay_curr_invoice_amount, invoice_amount),
6645 payment_cross_rate,
6646 payment_method_code, --4552701
6647 invoice_currency_code,
6648 payment_currency_code
6649 INTO l_discountable_amount,
6650 l_terms_id,
6651 l_last_updated_by,
6652 l_created_by,
6653 l_batch_id,
6654 l_terms_date,
6655 l_invoice_amount,
6656 l_pay_curr_invoice_amount,
6657 l_payment_cross_rate,
6658 l_payment_method,
6659 l_invoice_curr_code,
6660 l_pay_curr_code
6661 FROM ap_invoices
6662 WHERE invoice_id = p_invoice_id;
6663
6664 EXCEPTION
6665 WHEN OTHERS THEN
6666 RETURN;
6667 END;
6668
6669 -- create payment schedules
6670 AP_CREATE_PAY_SCHEDS_PKG.Create_Payment_Schedules
6671 (p_invoice_id,
6672 l_terms_id,
6673 l_last_updated_by,
6674 l_created_by,
6675 null, -- TODO: why payment_priority is null?
6676 l_batch_id,
6677 l_terms_date,
6678 l_invoice_amount,
6679 l_pay_curr_invoice_amount,
6680 l_payment_cross_rate,
6681 l_discountable_amount,
6682 l_payment_method,
6683 l_invoice_curr_code,
6684 l_pay_curr_code,
6685 l_curr_calling_sequence);
6686
6687 -------------------------------------------
6688 l_debug_info := 'createPaymentSchedules - payment schedule created.';
6689 Print_Debug(l_debug_loc, l_debug_info);
6690 -------------------------------------------
6691
6692 end if;
6693
6694 EXCEPTION
6695 when OTHERS then
6696 IF (SQLCODE <> -20001) THEN
6697 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
6698 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
6699 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',l_curr_calling_sequence);
6700 FND_MESSAGE.SET_TOKEN('PARAMETERS',
6701 ' Invoice Id = ' || to_char(P_Invoice_Id) ||
6702 ', Calling module = ' || 'createPaymentSchedules' );
6703 END IF;
6704 APP_EXCEPTION.RAISE_EXCEPTION;
6705
6706 END createPaymentSchedules;
6707
6708
6709 FUNCTION Is_Product_Registered(P_Application_Id IN NUMBER,
6710 X_Registration_Api OUT NOCOPY VARCHAR2,
6711 X_Registration_View OUT NOCOPY VARCHAR2,
6712 P_Calling_Sequence IN VARCHAR2) RETURN BOOLEAN IS
6713
6714 l_debug_info VARCHAR2(1000);
6715 l_curr_calling_sequence VARCHAR2(2000);
6716
6717 BEGIN
6718
6719 l_curr_calling_sequence := 'Is_Product_Registered <-'||p_calling_sequence;
6720
6721 BEGIN
6722 SELECT registration_api,
6723 registration_view
6724 INTO x_registration_api,
6725 x_registration_view
6726 FROM ap_product_registrations
6727 WHERE application_id = 200
6728 AND reg_application_id = p_application_id
6729 AND registration_event_type = 'DISTRIBUTION_GENERATION';
6730
6731 EXCEPTION WHEN NO_DATA_FOUND THEN
6732 x_registration_view := NULL;
6733 x_registration_api := NULL;
6734 RETURN(FALSE);
6735 END;
6736
6737 RETURN(TRUE);
6738
6739 EXCEPTION
6740 WHEN OTHERS then
6741 IF (SQLCODE <> -20001) THEN
6742 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
6743 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
6744 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',l_curr_calling_sequence);
6745 FND_MESSAGE.SET_TOKEN('PARAMETERS',
6746 ' Application Id = ' || to_char(P_Application_Id) );
6747 END IF;
6748 APP_EXCEPTION.RAISE_EXCEPTION;
6749
6750 END Is_Product_Registered;
6751
6752
6753 FUNCTION Gen_Dists_From_Registration(
6754 P_Batch_Id IN NUMBER,
6755 P_Invoice_Line_Rec IN AP_INVOICES_PKG.r_invoice_line_rec,
6756 P_Registration_Api IN VARCHAR2,
6757 P_Registration_View IN VARCHAR2,
6758 P_Generate_Permanent IN VARCHAR2,
6759 X_Error_Code OUT NOCOPY VARCHAR2,
6760 P_Calling_Sequence IN VARCHAR2) RETURN BOOLEAN IS
6761
6762 l_debug_info VARCHAR2(1000);
6763 l_curr_calling_sequence VARCHAR2(2000);
6764
6765 TYPE Invoice_Dists_Tab_Type IS TABLE OF ap_invoice_distributions_all%ROWTYPE;
6766 l_dist_tab Invoice_Dists_Tab_Type := Invoice_Dists_Tab_Type();
6767
6768 TYPE Expense_Report_Dists_Rec IS RECORD (
6769 Org_id ap_exp_report_dists_all.org_id%TYPE,
6770 Sequence_Num ap_exp_report_dists_all.sequence_num%TYPE,
6771 Code_Combination_Id ap_exp_report_dists_all.code_combination_id%TYPE,
6772 Amount ap_exp_report_dists_all.amount%TYPE,
6773 Project_Id ap_exp_report_dists_all.project_id%TYPE,
6774 Task_Id ap_exp_report_dists_all.task_id%TYPE,
6775 Award_Id ap_exp_report_dists_all.award_id%TYPE,
6776 pa_quantity ap_expense_report_lines_all.pa_quantity%TYPE, --bug6699834
6777 Expenditure_Organization_Id ap_exp_report_dists_all.expenditure_organization_id%TYPE,
6778 Expenditure_type ap_expense_report_lines_all.expenditure_type%TYPE,
6779 Expenditure_item_date ap_expense_report_lines_all.expenditure_item_date%TYPE,
6780 receipt_currency_amount ap_exp_report_dists_all.receipt_currency_amount%TYPE, --bug6520882
6781 receipt_currency_code ap_exp_report_dists_all.receipt_currency_code%TYPE,
6782 receipt_conversion_rate ap_exp_report_dists_all.receipt_conversion_rate%TYPE);
6783
6784 TYPE Expense_Report_Dists_Tab_Type IS TABLE OF Expense_Report_Dists_Rec
6785 index by BINARY_INTEGER;
6786
6787 l_exp_report_dists_tab Expense_Report_Dists_Tab_Type;
6788
6789 CURSOR c_expense_report_dists IS
6790 SELECT nvl(aerd.org_id,aerl.org_id), --Bug5867415
6791 aerd.sequence_num,
6792 aerd.code_combination_id,
6793 aerd.amount,
6794 aerd.project_id,
6795 aerd.task_id,
6796 aerd.award_id,
6797 aerl.pa_quantity, -- bug6699834
6798 aerd.expenditure_organization_id,
6799 --bugfix:4939074
6800 aerl.expenditure_type,
6801 aerl.expenditure_item_date,
6802 aerd.receipt_currency_amount, --bug6520882
6803 aerd.receipt_currency_code,
6804 aerd.receipt_conversion_rate
6805 FROM ap_exp_report_dists_all aerd,
6806 ap_expense_report_lines_all aerl
6807 WHERE aerd.report_header_id = p_invoice_line_rec.reference_key1
6808 AND aerd.report_line_id = p_invoice_line_rec.reference_key2
6809 AND aerd.report_line_id = aerl.report_line_id
6810 AND aerd.report_header_id = aerl.report_header_id
6811 ORDER BY report_distribution_id;
6812
6813 i NUMBER;
6814 j NUMBER;
6815 l_account_type VARCHAR2(10);
6816 l_distribution_line_number NUMBER;
6817 l_total_dist_amount NUMBER;
6818 l_api_name VARCHAR2(200) := 'Gen_Dists_From_Registration';
6819
6820 BEGIN
6821
6822 i:= 0;
6823 l_distribution_line_number := 0;
6824 l_total_dist_amount := 0;
6825
6826 l_curr_calling_sequence := 'Gen_Dists_From_Registration <- '||p_calling_sequence;
6827
6828 -------------------------------------------
6829 l_debug_info := 'Generate Distributions as per the applications registered view';
6830 Print_Debug(l_api_name, l_debug_info);
6831 -------------------------------------------
6832
6833 -------------------------------------------
6834 l_debug_info := 'P_Registration_View: '||P_Registration_View;
6835 Print_Debug(l_api_name, l_debug_info);
6836 -------------------------------------------
6837
6838 IF (P_Registration_View = 'AP_EXP_REPORT_DISTS') THEN
6839
6840 -------------------------------------------
6841 l_debug_info := 'Open Cursor c_expense_report_dists';
6842 Print_Debug(l_api_name, l_debug_info);
6843 -------------------------------------------
6844
6845 OPEN c_expense_report_dists;
6846 FETCH c_expense_report_dists
6847 BULK COLLECT INTO l_exp_report_dists_tab;
6848 CLOSE c_expense_report_dists;
6849
6850 IF (l_exp_report_dists_tab.COUNT > 0) THEN
6851
6852 -------------------------------------------
6853 l_debug_info := 'Exp Report Dists more than zero - setting the amount';
6854 Print_Debug(l_api_name, l_debug_info);
6855 -------------------------------------------
6856
6857 FOR i IN l_exp_report_dists_tab.first .. l_exp_report_dists_tab.last LOOP
6858 l_total_dist_amount := l_total_dist_amount + l_exp_report_dists_tab(i).amount;
6859 END LOOP;
6860
6861 END IF;
6862
6863 IF (l_exp_report_dists_tab.COUNT > 0) THEN
6864
6865 l_dist_tab.EXTEND(l_exp_report_dists_tab.COUNT);
6866
6867 -------------------------------------------
6868 l_debug_info := 'Exp Report Dists more than zero - setting other attributes';
6869 Print_Debug(l_api_name, l_debug_info);
6870 -------------------------------------------
6871
6872 FOR i IN l_exp_report_dists_tab.first .. l_exp_report_dists_tab.last LOOP
6873 l_distribution_line_number := l_distribution_line_number + 1;
6874
6875 l_dist_tab(i).org_id := l_exp_report_dists_tab(i).org_id;
6876 l_dist_tab(i).distribution_line_number := l_distribution_line_number;
6877 l_dist_tab(i).dist_code_combination_id := l_exp_report_dists_tab(i).code_combination_id;
6878 --bug6597595
6879 if l_total_dist_amount = 0 then
6880 l_dist_tab(i).amount := 0;
6881 else
6882 --bug6653070
6883 l_dist_tab(i).amount :=
6884 ((p_invoice_line_rec.amount) * l_exp_report_dists_tab(i).amount)/
6885 l_total_dist_amount;
6886 end if;
6887 l_dist_tab(i).project_id := l_exp_report_dists_tab(i).project_id;
6888 l_dist_tab(i).task_id := l_exp_report_dists_tab(i).task_id;
6889 l_dist_tab(i).award_id := l_exp_report_dists_tab(i).award_id;
6890 l_dist_tab(i).pa_quantity := l_exp_report_dists_tab(i).pa_quantity;-- bug6699834
6891
6892 l_dist_tab(i).expenditure_organization_id := l_exp_report_dists_tab(i).expenditure_organization_id;
6893 l_dist_tab(i).expenditure_type := l_exp_report_dists_tab(i).expenditure_type;
6894 l_dist_tab(i).expenditure_item_date := l_exp_report_dists_tab(i).expenditure_item_date;
6895 l_dist_tab(i).receipt_currency_amount:=l_exp_report_dists_tab(i).receipt_currency_amount;--bug6520882
6896 l_dist_tab(i).receipt_currency_code:= l_exp_report_dists_tab(i).receipt_currency_code;
6897 l_dist_tab(i).receipt_conversion_rate:= l_exp_report_dists_tab(i).receipt_conversion_rate;
6898 l_dist_tab(i).batch_id := p_batch_id;
6899 l_dist_tab(i).invoice_id := p_invoice_line_rec.invoice_id;
6900 l_dist_tab(i).invoice_line_number := p_invoice_line_rec.line_number;
6901
6902 SELECT ap_invoice_distributions_s.nextval
6903 INTO l_dist_tab(i).invoice_distribution_id
6904 FROM DUAL;
6905
6906 l_dist_tab(i).line_type_lookup_code := 'ITEM';
6907
6908 IF (nvl(p_generate_permanent,'N') = 'N') THEN
6909 l_dist_tab(i).distribution_class := 'CANDIDATE';
6910 ELSE
6911 l_dist_tab(i).distribution_class := 'PERMANENT';
6912 END IF;
6913
6914 l_dist_tab(i).description := p_invoice_line_rec.description;
6915 l_dist_tab(i).dist_match_type := 'NOT_MATCHED';
6916 l_dist_tab(i).accounting_date := p_invoice_line_rec.accounting_date;
6917 l_dist_tab(i).period_name := p_invoice_line_rec.period_name;
6918 l_dist_tab(i).accrual_posted_flag := 'N';
6919 l_dist_tab(i).cash_posted_flag := 'N';
6920 l_dist_tab(i).posted_flag := 'N';
6921 l_dist_tab(i).set_of_books_id := p_invoice_line_rec.set_of_books_id;
6922 l_dist_tab(i).encumbered_flag := 'N';
6923 l_dist_tab(i).reversal_flag := 'N';
6924 l_dist_tab(i).cancellation_flag := 'N';
6925 l_dist_tab(i).income_tax_region := p_invoice_line_rec.income_tax_region;
6926 l_dist_tab(i).type_1099 := p_invoice_line_rec.type_1099;
6927 l_dist_tab(i).assets_addition_flag := 'U';
6928
6929 BEGIN
6930 SELECT account_type
6931 INTO l_account_type
6932 FROM gl_code_combinations
6933 WHERE code_combination_id = l_dist_tab(i).dist_code_combination_id;
6934
6935 EXCEPTION
6936 WHEN NO_DATA_FOUND THEN
6937
6938 l_debug_info := l_debug_info || ': cannot read account type information';
6939 Print_Debug(l_api_name,l_debug_info);
6940
6941 RETURN(FALSE);
6942
6943 END;
6944
6945 IF (l_account_type = 'A' OR
6946 (l_account_type = 'E' AND
6947 p_invoice_line_rec.assets_tracking_flag = 'Y')) then
6948
6949 l_dist_tab(i).assets_tracking_flag := 'Y';
6950 l_dist_tab(i).asset_book_type_code := p_invoice_line_rec.asset_book_type_code;
6951 l_dist_tab(i).asset_category_id := p_invoice_line_rec.asset_category_id;
6952 ELSE
6953 l_dist_tab(i).assets_tracking_flag := 'N';
6954 END IF;
6955
6956 IF (l_dist_tab(i).project_id IS NULL) THEN
6957 l_dist_tab(i).pa_addition_flag := 'E';
6958 ELSE
6959 l_dist_tab(i).pa_addition_flag := 'N';
6960 END IF;
6961
6962 l_dist_tab(i).awt_group_id := p_invoice_line_rec.awt_group_id;
6963 l_dist_tab(i).inventory_transfer_status := 'N';
6964 l_dist_tab(i).intended_use := p_invoice_line_rec.primary_intended_use;
6965 l_dist_tab(i).rcv_charge_addition_flag := 'N';
6966 l_dist_tab(i).created_by := FND_GLOBAL.user_id;
6967 l_dist_tab(i).creation_date := SYSDATE;
6968 l_dist_tab(i).last_update_date := SYSDATE;
6969 l_dist_tab(i).last_update_login := FND_GLOBAL.login_id;
6970 l_dist_tab(i).last_updated_by := FND_GLOBAL.user_id;
6971
6972 END LOOP;
6973
6974 END IF; /* If l_exp_report_dists_tab.count > 0 */
6975
6976 -------------------------------------------
6977 l_debug_info := 'Bulk Insert into ap_invoice_distributions';
6978 Print_Debug(l_api_name, l_debug_info);
6979 -------------------------------------------
6980 IF (nvl(l_dist_tab.count,0)<>0) THEN
6981
6982 FORALL j IN l_dist_tab.first .. l_dist_tab.last
6983 INSERT INTO ap_invoice_distributions
6984 VALUES l_dist_tab(j);
6985
6986 FOR j IN l_dist_tab.first .. l_dist_tab.last
6987 LOOP
6988 IF l_dist_tab(j).award_id is not null then
6989 gms_ap_api.CREATE_AWARD_DISTRIBUTIONS( l_dist_tab(j). invoice_id,
6990 l_dist_tab(j).distribution_line_number,
6991 l_dist_tab(j).invoice_distribution_id,
6992 l_dist_tab(j).award_id,
6993 'AP',
6994 NULL,
6995 NULL);
6996 End If ;
6997 END LOOP ;
6998
6999 END IF;
7000
7001 ELSIF (P_Registration_Api IS NOT NULL) THEN
7002 NULL;
7003
7004 END IF;
7005
7006 -------------------------------------------
7007 l_debug_info := 'Setting generate distributions flag to Done';
7008 Print_Debug(l_api_name, l_debug_info);
7009 -------------------------------------------
7010
7011 IF (nvl(p_generate_permanent,'N') = 'Y') then
7012 BEGIN
7013 UPDATE AP_INVOICE_LINES
7014 SET GENERATE_DISTS = 'D'
7015 WHERE invoice_id = p_invoice_line_rec.invoice_id
7016 AND line_number = p_invoice_line_rec.line_number;
7017 EXCEPTION
7018 WHEN OTHERS THEN
7019 l_debug_info := l_debug_info || ': Error encountered';
7020 return (FALSE);
7021 END;
7022 END IF;
7023
7024 RETURN(TRUE);
7025
7026
7027 EXCEPTION
7028 WHEN OTHERS then
7029 IF (SQLCODE <> -20001) THEN
7030 l_debug_info := 'In others exception '||sqlerrm;
7031 Print_Debug(l_api_name,l_debug_info);
7032
7033 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
7034 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
7035 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',l_curr_calling_sequence);
7036 FND_MESSAGE.SET_TOKEN('PARAMETERS',
7037 ' Invoice Id = ' || to_char(P_invoice_line_rec.Invoice_Id) ||
7038 ', Invoice Line Number = '||to_char(p_invoice_line_rec.Line_Number) ||
7039 ', Registration Api = '||P_Registration_Api ||
7040 ', Registration View = '||P_Registration_View);
7041 END IF;
7042 APP_EXCEPTION.RAISE_EXCEPTION;
7043
7044 END Gen_Dists_From_Registration;
7045
7046
7047 ------------------------------------------------------------------------
7048 -- Function Batch_Approval:
7049 -- It selects all invoices depending on the parameters given to it and
7050 -- calls the on-line PL/SQL approval package to approve each invoice
7051 -- individually.
7052 ------------------------------------------------------------------------
7053
7054 FUNCTION batch_approval
7055 (p_run_option IN VARCHAR2,
7056 p_sob_id IN NUMBER,
7057 p_inv_start_date IN DATE,
7058 p_inv_end_date IN DATE,
7059 p_inv_batch_id IN NUMBER,
7060 p_vendor_id IN NUMBER,
7061 p_pay_group IN VARCHAR2,
7062 p_invoice_id IN NUMBER,
7063 p_entered_by IN NUMBER,
7064 p_debug_switch IN VARCHAR2,
7065 p_conc_request_id IN NUMBER,
7066 p_commit_size IN NUMBER,
7067 p_org_id IN NUMBER,
7068 p_report_holds_count OUT NOCOPY NUMBER) RETURN BOOLEAN
7069
7070 IS
7071
7072 TYPE hold_codeTab IS TABLE OF ap_hold_codes.hold_lookup_code%Type;
7073 TYPE invoiceIDTab IS TABLE OF ap_invoices.invoice_id%Type INDEX BY BINARY_INTEGER;
7074 TYPE invoiceNUMTab IS TABLE OF ap_invoices.invoice_num%Type INDEX BY BINARY_INTEGER;
7075 TYPE procinvoiceIDTab IS TABLE OF ap_invoices.invoice_id%Type;
7076 TYPE hold_org_idTab IS TABLE OF ap_invoices.org_id%Type;
7077
7078 TYPE orgIDTab IS TABLE OF ap_invoices_all.org_id%Type INDEX BY BINARY_INTEGER;
7079 TYPE invtypeTab IS TABLE OF ap_invoices_all.invoice_type_lookup_code%Type INDEX BY BINARY_INTEGER;
7080
7081 l_inv_batch_id NUMBER(15);
7082 l_vendor_id NUMBER(15);
7083 l_pay_group VARCHAR2(25);
7084 l_invoice_id NUMBER(15);
7085 l_entered_by NUMBER(15);
7086 l_holds_count NUMBER(5);
7087 l_approval_status VARCHAR2(25);
7088
7089 l_status VARCHAR2(80);
7090 l_approval_error VARCHAR2(2000);
7091 l_org_id NUMBER(15);
7092 l_sel_org_id NUMBER(15);
7093 l_old_org_id NUMBER(15);
7094
7095 l_sel_invoice_type VARCHAR2(25);
7096 l_calling_mode VARCHAR2(25);
7097 l_funds_return_code VARCHAR2(30); --Bug6610937
7098
7099 l_sql_stmt VARCHAR2(5000);
7100 l_sql_stmt_cursor INTEGER;
7101 ignore INTEGER;
7102 no_of_rows_fetched INTEGER;
7103
7104 l_hold_code hold_codeTab;
7105 l_selected_invoice_ids invoiceIDTab; -- 7461423
7106 l_sel_invoice_num invoiceNUMTab;
7107
7108 lc_sel_org_id orgIDTab;
7109 lc_sel_invoice_type invtypeTab;
7110
7111 l_processed_inv_id procinvoiceIDTab;
7112 l_hold_org_id hold_org_idTab;
7113
7114 l_validation_request_id NUMBER;
7115 l_invoice_num VARCHAR2(50);
7116 l_commit_size NUMBER;
7117 l_curr_calling_sequence VARCHAR2(2000);
7118
7119 l_holds HOLDSARRAY;
7120 l_hold_count COUNTARRAY;
7121 l_release_count COUNTARRAY;
7122 l_total_hold_count NUMBER;
7123 l_total_release_count NUMBER;
7124 l_line_variance_hold_exist BOOLEAN := FALSE;
7125 l_need_to_round_flag VARCHAR2(1) := 'Y';
7126
7127 l_success BOOLEAN;
7128 l_error_code VARCHAR2(4000);
7129 l_prorate_across_all_items VARCHAR2(1);
7130 l_debug_context VARCHAR2(2000);
7131 l_insufficient_data_exist BOOLEAN := FALSE;
7132
7133 l_calling_sequence VARCHAR2(20);
7134
7135 l_retained_amount NUMBER;
7136 l_recouped_amount NUMBER;
7137 l_invoice_rec AP_APPROVAL_PKG.Invoice_Rec;
7138 l_invoice_date AP_INVOICES.invoice_date%TYPE;
7139 l_invoice_currency_code AP_INVOICES.invoice_currency_code%TYPE;
7140 l_exchange_rate AP_INVOICES.exchange_rate%TYPE;
7141 l_exchange_rate_type AP_INVOICES.exchange_rate_type%TYPE;
7142 l_exchange_date AP_INVOICES.exchange_date%TYPE;
7143 l_tolerance_id AP_SUPPLIER_SITES_ALL.TOLERANCE_ID%TYPE;
7144 l_services_tolerance_id AP_SUPPLIER_SITES_ALL.SERVICES_TOLERANCE_ID%TYPE;
7145
7146 Tax_Exception EXCEPTION;
7147
7148 CURSOR SELECTED_INVOICES_CURSOR IS
7149 SELECT
7150 I.invoice_id,
7151 I.invoice_num,
7152 I.org_id,
7153 I.invoice_amount,
7154 I.base_amount,
7155 I.exchange_rate,
7156 I.invoice_currency_code,
7157 S.invoice_amount_limit,
7158 nvl(S.hold_future_payments_flag,'N') hold_future_payments_flag,
7159 I.invoice_type_lookup_code,
7160 I.exchange_date,
7161 I.exchange_rate_type,
7162 I.vendor_id,
7163 I.invoice_date,
7164 nvl(I.disc_is_inv_less_tax_flag,'N') disc_is_inv_less_tax_flag,
7165 nvl(I.exclude_freight_from_discount,'N') exclude_freight_from_discount,
7166 S.tolerance_id,
7167 s.services_tolerance_id
7168 FROM ap_invoices_all I,
7169 ap_supplier_sites_all S
7170 WHERE I.vendor_site_id = S.vendor_site_id (+)
7171 AND I.validation_request_id = AP_APPROVAL_PKG.G_VALIDATION_REQUEST_ID
7172 ORDER BY I.org_id;
7173
7174 l_api_name CONSTANT VARCHAR2(200) := 'Batch_Approval';
7175
7176 -- Start for bug 6511249
7177 CURSOR SELC_INV_CURSOR_BULK_ERROR IS
7178 SELECT I.invoice_id, i.invoice_num, i.org_id
7179 FROM ap_invoices_all I,
7180 ap_supplier_sites_all S
7181 WHERE I.vendor_site_id = S.vendor_site_id (+)
7182 AND I.validation_request_id = AP_APPROVAL_PKG.G_VALIDATION_REQUEST_ID
7183 ORDER BY I.org_id;
7184
7185 TYPE selc_inv_cursor_blk_err is table of selc_inv_cursor_bulk_error%rowtype;
7186
7187 l_selc_inv_cursor_blk_err selc_inv_cursor_blk_err;
7188 l_blk_err varchar2(1):='N';
7189 l_errbuf varchar2(200);
7190 l_conc_status varchar2(10);
7191 l_set_status boolean;
7192 Tax_Exception_Handled Exception;
7193 Tax_Dist_Exception_Handled Exception;
7194 -- End for bug 6511249
7195
7196 -- 7461423
7197 TYPE var_cur IS REF CURSOR;
7198 bat_inv_ref_cursor var_cur;
7199
7200 BEGIN
7201 IF (p_debug_switch = 'Y') THEN
7202 g_debug_mode := 'Y';
7203 END IF;
7204
7205 ---------------------------------------------------------------------
7206 Print_Debug(l_api_name, 'AP_APPROVAL_PKG.BATCH_APPROVAL.BEGIN');
7207 ---------------------------------------------------------------------
7208
7209 ap_approval_pkg.g_validation_request_id := p_conc_request_id;
7210 g_org_holds.delete;
7211
7212 ---------------------------------------------------------------------
7213 Print_Debug(l_api_name, 'Setting null input parameters');
7214 ---------------------------------------------------------------------
7215 l_inv_batch_id := NVL(p_inv_batch_id,-1);
7216 l_vendor_id := NVL(p_vendor_id,-1);
7217 l_pay_group := NVL(p_pay_group,'All');
7218 l_invoice_id := NVL(p_invoice_id,-1);
7219 l_entered_by := NVL(p_entered_by,-999);
7220 l_commit_size := NVL(p_commit_size,1000);
7221 l_org_id := NVL(p_org_id, -3115);
7222
7223 ---------------------------------------------------------------------
7224 Print_Debug(l_api_name, 'Clean-up validation_request_id');
7225 ---------------------------------------------------------------------
7226 UPDATE ap_invoices api
7227 SET validation_request_id = NULL
7228 WHERE validation_request_id IS NOT NULL
7229 AND EXISTS
7230 ( SELECT 'Request Completed'
7231 FROM fnd_concurrent_requests fcr
7232 WHERE fcr.request_id = api.validation_request_id
7233 AND fcr.phase_code = 'C' );
7234
7235 ---------------------------------------------------------------------
7236 Print_Debug(l_api_name, 'Cache System Options');
7237 ---------------------------------------------------------------------
7238 AP_Approval_PKG.Cache_Options(l_curr_calling_sequence);
7239
7240
7241 IF (l_invoice_id <> -1) THEN
7242
7243 IF validate_period(l_invoice_id) THEN /*bug6858309 - changed location of the call*/
7244
7245 ---------------------------------------------------------------------
7246 Print_Debug(l_api_name, 'Begin Approving Single Invoice');
7247 ---------------------------------------------------------------------
7248
7249 /* 6699825/6684139: Added the AND condition to check if the invoice has any
7250 lines. Otherwise, we will not proceed with validating the invoice */
7251
7252 UPDATE ap_invoices_all ai
7253 SET ai.validation_request_id = p_conc_request_id
7254 WHERE ai.invoice_id = l_invoice_id
7255 AND ai.validation_request_id IS NULL
7256 /*bug 7029877 Invoice saved but not submitted*/
7257 AND ai.approval_ready_flag <>'S'
7258 AND EXISTS (select ail.invoice_id
7259 from ap_invoice_lines_all ail
7260 where ail.invoice_id = ai.invoice_id) ;
7261
7262 -- bug 6351170 -Added below if condition - Return if there are no invoices to process
7263 IF sql%rowcount = 0 THEN
7264 RETURN true;
7265 END IF;
7266
7267 COMMIT;
7268
7269 BEGIN
7270 SELECT
7271 ai.invoice_num, ai.org_id, ai.invoice_type_lookup_code, ai.validation_request_id,
7272 ai.invoice_id, ai.invoice_date, ai.invoice_currency_code, ai.exchange_rate,
7273 ai.exchange_rate_type, ai.exchange_date, ai.vendor_id, ai.org_id, s.tolerance_id,
7274 s.services_tolerance_id
7275 INTO
7276 l_invoice_num, l_sel_org_id, l_sel_invoice_type, l_validation_request_id,
7277 l_invoice_id, l_invoice_date, l_invoice_currency_code, l_exchange_rate,
7278 l_exchange_rate_type, l_exchange_date, l_vendor_id, l_org_id, l_tolerance_id,
7279 l_services_tolerance_id
7280 FROM ap_invoices_all ai,
7281 ap_supplier_sites_all s
7282 WHERE ai.invoice_id = l_invoice_id
7283 AND ai.vendor_site_id = s.vendor_site_id(+);
7284 EXCEPTION
7285 WHEN OTHERS THEN
7286 Print_Debug(l_api_name, 'Invoice Number Not Found');
7287 RETURN(FALSE);
7288 END;
7289
7290 mo_global.set_policy_context('S', l_sel_org_id);
7291
7292 ---------------------------------------------------------------------
7293 Print_Debug (l_api_name, 'Calculate Tax');
7294 ---------------------------------------------------------------------
7295 l_success := ap_etax_pkg.calling_etax(
7296 p_invoice_id => NULL,
7297 p_calling_mode => 'CALCULATE',
7298 p_all_error_messages => 'N',
7299 p_error_code => l_error_code,
7300 p_calling_sequence => l_curr_calling_sequence);
7301
7302 IF (NOT l_success) THEN
7303 RAISE Tax_Exception;
7304 END IF;
7305
7306 ----------------------------------------------------------------
7307 Print_Debug(l_api_name, 'Initialize Invoice Holds Array');
7308 ----------------------------------------------------------------
7309 Initialize_Invoice_Holds(
7310 p_invoice_id => l_invoice_id,
7311 p_calling_sequence => l_curr_calling_sequence);
7312
7313 ---------------------------------------------------------------------
7314 Print_Debug (l_api_name, 'Generate Distributions');
7315 ---------------------------------------------------------------------
7316
7317 l_invoice_rec.invoice_id := l_invoice_id;
7318 l_invoice_rec.invoice_date := l_invoice_date;
7319 l_invoice_rec.invoice_currency_code := l_invoice_currency_code;
7320 l_invoice_rec.exchange_rate := l_exchange_rate;
7321 l_invoice_rec.exchange_rate_type := l_exchange_rate_type;
7322 l_invoice_rec.exchange_date := l_exchange_date;
7323 l_invoice_rec.vendor_id := l_vendor_id;
7324 l_invoice_rec.org_id := l_org_id;
7325 g_org_id := l_org_id;
7326
7327
7328 AP_APPROVAL_PKG.Generate_Distributions
7329 (p_invoice_rec => l_invoice_rec,
7330 p_base_currency_code => AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_org_id).base_currency_code,
7331 p_inv_batch_id => p_inv_batch_id,
7332 p_run_option => p_run_option,
7333 p_calling_sequence => l_curr_calling_sequence,
7334 x_error_code => l_error_code);
7335
7336 ---------------------------------------------------------------------
7337 Print_Debug (l_api_name, 'Generate Tax Distributions');
7338 ---------------------------------------------------------------------
7339 l_success := ap_etax_pkg.calling_etax (
7340 p_invoice_id => NULL,
7341 p_calling_mode => 'DISTRIBUTE',
7342 p_all_error_messages => 'N',
7343 p_error_code => l_error_code,
7344 p_calling_sequence => l_curr_calling_sequence);
7345
7346 IF (NOT l_success) THEN
7347 RAISE Tax_Exception;
7348 END IF;
7349
7350
7351 IF l_sel_invoice_type = 'PAYMENT REQUEST' THEN
7352 l_calling_mode := 'PAYMENT REQUEST';
7353 ELSE
7354 l_calling_mode := 'APPROVE';
7355 END IF;
7356
7357 ---------------------------------------------------------------------
7358 Print_Debug(l_api_name, 'Approving specified invoice : '||l_invoice_num);
7359 ---------------------------------------------------------------------
7360
7361 IF l_validation_request_id = p_conc_request_id THEN
7362
7363 --IF validate_period(l_invoice_id) THEN /*commented for bug 6858309*/
7364
7365 -- Cache Templates
7366 Cache_Tolerance_Templates(
7367 l_tolerance_id,
7368 l_services_tolerance_id,
7369 l_calling_sequence);
7370
7371 --Removed the hardcoded value of p_budget_control, bug6356402
7372 AP_APPROVAL_PKG.APPROVE(
7373 '',
7374 '',
7375 '',
7376 '',
7377 '',
7378 '',
7379 l_invoice_id,
7380 '',
7381 '',
7382 '',
7383 'Y',
7384 l_holds_count,
7385 l_approval_status,
7386 l_funds_return_code,
7387 l_calling_mode,
7388 'APXAPRVL',
7389 p_debug_switch
7390 );
7391 /*commented for bug 6858309
7392 ELSE
7393 fnd_message.set_name('SQLAP', 'AP_INV_NEVER_OPEN_PERIOD');
7394 fnd_message.set_token('INV_NUM', l_invoice_num);
7395 fnd_file.put_line(fnd_file.log, fnd_message.get);
7396 END IF; */
7397
7398 UPDATE ap_invoices_all
7399 SET validation_request_id = NULL
7400 WHERE invoice_id = l_invoice_id;
7401
7402 END IF;
7403
7404 ELSE /*bug6858309- changed location of the call*/
7405 fnd_message.set_name('SQLAP', 'AP_INV_NEVER_OPEN_PERIOD');
7406 fnd_message.set_token('INV_NUM', l_invoice_num);
7407 fnd_file.put_line(fnd_file.log, fnd_message.get);
7408
7409 END IF; --if validate_period(p_invoice_id)
7410
7411 ---------------------------------------------------------------------
7412 Print_Debug(l_api_name, 'End Approving Single Invoice');
7413 ---------------------------------------------------------------------
7414
7415 ELSE -- Invoice_id is null case -- Marker 0
7416
7417 ---------------------------------------------------------------------
7418 Print_Debug(l_api_name, 'Batch Approval Start');
7419 ---------------------------------------------------------------------
7420
7421 /*bug6858309 modified this dynamic update to filter out
7422 recurring invoices havign GL DATE in never open period*/
7423 /* Added for bug#7270053 Start */
7424 l_sql_stmt :=l_sql_stmt||
7425 'SELECT invoice_id from AP_INVOICES_ALL AI '|| -- 7461423
7426 ' WHERE AI.VALIDATION_REQUEST_ID IS NULL '||
7427 ' AND AI.APPROVAL_READY_FLAG <> ''S'' '||
7428 ' AND (UPPER(NVL(AI.SOURCE, ''X'')) <> ''RECURRING INVOICE'' OR '||
7429 ' (UPPER(NVL(AI.SOURCE, ''X'')) = ''RECURRING INVOICE'' AND NOT EXISTS '||
7430 ' (SELECT NULL '||
7431 ' FROM GL_PERIOD_STATUSES GLPS, AP_SYSTEM_PARAMETERS SP '||
7432 ' WHERE GLPS.APPLICATION_ID = ''200'' '||
7433 ' AND SP.ORG_ID = AI.ORG_ID '||
7434 ' AND GLPS.SET_OF_BOOKS_ID = SP.SET_OF_BOOKS_ID '||
7435 ' AND TRUNC(AI.GL_DATE) BETWEEN GLPS.START_DATE AND GLPS.END_DATE '||
7436 ' AND NVL(GLPS.ADJUSTMENT_PERIOD_FLAG, ''N'') = ''N'' '||
7437 ' AND GLPS.CLOSING_STATUS = ''N''))) '||
7438 ' AND NOT (AI.PAYMENT_STATUS_FLAG = ''Y'' AND '||
7439 ' AI.HISTORICAL_FLAG = ''Y'') '||
7440 ' AND ((( ( EXISTS '||
7441 ' (SELECT 1 '||
7442 ' FROM AP_INVOICE_DISTRIBUTIONS D '||
7443 ' WHERE D.INVOICE_ID = AI.INVOICE_ID '||
7444 ' AND NVL(D.MATCH_STATUS_FLAG, ''N'') <> ''A''' ||
7445 ' ) '||
7446 ' OR EXISTS '||
7447 ' (SELECT ''Unreleased Hold exists'' '||
7448 ' FROM AP_HOLDS H '||
7449 ' WHERE H.INVOICE_ID = AI.INVOICE_ID '||
7450 ' AND H.HOLD_LOOKUP_CODE IN '||
7451 ' (''QTY ORD'', ''QTY REC'', ''AMT ORD'', ''AMT REC'', ''QUALITY'', '||
7452 ' ''PRICE'', ''TAX DIFFERENCE'', ''CURRENCY DIFFERENCE'', '||
7453 ' ''REC EXCEPTION'', ''TAX VARIANCE'', ''PO NOT APPROVED'', '||
7454 ' ''PO REQUIRED'', ''MAX SHIP AMOUNT'', ''MAX RATE AMOUNT'', '||
7455 ' ''MAX TOTAL AMOUNT'', ''TAX AMOUNT RANGE'', ''MAX QTY ORD'', '||
7456 ' ''MAX QTY REC'', ''MAX AMT ORD'', ''MAX AMT REC'', '||
7457 ' ''CANT CLOSE PO'', ''CANT TRY PO CLOSE'', ''LINE VARIANCE'', '||
7458 ' ''CANT FUNDS CHECK'') '||
7459 ' AND H.RELEASE_LOOKUP_CODE IS NULL ' ||
7460 ' ) '||
7461 ' ) ' ||
7462 ' OR '||
7463 ' (AI.FORCE_REVALIDATION_FLAG = ''Y'')'||
7464 ' ) '||
7465 ' AND NOT EXISTS '||
7466 ' (SELECT ''Cancelled distributions'' '||
7467 ' FROM AP_INVOICE_DISTRIBUTIONS_ALL D2 '||
7468 ' WHERE D2.INVOICE_ID = AI.INVOICE_ID '||
7469 ' AND D2.CANCELLATION_FLAG = ''Y'''||
7470 ' )'||
7471 ' ) '||
7472 ' OR EXISTS '||
7473 ' (SELECT 1 '||
7474 ' FROM AP_INVOICE_LINES AIL '||
7475 ' WHERE AIL.INVOICE_ID = AI.INVOICE_ID '||
7476 ' AND AI.CANCELLED_DATE IS NULL '||
7477 ' AND NVL(AIL.DISCARDED_FLAG, ''N'') <> ''Y'' '||
7478 ' AND NVL(AIL.CANCELLED_FLAG, ''N'') <> ''Y'' '||
7479 ' AND NOT EXISTS '||
7480 ' (SELECT /*+ NO_UNNEST */ '||
7481 ' ''distributed line'' '||
7482 ' FROM AP_INVOICE_DISTRIBUTIONS_ALL D5 '||
7483 ' WHERE D5.INVOICE_ID = AIL.INVOICE_ID '||
7484 ' AND D5.INVOICE_LINE_NUMBER = AIL.LINE_NUMBER))) ' ;
7485 IF P_org_id IS NOT NULL THEN
7486 l_sql_stmt := l_sql_stmt|| 'AND AI.org_id = ' || l_org_id || ' ' ;
7487 END IF ;
7488 IF P_inv_batch_id IS NOT NULL THEN
7489 l_sql_stmt := l_sql_stmt|| 'AND AI.batch_id = ' || p_inv_batch_id || ' ' ;
7490 END IF ;
7491 IF P_vendor_id IS NOT NULL THEN
7492 l_sql_stmt := l_sql_stmt|| 'AND AI.vendor_id = ' || p_vendor_id || ' ' ;
7493 END IF ;
7494 IF P_inv_start_date IS NOT NULL AND P_inv_end_date IS NULL THEN
7495 l_sql_stmt := l_sql_stmt|| 'AND AI.invoice_date >= :b_start_date ' ;
7496 END IF ;
7497 IF P_inv_start_date IS NULL AND P_inv_end_date IS NOT NULL THEN
7498 l_sql_stmt := l_sql_stmt || 'AND AI.invoice_date <= :b_end_date ' ;
7499 END IF ;
7500 IF P_inv_start_date IS NOT NULL AND P_inv_end_date IS NOT NULL THEN
7501 IF P_inv_start_date <> P_inv_end_date THEN
7502 l_sql_stmt := l_sql_stmt || 'AND AI.invoice_date BETWEEN :b_start_date AND :b_end_date ' ;
7503 ELSE
7504 l_sql_stmt := l_sql_stmt || 'AND AI.invoice_date = :b_start_date ' ;
7505 END IF ;
7506 END IF ;
7507 IF P_entered_by IS NOT NULL THEN
7508 l_sql_stmt := l_sql_stmt || ' AND AI.created_by = ' || l_entered_by || ' ' ;
7509 END IF ;
7510 IF P_pay_group IS NOT NULL THEN
7511 l_sql_stmt := l_sql_stmt || ' and AI.pay_group_lookup_code = ' || '''' || l_pay_group || '''' || ' ' ;
7512 END IF ;
7513
7514 l_sql_stmt :=l_sql_stmt || ' FOR UPDATE SKIP LOCKED';
7515 ---------------------------------------------------------------------
7516 Print_Debug (l_api_name, l_sql_stmt);
7517 ---------------------------------------------------------------------
7518
7519 IF p_inv_start_date IS NOT NULL OR p_inv_end_date IS NOT NULL
7520 THEN
7521 IF (p_inv_start_date IS NOT NULL AND p_inv_end_date IS NOT NULL
7522 AND P_inv_start_date <> P_inv_end_date) THEN -- bug 7688696
7523
7524 OPEN bat_inv_ref_cursor FOR l_sql_stmt
7525 USING p_inv_start_date, p_inv_end_date; -- 7461423
7526
7527 ELSE
7528
7529 OPEN bat_inv_ref_cursor FOR l_sql_stmt
7530 USING NVL(p_inv_start_date, p_inv_end_date); -- 7461423
7531
7532 END IF;
7533
7534 ELSE
7535 /* Added for bug#7270053 End */
7536 OPEN bat_inv_ref_cursor FOR l_sql_stmt; -- 7461423
7537
7538 END IF;
7539
7540 -- 7461423 to skip locked invoices
7541 FETCH bat_inv_ref_cursor
7542 BULK COLLECT INTO l_selected_invoice_ids;
7543 CLOSE bat_inv_ref_cursor;
7544
7545 IF l_selected_invoice_ids.count > 0 THEN
7546
7547 FOR k IN 1..l_selected_invoice_ids.count
7548 LOOP
7549
7550 UPDATE ap_invoices_all
7551 SET validation_request_id = AP_APPROVAL_PKG.G_VALIDATION_REQUEST_ID
7552 WHERE invoice_id = l_selected_invoice_ids(k)
7553 AND validation_request_id IS NULL;
7554
7555 END LOOP;
7556
7557 ELSE
7558
7559 RETURN true;
7560
7561 END IF;
7562
7563 COMMIT;
7564
7565 ---------------------------------------------------------------------
7566 Print_Debug (l_api_name, 'Calculate Tax');
7567 ---------------------------------------------------------------------
7568
7569 SAVEPOINT AP_APPROVAL_PKG_SP_ETAX;
7570
7571 l_success := ap_etax_pkg.calling_etax(
7572 p_invoice_id => NULL,
7573 p_calling_mode => 'CALCULATE',
7574 p_all_error_messages => 'N',
7575 p_error_code => l_error_code,
7576 p_calling_sequence => l_curr_calling_sequence);
7577
7578 IF (NOT l_success) THEN -- Marker 1
7579
7580 ROLLBACK TO SAVEPOINT AP_APPROVAL_PKG_SP_ETAX;
7581
7582 l_blk_err := 'Y';
7583
7584 ---------------------------------------------------------------------
7585 Print_Debug (l_api_name, 'Set Concurrent Request Warning');
7586 ---------------------------------------------------------------------
7587
7588 l_conc_status := 'WARNING';
7589 --bug 7512258 removed call to FND_CONCURRENT.SET_COMPLETION_STATUS
7590
7591 ---------------------------------------------------------------------
7592 Print_Debug (l_api_name, 'Begin Single Mode');
7593 ---------------------------------------------------------------------
7594
7595 OPEN SELC_INV_CURSOR_BULK_ERROR;
7596 FETCH SELC_INV_CURSOR_BULK_ERROR
7597 BULK COLLECT INTO l_selc_inv_cursor_blk_err;
7598
7599 UPDATE ap_invoices_all
7600 SET validation_request_id = NULL
7601 WHERE validation_request_id IS NOT NULL
7602 AND invoice_id IN (SELECT invoice_id
7603 FROM ap_invoices_all
7604 WHERE validation_request_id = AP_APPROVAL_PKG.G_VALIDATION_REQUEST_ID);
7605
7606 FOR i IN 1..l_selc_inv_cursor_blk_err.count
7607 LOOP
7608
7609 SAVEPOINT AP_APPROVAL_PKG_SP_INV;
7610
7611 UPDATE ap_invoices_all
7612 SET validation_request_id = AP_APPROVAL_PKG.G_VALIDATION_REQUEST_ID
7613 WHERE invoice_id = l_selc_inv_cursor_blk_err(i).invoice_id;
7614
7615 BEGIN
7616
7617 BEGIN
7618 SELECT
7619 ai.invoice_num, ai.org_id, ai.invoice_type_lookup_code, ai.validation_request_id,
7620 ai.invoice_id, ai.invoice_date, ai.invoice_currency_code, ai.exchange_rate,
7621 ai.exchange_rate_type, ai.exchange_date, ai.vendor_id, ai.org_id, s.tolerance_id,
7622 s.services_tolerance_id
7623 INTO
7624 l_invoice_num, l_sel_org_id, l_sel_invoice_type, l_validation_request_id,
7625 l_invoice_id, l_invoice_date, l_invoice_currency_code, l_exchange_rate,
7626 l_exchange_rate_type, l_exchange_date, l_vendor_id, l_org_id, l_tolerance_id,
7627 l_services_tolerance_id
7628 FROM
7629 ap_invoices_all ai,
7630 ap_supplier_sites_all s
7631 WHERE
7632 ai.invoice_id = l_selc_inv_cursor_blk_err(i).invoice_id
7633 AND
7634 ai.vendor_site_id = s.vendor_site_id(+);
7635
7636 EXCEPTION
7637 WHEN OTHERS THEN
7638 Print_Debug(l_api_name, 'Invoice Number Not Found');
7639 RAISE;
7640 END;
7641
7642 mo_global.set_policy_context('S', l_sel_org_id);
7643
7644 ---------------------------------------------------------------------
7645 Print_Debug (l_api_name, 'Calculate Tax');
7646 ---------------------------------------------------------------------
7647 l_success := ap_etax_pkg.calling_etax(
7648 p_invoice_id => NULL,
7649 p_calling_mode => 'CALCULATE',
7650 p_all_error_messages => 'N',
7651 p_error_code => l_error_code,
7652 p_calling_sequence => l_curr_calling_sequence);
7653
7654 IF (NOT l_success) THEN
7655 RAISE Tax_Exception_Handled;
7656 END IF;
7657
7658 ----------------------------------------------------------------
7659 Print_Debug(l_api_name, 'Initialize Invoice Holds Array');
7660 ----------------------------------------------------------------
7661 Initialize_Invoice_Holds(
7662 p_invoice_id => l_invoice_id,
7663 p_calling_sequence => l_curr_calling_sequence);
7664
7665 ---------------------------------------------------------------------
7666 Print_Debug (l_api_name, 'Generate Distributions');
7667 ---------------------------------------------------------------------
7668
7669 l_invoice_rec.invoice_id := l_invoice_id;
7670 l_invoice_rec.invoice_date := l_invoice_date;
7671 l_invoice_rec.invoice_currency_code := l_invoice_currency_code;
7672 l_invoice_rec.exchange_rate := l_exchange_rate;
7673 l_invoice_rec.exchange_rate_type := l_exchange_rate_type;
7674 l_invoice_rec.exchange_date := l_exchange_date;
7675 l_invoice_rec.vendor_id := l_vendor_id;
7676 l_invoice_rec.org_id := l_org_id;
7677 g_org_id := l_org_id;
7678
7679
7680 AP_APPROVAL_PKG.Generate_Distributions
7681 (p_invoice_rec => l_invoice_rec,
7682 p_base_currency_code => AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_org_id).base_currency_code,
7683 p_inv_batch_id => p_inv_batch_id,
7684 p_run_option => p_run_option,
7685 p_calling_sequence => l_curr_calling_sequence,
7686 x_error_code => l_error_code);
7687
7688 ---------------------------------------------------------------------
7689 Print_Debug (l_api_name, 'Generate Tax Distributions');
7690 ---------------------------------------------------------------------
7691 l_success := ap_etax_pkg.calling_etax (
7692 p_invoice_id => NULL,
7693 p_calling_mode => 'DISTRIBUTE',
7694 p_all_error_messages => 'N',
7695 p_error_code => l_error_code,
7696 p_calling_sequence => l_curr_calling_sequence);
7697
7698 IF (NOT l_success) THEN
7699 RAISE Tax_Exception_Handled;
7700 END IF;
7701
7702 IF l_sel_invoice_type = 'PAYMENT REQUEST' THEN
7703 l_calling_mode := 'PAYMENT REQUEST';
7704 ELSE
7705 l_calling_mode := 'APPROVE';
7706 END IF;
7707
7708 ---------------------------------------------------------------------
7709 Print_Debug(l_api_name, 'Approving specified invoice : '||l_selc_inv_cursor_blk_err(i).invoice_num);
7710 ---------------------------------------------------------------------
7711
7712 IF l_validation_request_id = p_conc_request_id THEN
7713
7714 IF validate_period(l_invoice_id) THEN
7715
7716 -- Cache Templates
7717 Cache_Tolerance_Templates(
7718 l_tolerance_id,
7719 l_services_tolerance_id,
7720 l_calling_sequence);
7721
7722 --Removed the hardcoded value of p_budget_control, bug6356402
7723 AP_APPROVAL_PKG.APPROVE(
7724 '',
7725 '',
7726 '',
7727 '',
7728 '',
7729 '',
7730 l_invoice_id,
7731 '',
7732 '',
7733 '',
7734 'Y',
7735 l_holds_count,
7736 l_approval_status,
7737 l_funds_return_code,
7738 l_calling_mode,
7739 'APXAPRVL',
7740 p_debug_switch
7741 );
7742 ELSE
7743 fnd_message.set_name('SQLAP', 'AP_INV_NEVER_OPEN_PERIOD');
7744 fnd_message.set_token('INV_NUM', l_invoice_num);
7745 fnd_file.put_line(fnd_file.log, fnd_message.get);
7746 END IF;
7747
7748 END IF;
7749 -- BUG 7509921 Update Validation Request id to null
7750 UPDATE ap_invoices_all
7751 SET validation_request_id = NULL
7752 WHERE invoice_id = l_selc_inv_cursor_blk_err(i).invoice_id;
7753 --End 7509921
7754 ---------------------------------------------------------------------
7755 Print_Debug(l_api_name, 'End Approving Single Invoice');
7756 ---------------------------------------------------------------------
7757
7758 EXCEPTION
7759 WHEN TAX_EXCEPTION_HANDLED THEN
7760
7761 ROLLBACK TO SAVEPOINT AP_APPROVAL_PKG_SP_INV;
7762
7763 ap_utilities_pkg.ap_get_message(l_approval_error);
7764 fnd_file.put_line (fnd_file.log, ' ');
7765 fnd_file.put_line (fnd_file.log, l_approval_error || 'Invoice Validation did not process Invoice Number: '|| l_invoice_num);
7766 fnd_file.put_line (fnd_file.log, ' Error: ' ||sqlerrm);
7767 Print_Debug (l_api_name, 'Exception: '|| sqlerrm ||' Invoice Validation did not process Invoice Number: '||
7768 l_invoice_num);
7769
7770
7771 WHEN OTHERS THEN
7772
7773 ROLLBACK TO SAVEPOINT AP_APPROVAL_PKG_SP_INV;
7774
7775 ap_utilities_pkg.ap_get_message(l_approval_error);
7776 fnd_file.put_line (fnd_file.log, ' ');
7777 fnd_file.put_line (fnd_file.log, l_approval_error || 'Invoice Validation did not process Invoice Number: '|| l_invoice_num);
7778 fnd_file.put_line (fnd_file.log, ' Error: ' ||sqlerrm);
7779 Print_Debug (l_api_name, 'Exception: '|| sqlerrm ||' Invoice Validation did not process Invoice Number: '||
7780 l_invoice_num);
7781
7782 END;
7783 END LOOP;
7784
7785 CLOSE SELC_INV_CURSOR_BULK_ERROR;
7786
7787 END IF; -- Marker 1
7788
7789
7790 IF l_blk_err = 'N' THEN -- Marker 2
7791
7792 ---------------------------------------------------------------------
7793 Print_Debug (l_api_name, 'Generate Distributions');
7794 ---------------------------------------------------------------------
7795
7796 OPEN SELECTED_INVOICES_CURSOR;
7797 LOOP
7798 FETCH SELECTED_INVOICES_CURSOR
7799 BULK COLLECT INTO AP_APPROVAL_PKG.G_SELECTED_INVOICES
7800 LIMIT l_commit_size;
7801
7802 EXIT WHEN SELECTED_INVOICES_CURSOR%NOTFOUND
7803 AND AP_APPROVAL_PKG.G_SELECTED_INVOICES.COUNT <= 0;
7804
7805 FOR i IN 1..AP_APPROVAL_PKG.G_SELECTED_INVOICES.COUNT
7806 LOOP
7807 -- Set Policy
7808 IF AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).org_id <> nvl(l_old_org_id, -3115) THEN
7809
7810 mo_global.set_policy_context
7811 ('S', AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).org_id);
7812
7813 l_old_org_id := AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).org_id;
7814
7815 END IF;
7816
7817 -- Initialize Invoice Holds Array
7818 Initialize_Invoice_Holds(
7819 p_invoice_id => AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).invoice_id,
7820 p_calling_sequence => l_curr_calling_sequence);
7821
7822 g_org_id := AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).org_id;
7823
7824 AP_APPROVAL_PKG.Generate_Distributions
7825 (p_invoice_rec => AP_APPROVAL_PKG.G_SELECTED_INVOICES(i),
7826 p_base_currency_code => AP_APPROVAL_PKG.G_OPTIONS_TABLE(g_org_id).base_currency_code,
7827 p_inv_batch_id => p_inv_batch_id,
7828 p_run_option => p_run_option,
7829 p_calling_sequence => l_curr_calling_sequence,
7830 x_error_code => l_error_code);
7831
7832 END LOOP;
7833
7834 AP_APPROVAL_PKG.G_SELECTED_INVOICES.DELETE;
7835
7836 END LOOP;
7837 CLOSE SELECTED_INVOICES_CURSOR;
7838
7839 ---------------------------------------------------------------------
7840 Print_Debug (l_api_name, 'Generate Tax Distributions');
7841 ---------------------------------------------------------------------
7842
7843 SAVEPOINT AP_APPROVAL_PKG_SP_TAX_DIST;
7844
7845 l_success := ap_etax_pkg.calling_etax (
7846 p_invoice_id => NULL,
7847 p_calling_mode => 'DISTRIBUTE',
7848 p_all_error_messages => 'N',
7849 p_error_code => l_error_code,
7850 p_calling_sequence => l_curr_calling_sequence);
7851
7852
7853 IF (NOT l_success) THEN -- Marker 3
7854
7855 ROLLBACK TO SAVEPOINT AP_APPROVAL_PKG_SP_TAX_DIST;
7856
7857 ---------------------------------------------------------------------
7858 Print_Debug (l_api_name, 'Set Concurrent Request Warning');
7859 ---------------------------------------------------------------------
7860
7861 l_conc_status := 'WARNING';
7862 --bug 7512258 removed call to FND_CONCURRENT.SET_COMPLETION_STATUS
7863
7864 ---------------------------------------------------------------------
7865 Print_Debug (l_api_name, 'Begin Single Mode');
7866 ---------------------------------------------------------------------
7867
7868 OPEN SELC_INV_CURSOR_BULK_ERROR;
7869 FETCH SELC_INV_CURSOR_BULK_ERROR
7870 BULK COLLECT INTO l_selc_inv_cursor_blk_err;
7871
7872 UPDATE ap_invoices_all
7873 SET validation_request_id = NULL
7874 WHERE validation_request_id IS NOT NULL
7875 AND invoice_id IN (SELECT invoice_id
7876 FROM ap_invoices_all
7877 WHERE validation_request_id = AP_APPROVAL_PKG.G_VALIDATION_REQUEST_ID);
7878
7879 FOR i IN 1..l_selc_inv_cursor_blk_err.count
7880 LOOP
7881
7882 SAVEPOINT AP_APPROVAL_PKG_SP_TAX_DIST;
7883
7884 UPDATE ap_invoices_all
7885 SET validation_request_id = AP_APPROVAL_PKG.G_VALIDATION_REQUEST_ID
7886 WHERE invoice_id = l_selc_inv_cursor_blk_err(i).invoice_id;
7887
7888 BEGIN
7889
7890 mo_global.set_policy_context('S', l_selc_inv_cursor_blk_err(i).org_id);
7891
7892 ---------------------------------------------------------------------
7893 Print_Debug (l_api_name, 'Generate Tax Distributions: '||l_selc_inv_cursor_blk_err(i).invoice_id);
7894 ---------------------------------------------------------------------
7895 l_success := ap_etax_pkg.calling_etax (
7896 p_invoice_id => NULL,
7897 p_calling_mode => 'DISTRIBUTE',
7898 p_all_error_messages => 'N',
7899 p_error_code => l_error_code,
7900 p_calling_sequence => l_curr_calling_sequence);
7901
7902 IF (NOT l_success) THEN
7903 RAISE Tax_Dist_Exception_Handled;
7904 END IF;
7905 --Bug 7509921
7906 IF l_sel_invoice_type = 'PAYMENT REQUEST' THEN
7907 l_calling_mode := 'PAYMENT REQUEST';
7908 ELSE
7909 l_calling_mode := 'APPROVE';
7910 END IF;
7911
7912 ---------------------------------------------------------------------
7913 Print_Debug(l_api_name, 'Approving specified invoice : '||l_selc_inv_cursor_blk_err(i).invoice_num);
7914 ---------------------------------------------------------------------
7915
7916 IF l_validation_request_id = p_conc_request_id THEN
7917
7918 IF validate_period(l_invoice_id) THEN
7919
7920 -- Cache Templates
7921 Cache_Tolerance_Templates(
7922 l_tolerance_id,
7923 l_services_tolerance_id,
7924 l_calling_sequence);
7925
7926 --Removed the hardcoded value of p_budget_control, bug6356402
7927 AP_APPROVAL_PKG.APPROVE(
7928 '',
7929 '',
7930 '',
7931 '',
7932 '',
7933 '',
7934 l_invoice_id,
7935 '',
7936 '',
7937 '',
7938 'Y',
7939 l_holds_count,
7940 l_approval_status,
7941 l_funds_return_code,
7942 l_calling_mode,
7943 'APXAPRVL',
7944 p_debug_switch
7945 );
7946 ELSE
7947 fnd_message.set_name('SQLAP', 'AP_INV_NEVER_OPEN_PERIOD');
7948 fnd_message.set_token('INV_NUM', l_invoice_num);
7949 fnd_file.put_line(fnd_file.log, fnd_message.get);
7950 END IF;
7951
7952 END IF;
7953 -- BUG 7509921 Update Validation Request id to null
7954 UPDATE ap_invoices_all
7955 SET validation_request_id = NULL
7956 WHERE invoice_id = l_selc_inv_cursor_blk_err(i).invoice_id;
7957 --End 7509921
7958 ---------------------------------------------------------------------
7959 Print_Debug(l_api_name, 'End Approving Single Invoice');
7960 ---------------------------------------------------------------------
7961
7962
7963 EXCEPTION
7964 WHEN TAX_DIST_EXCEPTION_HANDLED THEN
7965
7966 ROLLBACK TO SAVEPOINT AP_APPROVAL_PKG_SP_TAX_DIST;
7967
7968 ap_utilities_pkg.ap_get_message(l_approval_error);
7969
7970 fnd_file.put_line (fnd_file.log, ' ');
7971 fnd_file.put_line (fnd_file.log, l_approval_error || 'Invoice Validation did not process Invoice Number: '||
7972 l_selc_inv_cursor_blk_err(i).invoice_num);
7973 fnd_file.put_line (fnd_file.log, ' Error: ' ||sqlerrm);
7974 Print_Debug (l_api_name, 'Exception: '|| sqlerrm ||' Invoice Validation did not process Invoice Number: '||
7975 l_selc_inv_cursor_blk_err(i).invoice_num);
7976
7977 WHEN OTHERS THEN
7978
7979 ROLLBACK TO SAVEPOINT AP_APPROVAL_PKG_SP_TAX_DIST;
7980
7981 ap_utilities_pkg.ap_get_message(l_approval_error);
7982
7983 fnd_file.put_line (fnd_file.log, ' ');
7984 fnd_file.put_line (fnd_file.log, l_approval_error || 'Invoice Validation did not process Invoice Number: '||
7985 l_selc_inv_cursor_blk_err(i).invoice_num);
7986 fnd_file.put_line (fnd_file.log, ' Error: ' ||sqlerrm);
7987 Print_Debug (l_api_name, 'Exception: '|| sqlerrm ||' Invoice Validation did not process Invoice Number: '||
7988 l_selc_inv_cursor_blk_err(i).invoice_num);
7989
7990 END;
7991 END LOOP;
7992 CLOSE SELC_INV_CURSOR_BULK_ERROR;
7993
7994 END IF; -- Marker 3
7995
7996 ---------------------------------------------------------------------
7997 Print_Debug (l_api_name, 'Call Approve per invoice');
7998 ---------------------------------------------------------------------
7999
8000 OPEN SELECTED_INVOICES_CURSOR;
8001 LOOP
8002 FETCH SELECTED_INVOICES_CURSOR
8003 BULK COLLECT INTO AP_APPROVAL_PKG.G_SELECTED_INVOICES
8004 LIMIT l_commit_size;
8005
8006 EXIT WHEN SELECTED_INVOICES_CURSOR%NOTFOUND
8007 and AP_APPROVAL_PKG.G_SELECTED_INVOICES.COUNT <= 0;
8008
8009 FOR i IN 1..AP_APPROVAL_PKG.G_SELECTED_INVOICES.COUNT LOOP
8010
8011 -- Set Policy
8012 IF AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).org_id <> nvl(l_old_org_id, -3115) THEN
8013
8014 mo_global.set_policy_context('S', AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).org_id);
8015
8016 l_old_org_id := AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).org_id;
8017
8018 END IF;
8019
8020 -- Set Calling Mode
8021 IF AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).invoice_type_lookup_code = 'PAYMENT REQUEST' THEN
8022 l_calling_mode := 'PAYMENT REQUEST';
8023 ELSE
8024 l_calling_mode := 'APPROVE';
8025
8026 -- Cache Templates
8027 Cache_Tolerance_Templates(
8028 AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).tolerance_id,
8029 AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).services_tolerance_id,
8030 l_calling_sequence);
8031 END IF;
8032
8033 -- Call Approve
8034 IF validate_period(
8035 AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).invoice_id) THEN
8036
8037 --Removed the hardcoded value of p_budget_control, bug6356402
8038 AP_APPROVAL_PKG.approve(
8039 '',
8040 '',
8041 '',
8042 '',
8043 '',
8044 '',
8045 AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).invoice_id,
8046 '',
8047 '',
8048 '',
8049 'Y',
8050 l_holds_count,
8051 l_approval_status,
8052 l_funds_return_code,
8053 l_calling_mode,
8054 'APXAPRVL',
8055 p_debug_switch
8056 );
8057
8058 ELSE
8059 fnd_message.set_name('SQLAP', 'AP_INV_NEVER_OPEN_PERIOD');
8060 fnd_message.set_token('INV_NUM', AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).invoice_num);
8061 fnd_file.put_line(fnd_file.log, fnd_message.get);
8062 END IF;
8063
8064 -- Update Validation Request_ID to NULL;
8065 UPDATE ap_invoices_all
8066 SET validation_request_id = NULL
8067 WHERE invoice_id = AP_APPROVAL_PKG.G_SELECTED_INVOICES(i).invoice_id;
8068
8069 END LOOP;
8070
8071 AP_APPROVAL_PKG.G_SELECTED_INVOICES.DELETE;
8072
8073 END LOOP;
8074
8075 CLOSE SELECTED_INVOICES_CURSOR;
8076
8077 END IF; -- Marker 2
8078
8079 END IF; -- Marker 0
8080
8081 ---------------------------------------------------------------------
8082 Print_Debug (l_api_name, 'Populate ap_temp_approval_temp_gt');
8083 ---------------------------------------------------------------------
8084
8085 DELETE FROM ap_temp_approval_gt;
8086
8087 FORALL i in g_org_holds.first..g_org_holds.last
8088 INSERT INTO ap_temp_approval_gt VALUES g_org_holds(i);
8089
8090 COMMIT;
8091
8092 ---------------------------------------------------------------------
8093 Print_Debug (l_api_name, 'Get the count of rows that will be printed');
8094 ---------------------------------------------------------------------
8095
8096 SELECT count(*) into p_report_holds_count
8097 FROM ap_temp_approval_gt
8098 WHERE number_holds_placed <> 0
8099 OR number_holds_released <> 0;
8100
8101 -- 7512258
8102 -- moved the call to end of the approval process
8103 ---------------------------------------------------------------------
8104 Print_Debug (l_api_name, 'Set Concurrent Request Warning');
8105 ---------------------------------------------------------------------
8106 IF l_conc_status = 'WARNING' THEN
8107 l_errbuf := 'Warning/Error message to be displayed';
8108 l_set_status := FND_CONCURRENT.SET_COMPLETION_STATUS(l_conc_status,l_errbuf);
8109 END IF;
8110
8111
8112 ---------------------------------------------------------------------
8113 Print_Debug(l_api_name, 'AP_APPROVAL_PKG.BATCH_APPROVAL.END');
8114 ---------------------------------------------------------------------
8115
8116 RETURN(TRUE);
8117
8118 EXCEPTION
8119
8120 WHEN TAX_EXCEPTION THEN
8121 AP_UTILITIES_PKG.AP_GET_MESSAGE(l_approval_error);
8122 fnd_file.put_line(fnd_file.log,l_approval_error);
8123 fnd_file.put_line(fnd_file.log,sqlerrm);
8124 Print_Debug(l_api_name, 'Exception: '||sqlerrm);
8125
8126 --Bug7246971
8127
8128 FND_MESSAGE.SET_NAME('SQLAP','AP_TAX_EXCEPTION');
8129 IF l_error_code IS NOT NULL THEN
8130 FND_MESSAGE.SET_TOKEN('ERROR', l_error_code);
8131 ELSE
8132 FND_MESSAGE.SET_TOKEN('ERROR', SQLERRM);
8133 END IF;
8134 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
8135 FND_MESSAGE.SET_TOKEN('PARAMETERS',
8136 'Run Option = '|| p_run_option
8137 ||', Batch Id = '|| to_char(p_inv_batch_id)
8138 ||', Begin Date = '|| to_char(p_inv_start_date)
8139 ||', End Date = '|| to_char(p_inv_end_date)
8140 ||', Vendor Id = '|| to_char(p_vendor_id)
8141 ||', Pay Group = '|| p_pay_group
8142 ||', Invoice Id = '|| to_char(p_invoice_id)
8143 ||', Entered By = '|| to_char(p_entered_by)
8144 ||', Concurrent Request Id = '|| to_char(p_conc_request_id)
8145 ||', Org Id = '|| to_char(p_org_id));
8146 APP_EXCEPTION.RAISE_EXCEPTION;
8147
8148 --Bug7246971
8149
8150 RETURN (FALSE);
8151
8152 WHEN OTHERS THEN
8153 AP_UTILITIES_PKG.AP_GET_MESSAGE(l_approval_error);
8154 fnd_file.put_line(fnd_file.log,l_approval_error);
8155 fnd_file.put_line(fnd_file.log,sqlerrm);
8156 Print_Debug(l_api_name, 'Others: Exception: '||sqlerrm);
8157
8158 --Bug7246971
8159
8160 IF (SQLCODE <> -20001) THEN
8161 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
8162 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
8163 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
8164 FND_MESSAGE.SET_TOKEN('PARAMETERS',
8165 'Run Option = '|| p_run_option
8166 ||', Batch Id = '|| to_char(p_inv_batch_id)
8167 ||', Begin Date = '|| to_char(p_inv_start_date)
8168 ||', End Date = '|| to_char(p_inv_end_date)
8169 ||', Vendor Id = '|| to_char(p_vendor_id)
8170 ||', Pay Group = '|| p_pay_group
8171 ||', Invoice Id = '|| to_char(p_invoice_id)
8172 ||', Entered By = '|| to_char(p_entered_by)
8173 ||', Concurrent Request Id = '|| to_char(p_conc_request_id)
8174 ||', Org Id = '|| to_char(p_org_id));
8175
8176 END IF;
8177 APP_EXCEPTION.RAISE_EXCEPTION;
8178
8179 --Bug7246971
8180
8181 RETURN (FALSE);
8182
8183 END BATCH_APPROVAL;
8184
8185 PROCEDURE Cache_Options
8186 (p_calling_sequence IN VARCHAR2) IS
8187
8188 CURSOR C_Options_Query IS
8189 SELECT nvl(gls.chart_of_accounts_id, -1) chart_of_accounts_id,
8190 nvl(sp.set_of_books_id, -1) set_of_books_id,
8191 nvl(sp.automatic_offsets_flag, 'N') automatic_offsets_flag,
8192 nvl(recalc_pay_schedule_flag, 'N') recalc_pay_schedule_flag,
8193 sp.liability_post_lookup_code liability_post_lookup_code,
8194 nvl(sp.rate_var_gain_ccid, -1) rate_var_gain_ccid,
8195 nvl(sp.rate_var_loss_ccid, -1) rate_var_loss_ccid,
8196 nvl(sp.base_currency_code, 'USD') base_currency_code,
8197 nvl(sp.match_on_tax_flag, 'N') match_on_tax_flag,
8198 nvl(sp.enforce_tax_from_account, 'N') enforce_tax_from_account,
8199 nvl(fp.inv_encumbrance_type_id, -1) inv_encumbrance_type_id,
8200 nvl(fp.purch_encumbrance_type_id, -1) purch_encumbrance_type_id,
8201 nvl(fp.receipt_acceptance_days, 0) receipt_acceptance_days,
8202 nvl(gl_date_from_receipt_flag, 'S') gl_date_from_receipt_flag,
8203 accounting_method_option,
8204 secondary_accounting_method,
8205 nvl(fp.cash_basis_enc_nr_tax, 'EXCLUDE RECOVERABLE TAX') cash_basis_enc_nr_tax,
8206 nvl(fp.non_recoverable_tax_flag, 'N') non_recoverable_tax_flag,
8207 nvl(disc_is_inv_less_tax_flag,'N') disc_is_inv_less_tax_flag,
8208 fp.org_id org_id,
8209 5 System_User,
8210 fnd_global.user_id User_Id
8211 FROM ap_system_parameters_all sp,
8212 financials_system_params_all fp,
8213 gl_sets_of_books gls,
8214 Mo_Glob_Org_Access_Tmp mo
8215 WHERE sp.set_of_books_id = gls.set_of_books_id
8216 AND sp.org_id = fp.org_id
8217 AND mo.organization_id = fp.org_id;
8218
8219 l_options_rec C_Options_Query%rowtype;
8220
8221 l_debug_loc VARCHAR2(30) := 'Cache_Options';
8222 l_curr_calling_sequence VARCHAR2(2000);
8223 l_debug_info VARCHAR2(1000);
8224 BEGIN
8225
8226 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
8227
8228 ------------------------------------------------------------
8229 l_debug_info := 'Retrieving system parameters for approval';
8230 Print_Debug(l_debug_loc,l_debug_info);
8231 ------------------------------------------------------------
8232
8233 OPEN C_Options_Query;
8234 LOOP
8235 FETCH C_Options_Query INTO l_options_rec;
8236 EXIT WHEN C_Options_Query%NOTFOUND;
8237
8238 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).chart_of_accounts_id
8239 := l_options_rec.chart_of_accounts_id;
8240 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).set_of_books_id
8241 := l_options_rec.set_of_books_id;
8242 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).automatic_offsets_flag
8243 := l_options_rec.automatic_offsets_flag;
8244 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).recalc_pay_schedule_flag
8245 := l_options_rec.recalc_pay_schedule_flag;
8246 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).liability_post_lookup_code
8247 := l_options_rec.liability_post_lookup_code;
8248 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).rate_var_gain_ccid
8249 := l_options_rec.rate_var_gain_ccid;
8250 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).rate_var_loss_ccid
8251 := l_options_rec.rate_var_loss_ccid;
8252 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).base_currency_code
8253 := l_options_rec.base_currency_code;
8254 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).match_on_tax_flag
8255 := l_options_rec.match_on_tax_flag;
8256 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).enforce_tax_from_account
8257 := l_options_rec.enforce_tax_from_account;
8258 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).inv_encumbrance_type_id
8259 := l_options_rec.inv_encumbrance_type_id;
8260 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).purch_encumbrance_type_id
8261 := l_options_rec.purch_encumbrance_type_id;
8262 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).receipt_acceptance_days
8263 := l_options_rec.receipt_acceptance_days;
8264 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).gl_date_from_receipt_flag
8265 := l_options_rec.gl_date_from_receipt_flag;
8266 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).accounting_method_option
8267 := l_options_rec.accounting_method_option;
8268 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).secondary_accounting_method
8269 := l_options_rec.secondary_accounting_method;
8270 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).cash_basis_enc_nr_tax
8271 := l_options_rec.cash_basis_enc_nr_tax;
8272 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).non_recoverable_tax_flag
8273 := l_options_rec.non_recoverable_tax_flag;
8274 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).disc_is_inv_less_tax_flag
8275 := l_options_rec.disc_is_inv_less_tax_flag;
8276 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).org_id
8277 := l_options_rec.org_id;
8278 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).System_User
8279 := l_options_rec.System_User;
8280 AP_APPROVAL_PKG.G_OPTIONS_TABLE(l_options_rec.org_id).user_id
8281 := l_options_rec.user_id;
8282
8283 END LOOP;
8284 CLOSE C_Options_Query;
8285
8286 EXCEPTION
8287 WHEN OTHERS THEN
8288 IF (SQLCODE <> -20001) THEN
8289 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
8290 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
8291 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
8292 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
8293 END IF;
8294
8295 IF C_Options_Query%ISOPEN THEN
8296 CLOSE C_Options_Query;
8297 END IF;
8298
8299 APP_EXCEPTION.RAISE_EXCEPTION;
8300
8301 END Cache_Options;
8302
8303
8304 PROCEDURE Cache_Tolerance_Templates
8305 ( p_tolerance_id IN NUMBER,
8306 p_services_tolerance_id IN NUMBER,
8307 p_calling_sequence IN VARCHAR2) IS
8308 l_debug_loc VARCHAR2(30) := 'Cache_Tolerance_Templates';
8309 l_curr_calling_sequence VARCHAR2(2000);
8310 l_debug_info VARCHAR2(1000);
8311 BEGIN
8312
8313 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
8314
8315 ------------------------------------------------------------
8316 l_debug_info := 'Retrieving Supplier Site Tolerances';
8317 Print_Debug(l_debug_loc,l_debug_info);
8318 ------------------------------------------------------------
8319
8320 IF p_tolerance_id IS NOT NULL THEN
8321
8322 IF NOT G_GOODS_TOLERANCES.exists(p_tolerance_id) THEN
8323
8324 SELECT decode( price_tolerance, NULL, NULL,
8325 (1 + (price_tolerance/100))),
8326 decode(quantity_tolerance, NULL, NULL,
8327 (1 + (quantity_tolerance/100))),
8328 decode( qty_received_tolerance, NULL, NULL,
8329 (1 + (qty_received_tolerance/100))),
8330 max_qty_ord_tolerance,
8331 max_qty_rec_tolerance,
8332 ship_amt_tolerance,
8333 rate_amt_tolerance,
8334 total_amt_tolerance
8335 INTO G_GOODS_TOLERANCES(p_tolerance_id).price_tolerance,
8336 G_GOODS_TOLERANCES(p_tolerance_id).quantity_tolerance,
8337 G_GOODS_TOLERANCES(p_tolerance_id).qty_received_tolerance,
8338 G_GOODS_TOLERANCES(p_tolerance_id).max_qty_ord_tolerance,
8339 G_GOODS_TOLERANCES(p_tolerance_id).max_qty_rec_tolerance,
8340 G_GOODS_TOLERANCES(p_tolerance_id).ship_amt_tolerance,
8341 G_GOODS_TOLERANCES(p_tolerance_id).rate_amt_tolerance,
8342 G_GOODS_TOLERANCES(p_tolerance_id).total_amt_tolerance
8343 FROM ap_tolerance_templates
8344 WHERE tolerance_id = p_tolerance_id;
8345
8346 END IF;
8347 END IF;
8348
8349 IF p_services_tolerance_id IS NOT NULL THEN
8350 IF NOT G_SERVICES_TOLERANCES.exists(p_services_tolerance_id) THEN
8351 SELECT decode(quantity_tolerance, NULL, NULL,
8352 (1 + (quantity_tolerance/100))),
8353 decode( qty_received_tolerance, NULL, NULL,
8354 (1 + (qty_received_tolerance/100))),
8355 max_qty_ord_tolerance,
8356 max_qty_rec_tolerance,
8357 ship_amt_tolerance,
8358 rate_amt_tolerance,
8359 total_amt_tolerance
8360 INTO G_SERVICES_TOLERANCES(p_services_tolerance_id).amount_tolerance,
8361 G_SERVICES_TOLERANCES(p_services_tolerance_id).amt_received_tolerance,
8362 G_SERVICES_TOLERANCES(p_services_tolerance_id).max_amt_ord_tolerance,
8363 G_SERVICES_TOLERANCES(p_services_tolerance_id).max_amt_rec_tolerance,
8364 G_SERVICES_TOLERANCES(p_services_tolerance_id).ser_ship_amt_tolerance,
8365 G_SERVICES_TOLERANCES(p_services_tolerance_id).ser_rate_amt_tolerance,
8366 G_SERVICES_TOLERANCES(p_services_tolerance_id).ser_total_amt_tolerance
8367 FROM ap_tolerance_templates
8368 WHERE tolerance_id = p_services_tolerance_id;
8369 END IF;
8370 END IF;
8371
8372 EXCEPTION
8373 WHEN OTHERS THEN
8374 IF (SQLCODE <> -20001) THEN
8375 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
8376 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
8377 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
8378 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
8379 END IF;
8380 APP_EXCEPTION.RAISE_EXCEPTION;
8381 END Cache_Tolerance_Templates;
8382
8383 PROCEDURE Generate_Distributions
8384 (p_invoice_rec IN AP_APPROVAL_PKG.Invoice_Rec,
8385 p_base_currency_code IN VARCHAR2,
8386 p_inv_batch_id IN NUMBER,
8387 p_run_option IN VARCHAR2,
8388 p_calling_sequence IN VARCHAR2,
8389 x_error_code IN VARCHAR2,
8390 p_calling_mode IN VARCHAR2 ) IS /*bug 6833543 - added p_calling_mode*/
8391
8392 t_inv_lines_table AP_INVOICES_PKG.t_invoice_lines_table;
8393
8394 l_curr_calling_sequence VARCHAR2(2000);
8395 l_debug_info VARCHAR2(2000);
8396 l_debug_loc VARCHAR2(30) := 'Generate_Distributions';
8397
8398 l_prorate_across_all_items VARCHAR2(1);
8399 l_error_code VARCHAR2(4000);
8400 l_debug_context VARCHAR2(2000);
8401 l_success BOOLEAN;
8402
8403 l_system_user NUMBER := 5;
8404
8405 l_holds HOLDSARRAY;
8406 l_hold_count COUNTARRAY;
8407 l_release_count COUNTARRAY;
8408 l_insufficient_data_exist BOOLEAN := FALSE;
8409
8410 l_recouped_amount NUMBER;
8411 l_retained_amount NUMBER;
8412 l_result BOOLEAN;
8413
8414 l_line_variance_hold_exist BOOLEAN := FALSE;
8415 l_need_to_round_flag VARCHAR2(1) := 'Y';
8416
8417 l_not_exist_nond_line VARCHAR2(1); --bug6783517
8418
8419 -- bug6783517 starts
8420 CURSOR dist_gen_holds(p_invoice_id NUMBER)
8421 IS
8422 SELECT hold_lookup_code
8423 FROM ap_holds_all
8424 WHERE hold_lookup_code IN ('DISTRIBUTION SET INACTIVE',
8425 'SKELETON DISTRIBUTION SET',
8426 'CANNOT OVERLAY ACCOUNT',
8427 'INVALID DEFAULT ACCOUNT',
8428 'CANNOT EXECUTE ALLOCATION',
8429 'CANNOT OVERLAY ACCOUNT',
8430 'INVALID DEFAULT ACCOUNT',
8431 'PERIOD CLOSED',
8432 'PROJECT GL DATE CLOSED')
8433 AND release_lookup_code IS NULL
8434 AND invoice_id = p_invoice_id;
8435
8436 TYPE holds_tab_type IS
8437 TABLE OF AP_HOLDS_ALL.HOLD_LOOKUP_CODE%TYPE
8438 INDEX BY BINARY_INTEGER;
8439
8440 t_holds_tab holds_tab_type;
8441 -- bug6783517 ends
8442
8443 BEGIN
8444
8445 l_curr_calling_sequence := 'AP_APPROVAL_PKG.'||l_debug_loc||'<-'||p_calling_sequence;
8446
8447 ----------------------------------------------------------------
8448 l_debug_info := 'Check Line Variance at invoice header level';
8449 Print_Debug(l_debug_loc, l_debug_info);
8450 ----------------------------------------------------------------
8451
8452 Check_Line_Variance(
8453 p_invoice_rec.invoice_id,
8454 l_system_user,
8455 l_holds,
8456 l_hold_count,
8457 l_release_count,
8458 l_line_variance_hold_exist,
8459 l_curr_calling_sequence,
8460 p_base_currency_code); --bug 7271262
8461
8462 IF ( p_invoice_rec.invoice_currency_code <> p_base_currency_code ) THEN
8463
8464 ----------------------------------------------------------------
8465 l_debug_info := 'Calculate Base Amount. Round if no line variance';
8466 Print_Debug(l_debug_loc, l_debug_info);
8467 ----------------------------------------------------------------
8468
8469 IF ( l_line_variance_hold_exist ) THEN
8470 l_need_to_round_flag := 'N';
8471 END IF;
8472
8473 Line_Base_Amount_Calculation(
8474 p_invoice_id => p_invoice_rec.invoice_id,
8475 p_invoice_currency_code => p_invoice_rec.invoice_currency_code,
8476 p_base_currency_code => p_base_currency_code,
8477 p_exchange_rate => p_invoice_rec.exchange_rate,
8478 p_need_to_round_flag => l_need_to_round_flag,
8479 p_calling_sequence => l_curr_calling_sequence);
8480
8481 END IF;
8482
8483 ----------------------------------------------------------------
8484 l_debug_info := 'Bulk Collect Invoice Lines';
8485 Print_Debug(l_debug_loc, l_debug_info);
8486 ----------------------------------------------------------------
8487
8488 OPEN Invoice_Line_Cur (p_invoice_rec.invoice_id);
8489 FETCH Invoice_Line_Cur BULK COLLECT
8490 INTO t_inv_lines_table;
8491 CLOSE Invoice_Line_Cur;
8492
8493 /* There are some holds which are put on the invoice when */
8494 /* the distributions are generated for the Invoice */
8495 /* But even after the fix in the bug6731107, if a distribution */
8496 /* is inserted for the Invoice, then the generate_dist flag */
8497 /* for the line is set to 'D', and hence the code */
8498 /* Execute_Dist_Generation_Check would no longer be called */
8499 /*
8500 /* As such, when there are no lines on the invoice */
8501 /* for which the generate_dist flag is NOT 'D' then we would */
8502 /* release all the holds on the Invoice which are put during */
8503 /* the dist generation process : bug6783517 */
8504
8505
8506 l_debug_info := 'Checking if there exists a non d line';
8507
8508 BEGIN
8509
8510 SELECT 'Y'
8511 INTO l_not_exist_nond_line
8512 FROM ap_invoice_lines_all ail
8513 WHERE ail.invoice_id = p_invoice_rec.invoice_id
8514 AND nvl(ail.generate_dists, 'N') <> 'D'
8515 AND rownum < 2;
8516
8517 EXCEPTION
8518 WHEN NO_DATA_FOUND THEN
8519 l_not_exist_nond_line := 'N';
8520
8521 END;
8522
8523 /*bug 6833543: While cancelling an invoice that has a non D line
8524 and postable hold which is not user releasable like CANNOT EXECUTE
8525 ALLOCATION, the code failed to release the holds
8526 and the invoice gets stuck in a semi-cancelled state.Fix of
8527 6783517 has to take care of releasing holds in such scenario i.e
8528 when p_calling_mode is CANCEL*/
8529
8530 l_debug_info := 'If there is no non d line or p_calling_mode is CANCEL, then fetch all the dist gen holds';
8531
8532 IF (l_not_exist_nond_line = 'N' OR p_calling_mode = 'CANCEL') THEN
8533 OPEN dist_gen_holds (p_invoice_rec.invoice_id);
8534 FETCH dist_gen_holds BULK COLLECT INTO t_holds_tab;
8535 CLOSE dist_gen_holds;
8536 END IF;
8537
8538 l_debug_info := 'Release all the non D holds';
8539
8540 IF nvl(t_holds_tab.count, 0) > 0 THEN
8541
8542 FOR i IN NVL(t_holds_tab.first,0)..NVL(t_holds_tab.last,0)
8543 LOOP
8544
8545 l_debug_info := 'Inside the loop';
8546
8547 Process_Inv_Hold_Status(
8548 p_invoice_rec.invoice_id,
8549 null,
8550 null,
8551 t_holds_tab(i),
8552 'N',
8553 null,
8554 l_system_user,
8555 l_holds,
8556 l_hold_count,
8557 l_release_count,
8558 l_curr_calling_sequence);
8559
8560 END LOOP;
8561
8562 END IF;
8563 /* bug 6783517 ends */
8564
8565 -- Perf 6759699
8566 -- If the p_run_option is not new then the below function will be
8567 -- called once for a invoice id.
8568
8569 IF ( nvl(t_inv_lines_table.count,0) <> 0 AND
8570 (nvl(p_run_option,'Yes') <> 'New' ))THEN
8571
8572 Update_Inv_Dists_To_Selected( p_invoice_rec.invoice_id,
8573 null ,
8574 p_run_option,
8575 l_curr_calling_sequence);
8576 End IF; -- 6759699
8577
8578 FOR i IN NVL(t_inv_lines_table.first,0)..NVL(t_inv_lines_table.last,0)
8579 LOOP
8580 IF (t_inv_lines_table.exists(i)) THEN
8581
8582 IF t_inv_lines_table(i).line_type_lookup_code in
8583 ('FREIGHT', 'MISCELLANEOUS') THEN
8584
8585 ----------------------------------------------------------------
8586 l_debug_info := 'Create charge allocations ';
8587 Print_Debug(l_debug_loc, l_debug_info);
8588 ----------------------------------------------------------------
8589
8590 SELECT nvl(prorate_across_all_items,'N')
8591 INTO l_prorate_across_all_items
8592 FROM ap_invoice_lines_all
8593 WHERE invoice_id = t_inv_lines_table(i).invoice_id
8594 AND line_number = t_inv_lines_table(i).line_number;
8595
8596 IF (l_prorate_across_all_items='Y') then
8597
8598 l_success := AP_ALLOCATION_RULES_PKG.Create_Proration_Rule(
8599 t_inv_lines_table(i).invoice_id,
8600 t_inv_lines_table(i).line_number,
8601 NULL,
8602 'APAPRVLB',
8603 l_error_code,
8604 l_debug_info,
8605 l_debug_context,
8606 'Execute_Dist_Generation_Check');
8607
8608 END IF;
8609 END IF;
8610
8611 -- Bug fix : 6731107: Added 'D' to the below if stmt
8612 IF (t_inv_lines_table(i).generate_dists IN ('D' , 'Y') ) THEN
8613
8614 IF t_inv_lines_table(i).line_type_lookup_code <> 'TAX' THEN
8615
8616 ----------------------------------------------------------------
8617 l_debug_info := 'Check Insufficient Line Info: Number and Type: '||
8618 t_inv_lines_table(i).line_number ||' and '||
8619 t_inv_lines_table(i).line_type_lookup_code;
8620 Print_Debug(l_debug_loc, l_debug_info);
8621 ----------------------------------------------------------------
8622
8623 Check_Insufficient_Line_Data(
8624 p_inv_line_rec => t_inv_lines_table(i),
8625 p_system_user => l_system_user,
8626 p_holds => l_holds,
8627 p_holds_count => l_hold_count,
8628 p_release_count => l_release_count,
8629 p_insufficient_data_exist => l_insufficient_data_exist,
8630 p_calling_mode => 'PERMANENT_DISTRIBUTIONS',
8631 p_calling_sequence => l_curr_calling_sequence );
8632
8633 IF ( (NOT l_insufficient_data_exist)
8634 AND (t_inv_lines_table(i).generate_dists = 'Y') ) THEN
8635 --Bug fix 6731107 : added the AND condition to above IF stmt.
8636 --Invoice distributions should be generated only when generate_dists flag is set to 'Y'
8637
8638 ----------------------------------------------------------------
8639 l_debug_info := 'Generate Invoice Distributions';
8640 Print_Debug(l_debug_loc, l_debug_info);
8641 ----------------------------------------------------------------
8642
8643 l_result := Execute_Dist_Generation_Check(
8644 p_batch_id => p_inv_batch_id,
8645 p_invoice_date => p_invoice_rec.invoice_date,
8646 p_vendor_id => p_invoice_rec.vendor_id,
8647 p_invoice_currency => p_invoice_rec.invoice_currency_code,
8648 p_exchange_rate => p_invoice_rec.exchange_rate,
8649 p_exchange_rate_type => p_invoice_rec.exchange_rate_type,
8650 p_exchange_date => p_invoice_rec.exchange_date,
8651 p_inv_line_rec => t_inv_lines_table(i),
8652 p_system_user => l_system_user,
8653 p_holds => l_holds,
8654 p_holds_count => l_hold_count,
8655 p_release_count => l_release_count,
8656 p_generate_permanent => 'Y',
8657 p_calling_mode => 'PERMANENT_DISTRIBUTIONS',
8658 p_error_code => l_error_code,
8659 p_curr_calling_sequence => l_curr_calling_sequence);
8660
8661 ELSE
8662 ----------------------------------------------------------------
8663 l_debug_info := 'Insufficient info for invoice line number: '||
8664 t_inv_lines_table(i).line_number;
8665 Print_Debug(l_debug_loc, l_debug_info);
8666 ----------------------------------------------------------------
8667 END IF; -- end of sufficient data check
8668 END IF; -- end of line_type_lookup_code check
8669 END IF; -- end of generate_dists check
8670
8671 IF (t_inv_lines_table(i).line_type_lookup_code IN ('ITEM', 'RETAINAGE RELEASE')) THEN
8672
8673 l_recouped_amount := AP_MATCHING_UTILS_PKG.Get_Inv_Line_Recouped_Amount
8674 (P_Invoice_Id => t_inv_lines_table(i).invoice_id,
8675 P_Invoice_Line_Number => t_inv_lines_table(i).line_number);
8676
8677 IF l_recouped_amount <> 0 THEN
8678 IF (ap_invoice_lines_utility_pkg.get_approval_status
8679 ( p_invoice_id => t_inv_lines_table(i).invoice_id
8680 ,p_line_number => t_inv_lines_table(i).line_number) = 'NEVER APPROVED') THEN
8681
8682 ----------------------------------------------------------------
8683 l_debug_info := 'Adjust Amount Paid if unapproved lines with recouped prepayments exist';
8684 Print_Debug(l_debug_loc, l_debug_info);
8685 ----------------------------------------------------------------
8686
8687 --bugfix:5609186 removed the l_recouped_amount from the pay_curr_invoice_amount
8688 --as pay_curr_invoice_amount has nothing to do with recouped amount. Recoupment
8689 --should effect only amount_paid on the invoice.
8690 update ap_invoices_all
8691 set amount_paid = nvl(amount_paid,0) + abs(l_recouped_amount)
8692 ,pay_curr_invoice_amount = ap_utilities_pkg.ap_round_currency
8693 (pay_curr_invoice_amount * payment_cross_rate,
8694 payment_currency_code)
8695 where invoice_id = t_inv_lines_table(i).invoice_id;
8696 END IF;
8697 END IF;
8698 END IF;
8699
8700 ----------------------------------------------------------------
8701 l_debug_info := 'Update Invoice Distributions to SELECTED';
8702 Print_Debug(l_debug_loc, l_debug_info);
8703 ----------------------------------------------------------------
8704 -- Perf 6759699
8705 -- All the reamining values for the p_run_option is handeled before
8706 -- the loop. If the line number is passed then it will use proper index.This will
8707 -- work only when the p_run_option is 'NEW'
8708 if ( p_run_option = 'NEW' ) then --6759699
8709
8710 Update_Inv_Dists_To_Selected(
8711 t_inv_lines_table(i).invoice_id,
8712 t_inv_lines_table(i).line_number,
8713 p_run_option,
8714 l_curr_calling_sequence);
8715 end if; -- p_run_option
8716 -----------------------------------------------------------------
8717 Print_Debug(l_debug_loc, 'Line Type : '|| t_inv_lines_table(i).line_type_lookup_code );
8718 Print_Debug(l_debug_loc, 'Match Type: '|| t_inv_lines_table(i).match_type );
8719 -----------------------------------------------------------------
8720
8721 IF ( t_inv_lines_table(i).line_type_lookup_code = 'ITEM' AND
8722 t_inv_lines_table(i).match_type in ('ITEM_TO_PO',
8723 'ITEM_TO_RECEIPT',
8724 'PRICE_CORRECTION',
8725 'QTY_CORRECTION',
8726 'ITEM_TO_SERVICE_PO',
8727 'ITEM_TO_SERVICE_RECEIPT',
8728 'AMOUNT_CORRECTION',
8729 'PO_PRICE_ADJUSTMENT' ) ) THEN
8730
8731 ----------------------------------------------------------------
8732 l_debug_info := 'Calculate Exchange Rate and Invoice Price Variance';
8733 Print_Debug(l_debug_loc, l_debug_info);
8734 ----------------------------------------------------------------
8735
8736 AP_APPROVAL_MATCHED_PKG.Exec_Matched_Variance_Checks(
8737 p_invoice_id => t_inv_lines_table(i).invoice_id,
8738 p_inv_line_number => t_inv_lines_table(i).line_number,
8739 p_base_currency_code => p_base_currency_code,
8740 p_inv_currency_code => p_invoice_rec.invoice_currency_code,
8741 p_sys_xrate_gain_ccid => NULL,
8742 p_sys_xrate_loss_ccid => NULL,
8743 p_system_user => l_system_user,
8744 p_holds => l_holds,
8745 p_hold_count => l_hold_count,
8746 p_release_count => l_release_count,
8747 p_calling_sequence => l_curr_calling_sequence );
8748
8749 END IF;
8750 END IF;
8751 END LOOP;
8752
8753 l_retained_amount := nvl(ap_invoices_utility_pkg.get_retained_total(p_invoice_rec.invoice_id, null),0);
8754
8755 IF l_retained_amount <> 0 THEN
8756
8757 ----------------------------------------------------------------
8758 l_debug_info := 'Adjust Amount Applicable To Discount with Retainage';
8759 Print_Debug(l_debug_loc, l_debug_info);
8760 ----------------------------------------------------------------
8761
8762 update ap_invoices_all
8763 set amount_applicable_to_discount = amount_applicable_to_discount + l_retained_amount
8764 ,pay_curr_invoice_amount = ap_utilities_pkg.ap_round_currency
8765 ((invoice_amount + l_retained_amount) * payment_cross_rate,
8766 payment_currency_code)
8767 where invoice_id = p_invoice_rec.invoice_id
8768 and nvl(net_of_retainage_flag, 'N') <> 'Y';
8769 END IF;
8770
8771 EXCEPTION
8772 WHEN OTHERS THEN
8773 IF (SQLCODE <> -20001) THEN
8774 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
8775 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
8776 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE', l_curr_calling_sequence);
8777 FND_MESSAGE.SET_TOKEN('DEBUG_INFO', l_debug_info);
8778 END IF;
8779 APP_EXCEPTION.RAISE_EXCEPTION;
8780 END Generate_Distributions;
8781
8782 PROCEDURE initialize_invoice_holds
8783 (p_invoice_id IN NUMBER,
8784 p_calling_sequence IN VARCHAR2) IS
8785
8786 Cursor c_invoice_holds (c_invoice_id NUMBER) Is
8787 Select hold_lookup_code,
8788 decode(release_lookup_code, NULL, 'ALREADY ON HOLD',
8789 'RELEASED BY USER') hold_status,
8790 invoice_id,
8791 hold_reason,
8792 release_lookup_code,
8793 line_location_id,
8794 rcv_transaction_id,
8795 last_updated_by,
8796 responsibility_id
8797 From ap_holds
8798 Where invoice_id = c_invoice_id
8799 Order By 1, 2 DESC;
8800
8801 j NUMBER := 1;
8802
8803 l_debug_info VARCHAR2(100);
8804 l_current_calling_sequence VARCHAR2(2000);
8805
8806 BEGIN
8807
8808 -- Update the calling sequence
8809 --
8810 l_current_calling_sequence := 'initialize_invoice_holds<-'||p_calling_sequence;
8811
8812 g_holds_tab.delete;
8813
8814 OPEN c_invoice_holds (p_invoice_id);
8815 LOOP
8816 FETCH c_invoice_holds
8817 INTO g_holds_tab(j);
8818 EXIT WHEN c_invoice_holds%notfound;
8819 j:=j+1;
8820 END LOOP;
8821 CLOSE c_invoice_holds;
8822
8823 EXCEPTION
8824 WHEN OTHERS then
8825 if (SQLCODE <> -20001 ) then
8826 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
8827 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
8828 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',l_current_calling_sequence);
8829 FND_MESSAGE.SET_TOKEN('PARAMETERS','Invoice_id = '||TO_CHAR(p_invoice_id));
8830 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
8831 end if;
8832
8833 APP_EXCEPTION.RAISE_EXCEPTION;
8834
8835 END initialize_invoice_holds;
8836
8837 Procedure Count_Org_Hold(
8838 p_org_id IN NUMBER,
8839 p_hold_lookup_code IN VARCHAR2,
8840 p_place_or_release IN VARCHAR2,
8841 p_calling_sequence IN VARCHAR2) IS
8842
8843 l_array_set VARCHAR2(1);
8844 l_array_count NUMBER;
8845
8846 l_debug_info VARCHAR2(100);
8847 l_current_calling_sequence VARCHAR2(2000);
8848
8849 Begin
8850
8851 -- Update the calling sequence
8852 --
8853 l_current_calling_sequence := 'count_org_hold<-'||p_calling_sequence;
8854
8855 l_array_set := 'N';
8856 l_array_count := g_org_holds.count;
8857
8858 l_debug_info := 'Update Org Hold Count';
8859
8860 if l_array_count > 0 then
8861
8862 for i in g_org_holds.first..g_org_holds.last loop
8863 if g_org_holds(i).org_id = p_org_id
8864 and g_org_holds(i).hold_lookup_code = p_hold_lookup_code then
8865 if p_place_or_release = 'P' then
8866 g_org_holds(i).holds_placed := g_org_holds(i).holds_placed + 1;
8867 l_array_set := 'Y';
8868 exit;
8869 elsif p_place_or_release = 'R' then
8870 g_org_holds(i).holds_released := g_org_holds(i).holds_released + 1;
8871 l_array_set := 'Y';
8872 exit;
8873 end if;
8874 end if;
8875 end loop;
8876
8877 end if;
8878
8879
8880 if l_array_set = 'N' then
8881
8882 l_debug_info := 'Set Org Hold Count';
8883
8884 if l_array_count = 0 then
8885 l_array_count := 1;
8886 else
8887 l_array_count := l_array_count + 1; --bug6370503
8888 end if;
8889
8890 if p_place_or_release = 'P' then
8891 g_org_holds(l_array_count).org_id := p_org_id;
8892 g_org_holds(l_array_count).hold_lookup_code := p_hold_lookup_code;
8893 g_org_holds(l_array_count).holds_placed := 1;
8894 g_org_holds(l_array_count).holds_released := 0;
8895 elsif p_place_or_release = 'R' then
8896 g_org_holds(l_array_count).org_id := p_org_id;
8897 g_org_holds(l_array_count).hold_lookup_code := p_hold_lookup_code;
8898 g_org_holds(l_array_count).holds_placed := 0;
8899 g_org_holds(l_array_count).holds_released := 1;
8900 end if;
8901 end if;
8902
8903 EXCEPTION
8904 WHEN OTHERS then
8905 if (SQLCODE <> -20001 ) then
8906 FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
8907 FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
8908 FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',l_current_calling_sequence);
8909 FND_MESSAGE.SET_TOKEN('PARAMETERS','Org_Id = '||to_char(p_org_id)
8910 ||' Hold = '||p_hold_lookup_code
8911 ||' Action = '||p_place_or_release);
8912 FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
8913 end if;
8914
8915 APP_EXCEPTION.RAISE_EXCEPTION;
8916 End Count_Org_Hold;
8917
8918 Procedure Print_Debug(
8919 p_api_name IN VARCHAR2,
8920 p_debug_info IN VARCHAR2) IS
8921 BEGIN
8922
8923 IF g_debug_mode = 'Y' THEN
8924
8925 AP_Debug_Pkg.Print(g_debug_mode, p_debug_info );
8926
8927 END IF;
8928
8929 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
8930 FND_LOG.STRING(G_LEVEL_STATEMENT,G_MODULE_NAME||p_api_name,p_debug_info);
8931 END IF;
8932 END Print_Debug;
8933
8934 /*=============================================================================
8935 | FUNCTION - get_adjusted_base_amount()
8936 |
8937 | DESCRIPTION
8938 | This function returns base amount after rouding.
8939 | Also calculates the rounding amount for the next line
8940 | For ex: before adjustment after adjustment
8941 | ---------------------------|----------------------------------------------
8942 | p_base_amount | 0.1 0 (since adjustment goes to -ve)
8943 | p_rounding_amt | -0.2 -0.1 (this much amount is adjusted)
8944 | p_next_line_rounding_amt| -0.1 (remaing amount..forward it to next line)
8945 |
8946 |
8947 | PARAMETERS
8948 | p_base_amount - entered base amount
8949 | p_rounding_amt - rounding amount for the base amount
8950 | p_next_line_rounding_amt - rounding amount calculate for the next line/distribution
8951 |
8952 | MODIFICATION HISTORY
8953 | DATE Author Action
8954 | 19-MAY-2008 KPASIKAN Created for the bug 6892789
8955 |
8956 *============================================================================*/
8957 FUNCTION get_adjusted_base_amount(p_base_amount IN NUMBER,
8958 p_rounding_amt OUT NOCOPY NUMBER,
8959 p_next_line_rounding_amt IN OUT NOCOPY NUMBER)
8960 RETURN NUMBER IS
8961 l_adjusted_base_amount NUMBER := 0;
8962 l_base_amount NUMBER := p_base_amount;
8963 l_next_line_rounding_amt NUMBER := p_next_line_rounding_amt;
8964 BEGIN
8965 l_adjusted_base_amount := l_base_amount + l_next_line_rounding_amt;
8966
8967 -- if adjusted base amount goes to -ve
8968 IF (l_base_amount > 0 AND l_adjusted_base_amount < 0)
8969 OR (l_base_amount < 0 AND l_adjusted_base_amount > 0) THEN
8970 -- rounding maount for the next line/dist
8971 p_next_line_rounding_amt := l_adjusted_base_amount;
8972
8973 -- rounding amt for the line/dist
8974 p_rounding_amt := -l_base_amount;
8975
8976 -- base amount will be adjusted to zero
8977 RETURN 0;
8978 ELSE
8979 -- rounding amt for the line/dist
8980 p_rounding_amt := l_next_line_rounding_amt;
8981
8982 -- no need to adjust next line/dist
8983 p_next_line_rounding_amt := 0;
8984
8985 -- base amount
8986 RETURN l_adjusted_base_amount;
8987 END IF;
8988 END;
8989
8990 END AP_APPROVAL_PKG;