[Home] [Help]
PACKAGE BODY: APPS.PO_RCO_VALIDATION_PVT
Source
1 PACKAGE BODY po_rco_validation_pvt AS
2 /* $Header: POXVRCVB.pls 120.39.12020000.6 2013/05/21 09:29:36 bpulivar ship $ */
3 --g_pkg_name CONSTANT VARCHAR2(30) := 'PO_RCO_VALIDATION_PVT';
4 -- Read the profile option that enables/disables the debug log
5 -- Logging global constants
6 d_package_base CONSTANT VARCHAR2(100) := po_log.get_package_base(g_pkg_name);
7
8 c_log_head CONSTANT VARCHAR2(50) := 'po.plsql.' || g_pkg_name || '.';
9
10 -- Debugging
11 g_debug_stmt CONSTANT BOOLEAN := po_debug.is_debug_stmt_on;
12 g_debug_unexp CONSTANT BOOLEAN := po_debug.is_debug_unexp_on;
13
14 g_module_prefix CONSTANT VARCHAR2(50) := 'po.plsql.' || g_pkg_name || '.';
15 g_fnd_debug VARCHAR2(1) := nvl(fnd_profile.value('AFLOG_ENABLED'), 'N');
16
17
18 -- Initializing Private Functions/Procedures
19 TYPE number_tbl IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
20
21 PROCEDURE Insert_PriceBreakRows(p_chn_grp_id IN NUMBER);
22
23 PROCEDURE Insert_LineQuantityOrAmount(p_chn_grp_id IN NUMBER);
24
25 PROCEDURE Validate_Quantity(p_header_id IN NUMBER,
26 p_release_id IN NUMBER,
27 p_po_change_table IN pos_chg_rec_tbl,
28 p_errortable IN OUT NOCOPY po_req_change_err_table,
29 p_error_index IN OUT NOCOPY NUMBER,
30 x_return_status OUT NOCOPY VARCHAR2,
31 x_return_msg OUT NOCOPY VARCHAR2);
32
33 PROCEDURE Decode_poerror(p_header_id IN NUMBER,
34 p_release_id IN NUMBER,
35 p_err_po_msg IN VARCHAR2,
36 p_doc_check_rec_type IN doc_check_return_type,
37 p_po_error_index IN NUMBER,
38 p_errortable IN OUT NOCOPY po_req_change_err_table,
39 p_error_index IN OUT NOCOPY NUMBER,
40 x_return_status OUT NOCOPY VARCHAR2,
41 x_return_msg OUT NOCOPY VARCHAR2);
42
43 PROCEDURE insert_reqchange(p_change_table change_tbl_type,
44 p_chn_req_grp_id NUMBER);
45
46 FUNCTION calculate_newunitprice(p_req_line_id NUMBER, p_new_price NUMBER) RETURN NUMBER;
47
48 PROCEDURE validate_changes(p_req_hdr_id IN NUMBER,
49 p_req_change_table IN OUT NOCOPY change_tbl_type,
50 x_return_status OUT NOCOPY VARCHAR2,
51 x_retmsg OUT NOCOPY VARCHAR,
52 p_errortable IN OUT NOCOPY po_req_change_err_table);
53
54
55 PROCEDURE update_recordswithtax(p_chn_req_grp_id NUMBER);
56
57 PROCEDURE update_internalrecordswithtax(p_chn_req_grp_id NUMBER);
58
59 PROCEDURE copy_change(p_header_id NUMBER,
60 p_release_id NUMBER,
61 p_req_hdr_id NUMBER,
62 req_change_record_tbl IN OUT NOCOPY change_tbl_type,
63 req_index IN NUMBER,
64 po_index IN NUMBER,
65 po_change_record_tbl IN OUT NOCOPY pos_chg_rec_tbl);
66
67 PROCEDURE insert_pricebreakrows(p_chn_grp_id IN NUMBER)
68 IS
69 l_api_name VARCHAR2(50) := 'Insert_PriceBreakRows';
70 l_progress VARCHAR2(5) := '000';
71
72 -- added for retroactive pricing checks
73 l_retropricing VARCHAR2(20) := '';
74 l_quantity_received NUMBER;
75 l_accrue_on_receipt_flag po_line_locations_all.accrue_on_receipt_flag%TYPE;
76 l_quantity_billed NUMBER;
77 l_call_price_break BOOLEAN := TRUE;
78
79 l_req_line_id NUMBER;
80 l_old_date DATE;
81 l_new_date DATE;
82 l_old_qty NUMBER;
83 l_new_qty NUMBER;
84 l_new_po_qty NUMBER;
85 l_old_price NUMBER;
86 l_old_curr_price NUMBER;
87 l_req_uom po_requisition_lines_all.unit_meas_lookup_code%TYPE;
88 l_req_user_id NUMBER;
89 l_document_header_id NUMBER;
90 l_document_num po_change_requests.document_num%TYPE;
91 l_document_revision_num NUMBER;
92 l_document_line_number NUMBER;
93 l_requester_id NUMBER;
94
95 l_source_doc_header_id NUMBER;
96 l_source_doc_line_num NUMBER;
97 l_deliver_to_loc_id NUMBER;
98 l_destination_org_id NUMBER;
99 l_req_currency_code po_requisition_lines_all.currency_code%TYPE;
100 l_req_rate_type po_requisition_lines_all.rate_type%TYPE;
101 l_org_id NUMBER;
102 l_creation_date DATE;
103 l_supplier_id NUMBER;
104 l_supplier_site_id NUMBER;
105 l_order_header_id NUMBER;
106 l_order_line_id NUMBER;
107 l_line_type_id NUMBER;
108 l_item_revision po_requisition_lines_all.item_revision%TYPE;
109 l_item_id NUMBER;
110 l_category_id NUMBER;
111 l_supplier_item_num po_requisition_lines_all.supplier_ref_number%TYPE;
112 l_in_price NUMBER;
113
114 -- output values
115 l_new_base_unit_price NUMBER;
116 l_new_price NUMBER;
117 l_new_curr_price NUMBER;
118 l_discount NUMBER;
119 l_currency_code po_requisition_lines_all.currency_code%TYPE;
120 l_rate_type po_requisition_lines_all.rate_type%TYPE;
121 l_rate_date DATE;
122 l_rate NUMBER;
123 l_price_break_id NUMBER;
124
125 CURSOR l_linepricebreak_csr(grp_id NUMBER) IS
126 SELECT
127 DISTINCT
128 pcr.document_header_id,
129 pcr.document_num,
130 pcr.document_revision_num,
131 pcr.document_line_id,
132 pcr.document_line_number,
133 pcr.requester_id
134 FROM po_change_requests pcr,
135 po_requisition_lines_all prla
136 WHERE pcr.change_request_group_id = grp_id
137 AND pcr.action_type = 'MODIFICATION'
138 AND prla.requisition_line_id = pcr.document_line_id
139 AND prla.blanket_po_header_id IS NOT NULL;
140
141 BEGIN
142 l_retropricing := fnd_profile.value('PO_ALLOW_RETROPRICING_OF_PO');
143
144 l_req_user_id := fnd_global.user_id;
145
146 OPEN l_linepricebreak_csr(p_chn_grp_id);
147 LOOP
148 FETCH l_linepricebreak_csr
149 INTO
150 l_document_header_id,
151 l_document_num,
152 l_document_revision_num,
153 l_req_line_id,
154 l_document_line_number,
155 l_requester_id;
156
157 EXIT WHEN l_linepricebreak_csr%notfound;
158 l_progress := '001';
159
160 SELECT
161 prla.need_by_date,
162 prla.unit_meas_lookup_code,
163 prla.unit_price,
164 prla.currency_unit_price,
165 prla.blanket_po_header_id,
166 prla.blanket_po_line_num,
167 prla.deliver_to_location_id,
168 prla.destination_organization_id,
169 prla.currency_code,
170 prla.rate_type,
171 prla.org_id,
172 prla.vendor_id,
173 prla.vendor_site_id,
174 prla.creation_date,
175 plla.po_header_id,
176 plla.po_line_id,
177 prla.line_type_id,
178 prla.item_revision,
179 prla.item_id,
180 prla.category_id,
181 prla.supplier_ref_number,
182 prla.unit_price,
183 nvl(plla.quantity_received, 0),
184 nvl(plla.accrue_on_receipt_flag, 'N'),
185 nvl(plla.quantity_billed, 0)
186 INTO
187 l_old_date,
188 l_req_uom,
189 l_old_price,
190 l_old_curr_price,
191 l_source_doc_header_id,
192 l_source_doc_line_num,
193 l_deliver_to_loc_id,
194 l_destination_org_id,
195 l_req_currency_code,
196 l_req_rate_type,
197 l_org_id,
198 l_supplier_id,
199 l_supplier_site_id,
200 l_creation_date,
201 l_order_header_id,
202 l_order_line_id,
203 l_line_type_id,
204 l_item_revision,
205 l_item_id,
206 l_category_id,
207 l_supplier_item_num,
208 l_in_price,
209 l_quantity_received,
210 l_accrue_on_receipt_flag,
211 l_quantity_billed
212 FROM
213 po_requisition_lines_all prla,
214 po_line_locations_all plla
215 WHERE prla.requisition_line_id = l_req_line_id
216 AND prla.line_location_id = plla.line_location_id;
217
218 BEGIN
219 SELECT new_need_by_date
220 INTO l_new_date
221 FROM po_change_requests
222 WHERE new_need_by_date IS NOT NULL
223 AND change_request_group_id = p_chn_grp_id
224 AND document_line_id = l_req_line_id;
225 EXCEPTION WHEN OTHERS THEN
226 l_new_date := l_old_date;
227 END;
228
229 l_progress := '002';
230
231 SELECT nvl(SUM(new_quantity), 0)
232 INTO l_new_qty
233 FROM po_change_requests
234 WHERE new_quantity IS NOT NULL
235 AND change_request_group_id = p_chn_grp_id
236 AND document_line_id = l_req_line_id
237 AND action_type = 'MODIFICATION'
238 AND request_level = 'DISTRIBUTION';
239
240 SELECT nvl(SUM(req_line_quantity), 0)
241 INTO l_old_qty
242 FROM po_req_distributions_all
243 WHERE requisition_line_id = l_req_line_id
244 AND distribution_id NOT IN(SELECT document_distribution_id
245 FROM po_change_requests
246 WHERE new_quantity IS NOT NULL
247 AND change_request_group_id = p_chn_grp_id
248 AND document_line_id = l_req_line_id
249 AND action_type = 'MODIFICATION'
250 AND request_level = 'DISTRIBUTION');
251
252 l_new_qty := l_new_qty + l_old_qty;
253
254 l_progress := '003';
255
256 IF (l_retropricing = 'ALL_RELEASES') THEN
257 l_call_price_break := TRUE;
258 ELSE
259 IF ((l_quantity_received > 0 AND
260 l_accrue_on_receipt_flag = 'Y') OR
261 (l_quantity_billed > 0)) THEN
262 l_call_price_break := FALSE;
263 END IF;
264 END IF;
265
266
267 IF (l_call_price_break) THEN
268
269 po_price_break_grp.get_price_break (
270 p_source_document_header_id => l_source_doc_header_id,
271 p_source_document_line_num => l_source_doc_line_num,
272 p_in_quantity => l_new_qty,
273 p_unit_of_measure => l_req_uom,
274 p_deliver_to_location_id => l_deliver_to_loc_id,
275 p_required_currency => l_req_currency_code,
276 p_required_rate_type => l_req_rate_type,
277 p_need_by_date => l_new_date,
278 p_destination_org_id => l_destination_org_id,
279 p_org_id => l_org_id,
280 p_supplier_id => l_supplier_id,
281 p_supplier_site_id => l_supplier_site_id,
282 p_creation_date => l_creation_date,
283 p_order_header_id => l_order_header_id,
284 p_order_line_id => l_order_line_id,
285 p_line_type_id => l_line_type_id,
286 p_item_revision => l_item_revision,
287 p_item_id => l_item_id,
288 p_category_id => l_category_id,
289 p_supplier_item_num => l_supplier_item_num,
290 p_in_price => l_in_price,
291 --Below is OUTPUT
292 x_base_unit_price => l_new_base_unit_price,
293 x_base_price => l_new_price,
294 x_currency_price => l_new_curr_price,
295 x_discount => l_discount,
296 x_currency_code => l_currency_code,
297 x_rate_type => l_rate_type,
298 x_rate_date => l_rate_date,
299 x_rate => l_rate,
300 x_price_break_id => l_price_break_id);
301
302 IF (g_fnd_debug = 'Y') THEN
303 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
304 fnd_log.string(fnd_log.level_statement, g_module_prefix ||
305 l_api_name, 'New Base Unit Price:' || to_char(l_new_base_unit_price) || ' New Price:' || to_char(l_new_price) || ' New Cur Unit Price:' || to_char(l_new_curr_price));
306 END IF;
307 END IF;
308
309 IF(l_new_price <> l_old_price) THEN
310 l_progress := '004';
311 IF(l_old_curr_price IS NULL) THEN
312 l_new_curr_price := NULL;
313 END IF;
314 INSERT INTO po_change_requests
315 (
316 change_request_group_id,
317 change_request_id,
318 initiator,
319 action_type,
320 request_level,
321 request_status,
322 document_type,
323 document_header_id,
324 document_num,
325 document_revision_num,
326 created_by,
327 creation_date,
328 document_line_id,
329 document_line_number,
330 old_price,
331 new_price,
332 old_currency_unit_price,
333 new_currency_unit_price,
334 last_updated_by,
335 last_update_date,
336 last_update_login,
337 requester_id,
338 change_active_flag)
339 VALUES
340 (
341 p_chn_grp_id,
342 po_chg_request_seq.nextval,
343 'REQUESTER',
344 'DERIVED',
345 'LINE',
346 'SYSTEMSAVE',
347 'REQ',
348 l_document_header_id,
349 l_document_num,
350 l_document_revision_num,
351 l_req_user_id,
352 SYSDATE,
353 l_req_line_id,
354 l_document_line_number,
355 l_old_price,
356 l_new_price,
357 l_old_curr_price,
358 l_new_curr_price,
359 l_req_user_id,
360 SYSDATE,
361 l_req_user_id,
362 l_requester_id,
363 'Y'
364 );
365
366 END IF;
367
368 END IF; -- if for l_call_price_break check
369
370 END LOOP;
371 CLOSE l_linepricebreak_csr;
372
373 EXCEPTION WHEN OTHERS THEN
374 IF g_fnd_debug = 'Y' THEN
375 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
376 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
377 l_api_name || '.others_exception', l_progress || ':' || SQLERRM);
378 END IF;
379 END IF;
380 RAISE;
381
382 END insert_pricebreakrows;
383
384
385 -- Inserts Derived Row for Line level Quantity or Amount changes
386
387 PROCEDURE insert_linequantityoramount(p_chn_grp_id IN NUMBER)
388 IS
389 l_api_name VARCHAR2(50) := 'Insert_LineQuantityOrAmount';
390 l_progress VARCHAR2(5) := '000';
391 l_line_id NUMBER;
392 l_line_num NUMBER;
393 l_id NUMBER;
394 l_old_quantity NUMBER;
395 l_new_quantity NUMBER;
396 l_req_user_id NUMBER;
397 l_req_header_id NUMBER;
398 l_req_num po_requisition_headers_all.segment1%TYPE;
399 l_requester_id NUMBER;
400 l_matching_basis po_requisition_lines_all.matching_basis%TYPE;
401 l_old_amount NUMBER;
402 l_new_amount NUMBER;
403 l_old_cur_amount NUMBER;
404 l_new_cur_amount NUMBER;
405
406 CURSOR l_line_csr(grp_id NUMBER) IS
407 SELECT DISTINCT
408 document_header_id,
409 document_num,
410 document_line_id,
411 document_line_number,
412 requester_id
413 FROM po_change_requests
414 WHERE action_type = 'MODIFICATION'
415 AND change_request_group_id = grp_id;
416
417 CURSOR l_line_qty_chn_csr(line_id NUMBER, grp_id NUMBER) IS
418 SELECT change_request_id
419 FROM po_change_requests
420 WHERE document_line_id = line_id
421 AND change_request_group_id = grp_id
422 AND new_quantity IS NOT NULL
423 AND request_level = 'DISTRIBUTION';
424
425 CURSOR l_line_amt_chn_csr(line_id NUMBER, grp_id NUMBER) IS
426 SELECT change_request_id
427 FROM po_change_requests
428 WHERE document_line_id = line_id
429 AND change_request_group_id = grp_id
430 AND new_amount IS NOT NULL
431 AND request_level = 'DISTRIBUTION';
432
433 BEGIN
434 l_req_user_id := fnd_global.user_id;
435
436 OPEN l_line_csr(p_chn_grp_id);
437 LOOP
438 FETCH l_line_csr INTO
439 l_req_header_id,
440 l_req_num,
441 l_line_id,
442 l_line_num,
443 l_requester_id;
444 EXIT WHEN l_line_csr%notfound;
445 l_progress := '001';
446
447 SELECT matching_basis, quantity, amount, currency_amount
448 INTO l_matching_basis, l_old_quantity, l_old_amount, l_old_cur_amount
449 FROM po_requisition_lines_all
450 WHERE requisition_line_id = l_line_id;
451
452 -- handle amount based lines
453 IF (l_matching_basis = 'AMOUNT') THEN
454 OPEN l_line_amt_chn_csr(l_line_id, p_chn_grp_id);
455 FETCH l_line_amt_chn_csr INTO l_id;
456 CLOSE l_line_amt_chn_csr;
457
458 l_progress := '002';
459
460 IF(l_id > 0) THEN
461
462 l_progress := '003';
463 SELECT SUM(amount)
464 INTO l_new_amount
465 FROM (
466 SELECT new_amount amount
467 FROM po_change_requests
468 WHERE change_request_group_id = p_chn_grp_id
469 AND document_line_id = l_line_id
470 AND new_amount IS NOT NULL
471 AND request_level = 'DISTRIBUTION'
472 UNION ALL
473 SELECT req_line_amount amount
474 FROM po_req_distributions_all
475 WHERE requisition_line_id = l_line_id
476 AND distribution_id NOT IN
477 (SELECT document_distribution_id
478 FROM po_change_requests
479 WHERE change_request_group_id = p_chn_grp_id
480 AND document_line_id = l_line_id
481 AND new_amount IS NOT NULL
482 AND request_level = 'DISTRIBUTION')
483 );
484
485 SELECT SUM(amount)
486 INTO l_new_cur_amount
487 FROM (
488 SELECT new_currency_amount amount
489 FROM po_change_requests
490 WHERE change_request_group_id = p_chn_grp_id
491 AND document_line_id = l_line_id
492 AND new_currency_amount IS NOT NULL
493 AND request_level = 'DISTRIBUTION'
494 UNION ALL
495 SELECT req_line_currency_amount amount
496 FROM po_req_distributions_all
497 WHERE requisition_line_id = l_line_id
498 AND distribution_id NOT IN
499 (SELECT document_distribution_id
500 FROM po_change_requests
501 WHERE change_request_group_id = p_chn_grp_id
502 AND document_line_id = l_line_id
503 AND new_currency_amount IS NOT NULL
504 AND request_level = 'DISTRIBUTION')
505 );
506
507 ELSE
508 l_new_amount := NULL;
509 l_new_cur_amount := NULL;
510 END IF;
511
512
513
514 ELSE -- handle quantity based lines
515 OPEN l_line_qty_chn_csr(l_line_id, p_chn_grp_id);
516 FETCH l_line_qty_chn_csr INTO l_id;
517 CLOSE l_line_qty_chn_csr;
518
519 l_progress := '002';
520
521 IF(l_id > 0) THEN
522
523 l_progress := '003';
524 SELECT SUM(quantity)
525 INTO l_new_quantity
526 FROM (
527 SELECT new_quantity quantity
528 FROM po_change_requests
529 WHERE change_request_group_id = p_chn_grp_id
530 AND document_line_id = l_line_id
531 AND new_quantity IS NOT NULL
532 AND request_level = 'DISTRIBUTION'
533 UNION ALL
534 SELECT req_line_quantity quantity
535 FROM po_req_distributions_all
536 WHERE requisition_line_id = l_line_id
537 AND distribution_id NOT IN
538 (SELECT document_distribution_id
539 FROM po_change_requests
540 WHERE change_request_group_id = p_chn_grp_id
541 AND document_line_id = l_line_id
542 AND new_quantity IS NOT NULL
543 AND request_level = 'DISTRIBUTION')
544 );
545 ELSE
546 l_new_quantity := NULL;
547 END IF;
548
549 END IF;
550
551 l_progress := '004';
552
553 INSERT INTO po_change_requests
554 (
555 change_request_group_id,
556 change_request_id,
557 initiator,
558 action_type,
559 request_level,
560 request_status,
561 document_type,
562 document_header_id,
563 document_num,
564 created_by,
565 creation_date,
566 document_line_id,
567 document_line_number,
568 old_quantity,
569 new_quantity,
570 old_amount,
571 new_amount,
572 old_currency_amount,
573 new_currency_amount,
574 last_updated_by,
575 last_update_date,
576 last_update_login,
577 requester_id,
578 change_active_flag)
579 VALUES
580 (
581 p_chn_grp_id,
582 po_chg_request_seq.nextval,
583 'REQUESTER',
584 'DERIVED',
585 'LINE',
586 'SYSTEMSAVE',
587 'REQ',
588 l_req_header_id,
589 l_req_num,
590 l_req_user_id,
591 SYSDATE,
592 l_line_id,
593 l_line_num,
594 l_old_quantity,
595 l_new_quantity,
596 l_old_amount,
597 l_new_amount,
598 l_old_cur_amount,
599 l_new_cur_amount,
600 l_req_user_id,
601 SYSDATE,
602 l_req_user_id,
603 l_requester_id,
604 'Y'
605 );
606
607 END LOOP;
608 CLOSE l_line_csr;
609 EXCEPTION WHEN OTHERS THEN
610 IF g_fnd_debug = 'Y' THEN
611 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
612 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
613 l_api_name || '.others_exception', l_progress || ':' || SQLERRM);
614 END IF;
615 END IF;
616 RAISE;
617
618 END insert_linequantityoramount;
619
620 PROCEDURE validate_quantity(p_header_id IN NUMBER,
621 p_release_id IN NUMBER,
622 p_po_change_table IN pos_chg_rec_tbl,
623 p_errortable IN OUT NOCOPY po_req_change_err_table,
624 p_error_index IN OUT NOCOPY NUMBER,
625 x_return_status OUT NOCOPY VARCHAR2,
626 x_return_msg OUT NOCOPY VARCHAR2)
627 IS
628 l_api_name VARCHAR2(50) := 'Validate_quantity';
629 l_err_req_line_id NUMBER;
630 l_err_req_dist_id NUMBER;
631 l_err_req_line_num NUMBER;
632 l_err_req_dist_num NUMBER;
633 l_err_po_msg VARCHAR2(2000);
634 l_err_billed_qty NUMBER;
635 l_err_new_qty NUMBER;
636 l_err_delivered_qty NUMBER;
637 l_qty_old_rec NUMBER;
638 l_qty_old_del NUMBER;
639 l_qty_old_bill NUMBER;
640 l_qty_new_rec NUMBER;
641 BEGIN
642 x_return_msg := 'VQ001';
643
644 FOR s IN 1..p_po_change_table.count
645 LOOP
646
647 IF(p_po_change_table(s).new_quantity IS NOT NULL) THEN
648
649 x_return_msg := 'VQ002';
650 /* SELECT
651 quantity_delivered,
652 quantity_billed
653 INTO
654 l_qty_old_del,
655 l_qty_old_bill
656 FROM po_distributions_all
657 WHERE po_distribution_id = p_po_change_table(s).document_distribution_id;
658 */
659 -- Code commented and new code added for bug 7138977
660 select
661 dist.quantity_delivered * Decode(line.ORDER_TYPE_LOOKUP_CODE,'AMOUNT', Nvl(dist.rate,1),1), dist.quantity_billed * Decode(line.ORDER_TYPE_LOOKUP_CODE,'AMOUNT', Nvl(dist.rate,1),1)
662 into
663 l_qty_old_del,
664 l_qty_old_bill
665 from po_distributions_all dist, po_lines_all line
666 where dist.po_line_id = line.po_line_id AND
667 dist.po_distribution_id = p_po_change_table(s).document_distribution_id;
668
669 IF (g_fnd_debug = 'Y') THEN
670 IF ( FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) THEN
671 FND_LOG.string(FND_LOG.level_statement, g_module_prefix ||
672 l_api_name, 'quantity_delivered : '||l_qty_old_del||', quantity_billed : '||l_qty_old_bill||', new_qty : '||p_po_change_table(s).new_quantity);
673 END IF;
674 END IF;
675
676 IF(l_qty_old_del > p_po_change_table(s).new_quantity OR
677 l_qty_old_bill > p_po_change_table(s).new_quantity) THEN
678
679 x_return_msg := 'VQ003:' || p_release_id || '*' || p_po_change_table(s).document_line_location_id ||
680 '*' || p_po_change_table(s).document_distribution_id;
681 IF(p_release_id IS NULL) THEN
682 SELECT
683 prla.line_num,
684 prda.distribution_num,
685 prla.requisition_line_id,
686 prda.distribution_id
687 INTO
688 l_err_req_line_num,
689 l_err_req_dist_num,
690 l_err_req_line_id,
691 l_err_req_dist_id
692 FROM
693 po_lines_all pla,
694 po_line_locations_all plla,
695 po_distributions_all pda,
696 po_requisition_lines_all prla,
697 po_req_distributions_all prda
698 WHERE
699 pla.po_header_id = p_header_id
700 AND pla.po_line_id = p_po_change_table(s).document_line_id
701 AND plla.po_line_id = pla.po_line_id
702 AND plla.line_location_id = p_po_change_table(s).document_line_location_id
703 AND pda.line_location_id = plla.line_location_id
704 AND pda.po_distribution_id = p_po_change_table(s).document_distribution_id
705 AND pda.req_distribution_id = prda.distribution_id
706 AND prda.requisition_line_id = prla.requisition_line_id;
707
708 ELSE
709 SELECT
710 prla.line_num,
711 prda.distribution_num,
712 prla.requisition_line_id,
713 prda.distribution_id
714 INTO
715 l_err_req_line_num,
716 l_err_req_dist_num,
717 l_err_req_line_id,
718 l_err_req_dist_id
719 FROM
720 po_line_locations_all plla,
721 po_distributions_all pda,
722 po_requisition_lines_all prla,
723 po_req_distributions_all prda
724 WHERE
725 plla.po_release_id = p_release_id
726 AND plla.line_location_id = p_po_change_table(s).document_line_location_id
727 AND pda.line_location_id = plla.line_location_id
728 AND pda.po_distribution_id = p_po_change_table(s).document_distribution_id
729 AND pda.req_distribution_id = prda.distribution_id
730 AND prda.requisition_line_id = prla.requisition_line_id;
731
732 END IF;
733 x_return_msg := 'VQ0031';
734 p_errortable.msg_data.extend(1);
735 p_errortable.req_line_id.extend(1);
736 p_errortable.req_dist_id.extend(1);
737 p_errortable.msg_count.extend(1);
738 p_errortable.err_attribute.extend(1);
739
740 p_errortable.req_line_id(p_error_index) := l_err_req_line_id;
741 p_errortable.req_dist_id(p_error_index) := l_err_req_dist_id;
742 fnd_message.set_name('PO', 'PO_RCO_NEW_QTY_BELOW_BILL_DEL');
743 fnd_message.set_token('LINE_NUM', l_err_req_line_num);
744 fnd_message.set_token('DIST_NUM', l_err_req_dist_num);
745 p_errortable.msg_data(p_error_index) := fnd_message.get;
746 p_errortable.msg_count(p_error_index) := 1;
747 p_errortable.err_attribute(p_error_index) := 'QUANTITY';
748
749 p_error_index := p_error_index + 1;
750 END IF;
751 x_return_msg := 'VQ004';
752 SELECT plla.quantity_received
753 INTO l_qty_old_rec
754 FROM
755 po_line_locations_all plla,
756 po_distributions_all pda
757 WHERE plla.line_location_id = pda.line_location_id
758 AND pda.po_distribution_id = p_po_change_table(s).document_distribution_id;
759
760 x_return_msg := 'VQ005';
761
762 SELECT SUM(plla.quantity_received) + p_po_change_table(s).new_quantity
763 INTO l_qty_new_rec
764 FROM
765 po_line_locations_all plla,
766 po_distributions_all pda1,
767 po_distributions_all pda2
768 WHERE plla.line_location_id = pda1.line_location_id
769 AND pda1.po_distribution_id <> p_po_change_table(s).document_distribution_id
770 AND pda1.line_location_id = pda2.line_location_id
771 AND pda2.po_distribution_id = p_po_change_table(s).document_distribution_id;
772
773
774
775
776 IF(l_qty_old_rec > l_qty_new_rec) THEN
777 x_return_msg := 'VQ006';
778 IF(p_release_id IS NULL) THEN
779 SELECT
780 prla.line_num,
781 prda.distribution_num,
782 prla.requisition_line_id,
783 prda.distribution_id
784 INTO
785 l_err_req_line_num,
786 l_err_req_dist_num,
787 l_err_req_line_id,
788 l_err_req_dist_id
789 FROM
790 po_lines_all pla,
791 po_line_locations_all plla,
792 po_distributions_all pda,
793 po_requisition_lines_all prla,
794 po_req_distributions_all prda
795 WHERE
796 pla.po_header_id = p_header_id
797 AND pla.po_line_id = p_po_change_table(s).document_line_id
798 AND plla.po_line_id = pla.po_line_id
799 AND plla.line_location_id = p_po_change_table(s).document_line_location_id
800 AND pda.line_location_id = plla.line_location_id
801 AND pda.po_distribution_id = p_po_change_table(s).document_distribution_id
802 AND pda.req_distribution_id = prda.distribution_id
803 AND prda.requisition_line_id = prla.requisition_line_id;
804
805 ELSE
806 SELECT
807 prla.line_num,
808 prda.distribution_num,
809 prla.requisition_line_id,
810 prda.distribution_id
811 INTO
812 l_err_req_line_num,
813 l_err_req_dist_num,
814 l_err_req_line_id,
815 l_err_req_dist_id
816 FROM
817 po_line_locations_all plla,
818 po_distributions_all pda,
819 po_requisition_lines_all prla,
820 po_req_distributions_all prda
821 WHERE
822 plla.po_release_id = p_release_id
823 AND plla.line_location_id = p_po_change_table(s).document_line_location_id
824 AND pda.line_location_id = plla.line_location_id
825 AND pda.po_distribution_id = p_po_change_table(s).document_distribution_id
826 AND pda.req_distribution_id = prda.distribution_id
827 AND prda.requisition_line_id = prla.requisition_line_id;
828
829 END IF;
830 p_errortable.msg_data.extend(1);
831 p_errortable.req_line_id.extend(1);
832 p_errortable.req_dist_id.extend(1);
833 p_errortable.msg_count.extend(1);
834 p_errortable.err_attribute.extend(1);
835
836 p_errortable.req_line_id(p_error_index) := l_err_req_line_id;
837 p_errortable.req_dist_id(p_error_index) := l_err_req_dist_id;
838 fnd_message.set_name('PO', 'PO_RCO_NEW_QTY_BELOW_REC');
839 fnd_message.set_token('LINE_NUM', l_err_req_line_num);
840 fnd_message.set_token('DIST_NUM', l_err_req_dist_num);
841 p_errortable.msg_data(p_error_index) := fnd_message.get;
842 p_errortable.msg_count(p_error_index) := 1;
843 p_errortable.err_attribute(p_error_index) := 'QUANTITY';
844
845 p_error_index := p_error_index + 1;
846
847 END IF;
848 END IF;
849 END LOOP;
850 EXCEPTION WHEN OTHERS THEN
851 IF g_fnd_debug = 'Y' THEN
852 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
853 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
854 l_api_name || '.others_exception', x_return_msg || ':' || SQLERRM);
855 END IF;
856 END IF;
857 RAISE;
858 END validate_quantity;
859
860
861 PROCEDURE decode_poerror(p_header_id IN NUMBER,
862 p_release_id IN NUMBER,
863 p_err_po_msg IN VARCHAR2,
864 p_doc_check_rec_type IN doc_check_return_type,
865 p_po_error_index IN NUMBER,
866 p_errortable IN OUT NOCOPY po_req_change_err_table,
867 p_error_index IN OUT NOCOPY NUMBER,
868 x_return_status OUT NOCOPY VARCHAR2,
869 x_return_msg OUT NOCOPY VARCHAR2)
870 IS
871 l_api_name VARCHAR2(50) := 'decode_POError';
872 l_progress VARCHAR2(5) := '000';
873 l_blanket_num po_headers_all.segment1%TYPE;
874 l_po_num po_headers_all.segment1%TYPE;
875 l_release_num NUMBER;
876 l_type_lookup_code po_headers_all.type_lookup_code%TYPE;
877 l_doc_type VARCHAR2(2000);
878 l_doc_num po_headers_all.segment1%TYPE;
879 l_err_po_line_num NUMBER;
880 l_vdr_cntct_id po_vendor_contacts.vendor_contact_id%TYPE;
881 l_buyer_id po_headers_all.agent_id%TYPE;
882 l_vdr_cntct_name varchar2(25);
883 l_buyer_name po_buyers_v.full_name%TYPE;
884
885 BEGIN
886 x_return_status := fnd_api.g_ret_sts_success;
887
888 l_err_po_line_num := p_doc_check_rec_type.line_num(p_po_error_index);
889
890 IF(p_release_id IS NULL) THEN
891 SELECT
892 segment1,
893 type_lookup_code,
894 vendor_contact_id,
895 agent_id
896 INTO
897 l_po_num,
898 l_type_lookup_code,
899 l_vdr_cntct_id,
900 l_buyer_id
901 FROM po_headers_all
902 WHERE po_header_id = p_header_id;
903
904 IF(l_type_lookup_code = 'STANDARD') THEN
905 l_doc_type := fnd_message.get_string('PO', 'PO_WF_NOTIF_STD_PO');
906 ELSIF(l_type_lookup_code = 'PLANNED') THEN
907 l_doc_type := fnd_message.get_string('PO', 'PO_WF_NOTIF_PLAN_PO');
908 ELSIF(l_type_lookup_code = 'BLANKET') THEN
909 l_doc_type := fnd_message.get_string('PO', 'PO_WF_NOTIF_BLANKET');
910 END IF;
911
912 l_doc_num := l_po_num;
913 ELSE
914 SELECT
915 pha.segment1,
916 pha.vendor_contact_id,
917 pha.agent_id,
918 pra.release_num,
919 pha.type_lookup_code
920 INTO
921 l_blanket_num,
922 l_vdr_cntct_id,
923 l_buyer_id,
924 l_release_num,
925 l_type_lookup_code
926 FROM po_headers_all pha,
927 po_releases_all pra
928 WHERE pra.po_release_id = p_release_id
929 AND pra.po_header_id = pha.po_header_id;
930
931 IF(l_type_lookup_code = 'BLANKET') THEN
932 l_doc_type := fnd_message.get_string('PO', 'PO_WF_NOTIF_BKT_REL');
933 ELSIF(l_type_lookup_code = 'PLANNED') THEN
934 l_doc_type := fnd_message.get_string('PO', 'PO_WF_NOTIF_SCH_REL');
935 END IF;
936
937 l_doc_num := l_blanket_num || '-' || l_release_num;
938 END IF;
939
940 l_progress := '001';
941
942 IF(p_err_po_msg = 'PO_SUB_REL_AMT_GRT_LIMIT_AMT') THEN
943 /*PO_RCO_REL_AMT_EXC_LIMIT:
944 Changes entered cause the amount being released plus the amount release to date to be
945 greater than the amount limit for Release BLANKET_NUM - RELEASE_NUM.*/
946
947
948 p_errortable.msg_data.extend(1);
949 p_errortable.req_line_id.extend(1);
950 p_errortable.req_dist_id.extend(1);
951 p_errortable.msg_count.extend(1);
952 p_errortable.err_attribute.extend(1);
953
954 fnd_message.set_name('PO', 'PO_RCO_REL_AMT_EXC_LIMIT');
955 fnd_message.set_token('BLANKET_NUM', l_blanket_num);
956 fnd_message.set_token('RELEASE_NUM', l_release_num);
957
958 p_errortable.msg_data(p_error_index) := fnd_message.get;
959 p_errortable.msg_count(p_error_index) := 1;
960 p_error_index := p_error_index + 1;
961
962 ELSIF(p_err_po_msg = 'PO_SUB_REL_AMT_LESS_MINREL_AMT') THEN
963 /*PO_RCO_REL_AMT_BELOW_MIN: Changes entered cause the amount being released
964 plus the amount release to date to be less than the Min Release Amount for
965 Release BLANKET_NUM - RELEASE_NUM*/
966
967
968 p_errortable.msg_data.extend(1);
969 p_errortable.req_line_id.extend(1);
970 p_errortable.req_dist_id.extend(1);
971 p_errortable.msg_count.extend(1);
972 p_errortable.err_attribute.extend(1);
973
974 fnd_message.set_name('PO', 'PO_RCO_REL_AMT_BELOW_MIN');
975 fnd_message.set_token('BLANKET_NUM', l_blanket_num);
976 fnd_message.set_token('RELEASE_NUM', l_release_num);
977
978 p_errortable.msg_data(p_error_index) := fnd_message.get;
979 p_errortable.msg_count(p_error_index) := 1;
980 p_error_index := p_error_index + 1;
981
982
983 ELSIF(p_err_po_msg = 'PO_SUB_REL_SHIPAMT_LESS_MINREL') THEN
984 /*PO_RCO_REL_LINE_BELOW_MIN: Changes entered cause release line total to be
985 less than the agreement limit for line LINE_NUM on Release BLANKET_NUM - RELEASE_NUM.*/
986
987
988 p_errortable.msg_data.extend(1);
989 p_errortable.req_line_id.extend(1);
990 p_errortable.req_dist_id.extend(1);
991 p_errortable.msg_count.extend(1);
992 p_errortable.err_attribute.extend(1);
993
994 fnd_message.set_name('PO', 'PO_RCO_REL_LINE_BELOW_MIN');
995 fnd_message.set_token('BLANKET_NUM', l_blanket_num);
996 fnd_message.set_token('RELEASE_NUM', l_release_num);
997 fnd_message.set_token('LINE_NUM', l_err_po_line_num);
998
999 p_errortable.msg_data(p_error_index) := fnd_message.get;
1000 p_errortable.msg_count(p_error_index) := 1;
1001 p_error_index := p_error_index + 1;
1002
1003
1004 ELSIF(p_err_po_msg = 'PO_SUB_REL_RATE_NULL') THEN
1005 /*PO_RCO_REL_NO_EXCH: No exchange rate conversion information is available for
1006 Release BLANKET_NUM - RELEASE_NUM your selected currency.
1007 Please contact your Purchasing department for assistance.*/
1008
1009
1010 p_errortable.msg_data.extend(1);
1011 p_errortable.req_line_id.extend(1);
1012 p_errortable.req_dist_id.extend(1);
1013 p_errortable.msg_count.extend(1);
1014 p_errortable.err_attribute.extend(1);
1015
1016 fnd_message.set_name('PO', 'PO_RCO_REL_NO_EXCH');
1017 fnd_message.set_token('BLANKET_NUM', l_blanket_num);
1018 fnd_message.set_token('RELEASE_NUM', l_release_num);
1019
1020 p_errortable.msg_data(p_error_index) := fnd_message.get;
1021 p_errortable.msg_count(p_error_index) := 1;
1022 p_error_index := p_error_index + 1;
1023
1024
1025 ELSIF(p_err_po_msg = 'PO_SUB_DIST_RATE_NULL') THEN
1026 --PO_RCO_DIST_NO_EXCH: No exchange rate conversion information is available for DOC_TYPE DOC_NUM line LINE_NUM for your selected currency. Please contact your Purchasing department for assistance.
1027
1028
1029 p_errortable.msg_data.extend(1);
1030 p_errortable.req_line_id.extend(1);
1031 p_errortable.req_dist_id.extend(1);
1032 p_errortable.msg_count.extend(1);
1033 p_errortable.err_attribute.extend(1);
1034
1035 fnd_message.set_name('PO', 'PO_RCO_DIST_NO_EXCH');
1036 fnd_message.set_token('DOC_TYPE', l_doc_type);
1037 fnd_message.set_token('DOC_NUM', l_doc_num);
1038 fnd_message.set_token('LINE_NUM', l_err_po_line_num);
1039
1040
1041 p_errortable.msg_data(p_error_index) := fnd_message.get;
1042 p_errortable.msg_count(p_error_index) := 1;
1043 p_error_index := p_error_index + 1;
1044
1045
1046 ELSIF(p_err_po_msg = 'PO_SUB_STD_GA_LINE_LESS_MINREL') THEN
1047 /*PO_RCO_STD_LINE_BELOW_MIN: Changes entered cause the line total to be
1048 less than the minimum release amount for line LINE_NUM on Purchase Order PO_NUM.*/
1049
1050
1051 p_errortable.msg_data.extend(1);
1052 p_errortable.req_line_id.extend(1);
1053 p_errortable.req_dist_id.extend(1);
1054 p_errortable.msg_count.extend(1);
1055 p_errortable.err_attribute.extend(1);
1056
1057 fnd_message.set_name('PO', 'PO_RCO_STD_LINE_BELOW_MIN');
1058 fnd_message.set_token('PO_NUM', l_po_num);
1059 fnd_message.set_token('LINE_NUM', l_err_po_line_num);
1060
1061
1062 p_errortable.msg_data(p_error_index) := fnd_message.get;
1063 p_errortable.msg_count(p_error_index) := 1;
1064 p_error_index := p_error_index + 1;
1065
1066
1067 ELSIF(p_err_po_msg = 'PO_SUB_REQ_AMT_TOL_EXCEED') THEN
1068 /*PO_RCO_AMT_EXC_TOL_MIN: Changes entered cause the total amount to
1069 exceed the amount tolerance limit for DOC_TYPE DOC_NUM.*/
1070
1071
1072 p_errortable.msg_data.extend(1);
1073 p_errortable.req_line_id.extend(1);
1074 p_errortable.req_dist_id.extend(1);
1075 p_errortable.msg_count.extend(1);
1076 p_errortable.err_attribute.extend(1);
1077
1078 fnd_message.set_name('PO', 'PO_RCO_AMT_EXC_TOL_MIN');
1079 fnd_message.set_token('DOC_TYPE', l_doc_type);
1080 fnd_message.set_token('DOC_NUM', l_doc_num);
1081
1082
1083 p_errortable.msg_data(p_error_index) := fnd_message.get;
1084 p_errortable.msg_count(p_error_index) := 1;
1085 p_error_index := p_error_index + 1;
1086
1087
1088 ELSIF(p_err_po_msg = 'PO_SUB_REQ_PRICE_TOL_EXCEED') THEN
1089 /*PO_RCO_LINE_PRICE_ECX_TOL: Changes entered cause the line price to
1090 exceed the price tolerance limit for LINE_NUM on DOC_TYPE DOC_NUM.*/
1091
1092
1093 p_errortable.msg_data.extend(1);
1094 p_errortable.req_line_id.extend(1);
1095 p_errortable.req_dist_id.extend(1);
1096 p_errortable.msg_count.extend(1);
1097 p_errortable.err_attribute.extend(1);
1098
1099 fnd_message.set_name('PO', 'PO_RCO_LINE_PRICE_ECX_TOL');
1100 fnd_message.set_token('DOC_TYPE', l_doc_type);
1101 fnd_message.set_token('DOC_NUM', l_doc_num);
1102 fnd_message.set_token('LINE_NUM', l_err_po_line_num);
1103
1104
1105 p_errortable.msg_data(p_error_index) := fnd_message.get;
1106 p_errortable.msg_count(p_error_index) := 1;
1107 p_error_index := p_error_index + 1;
1108
1109
1110
1111 ELSIF(p_err_po_msg = 'PO_SUB_STD_AMT_GRT_GA_AMT_LMT') THEN
1112 /*PO_RCO_STD_AMT_EXC_LIMIT: Changes entered cause the amount being released
1113 plus the amount release to date to be
1114 greater than the amount limit for Purchase Order PO_NUM.*/
1115
1116
1117
1118 p_errortable.msg_data.extend(1);
1119 p_errortable.req_line_id.extend(1);
1120 p_errortable.req_dist_id.extend(1);
1121 p_errortable.msg_count.extend(1);
1122 p_errortable.err_attribute.extend(1);
1123
1124 fnd_message.set_name('PO', 'PO_RCO_STD_AMT_EXC_LIMIT');
1125 fnd_message.set_token('PO_NUM', l_po_num);
1126
1127 p_errortable.msg_data(p_error_index) := fnd_message.get;
1128 p_errortable.msg_count(p_error_index) := 1;
1129 p_error_index := p_error_index + 1;
1130
1131
1132 ELSIF(p_err_po_msg = 'PO_SUB_STD_GA_PRICE_MISMATCH') THEN
1133 /*PO_RCO_STD_PRICE_EXC_TOL: Changes entered cause the line price to
1134 exceed the price override tolerance limit for LINE_NUM on Purchase Order PO_NUM.*/
1135
1136 p_errortable.msg_data.extend(1);
1137 p_errortable.req_line_id.extend(1);
1138 p_errortable.req_dist_id.extend(1);
1139 p_errortable.msg_count.extend(1);
1140 p_errortable.err_attribute.extend(1);
1141
1142 fnd_message.set_name('PO', 'PO_RCO_STD_PRICE_EXC_TOL');
1143 fnd_message.set_token('PO_NUM', l_po_num);
1144 fnd_message.set_token('LINE_NUM', l_err_po_line_num);
1145
1146 p_errortable.msg_data(p_error_index) := fnd_message.get;
1147 p_errortable.msg_count(p_error_index) := 1;
1148 p_error_index := p_error_index + 1;
1149 elsif(p_err_po_msg = 'PO_PDOI_INVALID_VDR_CNTCT') then
1150
1151
1152 SELECT first_name||', '||last_name into l_vdr_cntct_name
1153 FROM po_vendor_contacts
1154 WHERE vendor_contact_id = l_vdr_cntct_id and ROWNUM = 1;
1155
1156 SELECT full_name into l_buyer_name
1157 FROM po_buyers_v
1158 WHERE employee_id = l_buyer_id;
1159
1160 p_errorTable.msg_data.extend(1);
1161 p_errorTable.req_line_id.extend(1);
1162 p_errorTable.req_dist_id.extend(1);
1163 p_errorTable.msg_count.extend(1);
1164 p_errorTable.err_attribute.extend(1);
1165
1166 fnd_message.set_name('PO','PO_RCO_INVALID_VDR_CNTCT');
1167 fnd_message.set_token('NAME',l_vdr_cntct_name);
1168 fnd_message.set_token('PO_NUM',l_po_num);
1169 fnd_message.set_token('BUYER',l_buyer_name);
1170
1171 p_errorTable.msg_data(p_error_index) := fnd_message.get;
1172 p_errorTable.msg_count(p_error_index) := 1;
1173 p_error_index := p_error_index + 1;
1174 END IF;
1175 EXCEPTION
1176 WHEN OTHERS THEN
1177 IF g_fnd_debug = 'Y' THEN
1178 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
1179 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
1180 l_api_name || '.others_exception',
1181 p_header_id || '*' || p_release_id || '*' || p_err_po_msg || ':' || SQLERRM);
1182 END IF;
1183 END IF;
1184 x_return_status := fnd_api.g_ret_sts_unexp_error;
1185 x_return_msg := 'DPE_UNEXP:' || p_header_id || '*' || p_release_id || '*' || p_err_po_msg || '*' || l_progress || ':' || SQLERRM;
1186 END decode_poerror;
1187
1188 /*
1189 *Given a particular ReqLine_id, and a new transactional price, we will return
1190 *the new functionally currency price.
1191 */
1192 FUNCTION calculate_newunitprice(p_req_line_id NUMBER, p_new_price NUMBER) RETURN NUMBER
1193 IS
1194 l_transaction_currency po_requisition_lines_all.currency_code%TYPE;
1195 l_functional_currency gl_sets_of_books.currency_code%TYPE;
1196 l_rate_type po_requisition_lines_all.rate_type%TYPE;
1197 l_conversion_date DATE;
1198 l_rate NUMBER;
1199 l_unit_price NUMBER;
1200 l_denominator NUMBER;
1201 l_numerator NUMBER;
1202 l_set_of_books_id NUMBER;
1203 l_gl_rate NUMBER;
1204
1205 BEGIN
1206
1207 SELECT currency_code
1208 INTO l_transaction_currency
1209 FROM po_requisition_lines_all
1210 WHERE requisition_line_id = p_req_line_id ;
1211
1212 SELECT currency_code, fsp.set_of_books_id
1213 INTO l_functional_currency, l_set_of_books_id
1214 FROM
1215 gl_sets_of_books gsob,
1216 financials_system_parameters fsp
1217 WHERE fsp.set_of_books_id = gsob.set_of_books_id;
1218
1219 IF(l_transaction_currency <> l_functional_currency) THEN
1220 SELECT nvl(rate_type,' ')
1221 INTO l_rate_type
1222 FROM po_requisition_lines_all
1223 WHERE requisition_line_id = p_req_line_id;
1224
1225 IF(l_rate_type <> 'User') THEN
1226 SELECT rate_date
1227 INTO l_conversion_date
1228 FROM po_requisition_lines_all
1229 WHERE requisition_line_id = p_req_line_id;
1230
1231 gl_currency_api.get_triangulation_rate(l_set_of_books_id,
1232 l_transaction_currency,
1233 l_conversion_date,
1234 l_rate_type,
1235 l_denominator,
1236 l_numerator,
1237 l_gl_rate);
1238
1239
1240 l_unit_price :=
1241 (p_new_price / l_denominator) * l_numerator;
1242 ELSE
1243 SELECT rate
1244 INTO l_rate
1245 FROM po_requisition_lines_all
1246 WHERE requisition_line_id = p_req_line_id;
1247
1248 l_unit_price := p_new_price * l_rate;
1249 END IF;
1250 ELSE
1251 l_unit_price := NULL;
1252 END IF;
1253 RETURN l_unit_price;
1254 EXCEPTION WHEN OTHERS THEN
1255 RETURN NULL;
1256 END calculate_newunitprice;
1257
1258 PROCEDURE generate_po_change_table(p_po_change_table IN OUT NOCOPY pos_chg_rec_tbl,
1259 p_progress OUT NOCOPY VARCHAR) IS
1260 l_shipment_index number_tbl;
1261 l_last NUMBER := 1;
1262 i NUMBER := 1;
1263 l_po_change_table_count NUMBER;
1264 l_po_tbl_index NUMBER;
1265 l_ship_quantity NUMBER;
1266 l_ship_to_location_id NUMBER;
1267 l_ship_to_organization_id NUMBER;
1268 l_need_by_date DATE;
1269
1270 BEGIN
1271
1272 l_po_change_table_count := p_po_change_table.count + 1;
1273 p_progress := 'G1' || to_char(l_po_change_table_count);
1274 WHILE (i<l_po_change_table_count) LOOP
1275 p_progress := 'G1' || to_char(l_po_change_table_count) ||' '|| to_char(i);
1276 IF(p_po_change_table(i).request_level = 'SHIPMENT') THEN
1277 l_shipment_index(p_po_change_table(i).document_line_location_id) := i;
1278 END IF;
1279 i := i + 1;
1280 END LOOP;
1281 i := 1;
1282 l_po_tbl_index := l_po_change_table_count;
1283 p_progress := 'G2' || to_char(l_po_change_table_count);
1284 WHILE (i<l_po_change_table_count) LOOP
1285 p_progress := 'G2' || to_char(l_po_change_table_count) ||' '|| to_char(i);
1286 IF(p_po_change_table(i).request_level = 'DISTRIBUTION') THEN
1287 IF(l_shipment_index.exists(p_po_change_table(i).document_line_location_id)) THEN
1288 p_po_change_table(l_shipment_index(p_po_change_table(i).
1289 document_line_location_id)).new_quantity
1290 := nvl(p_po_change_table(l_shipment_index(p_po_change_table(i).
1291 document_line_location_id)).new_quantity,
1292 p_po_change_table(l_shipment_index(p_po_change_table(i).
1293 document_line_location_id)).old_quantity) +
1294 p_po_change_table(i).new_quantity - p_po_change_table(i).old_quantity;
1295 ELSE
1296 p_progress := 'G2' || to_char(l_po_change_table_count) ||' '|| to_char(i) ||' '|| to_char(p_po_change_table(i).document_line_location_id);
1297 p_po_change_table.extend(1);
1298 l_shipment_index(p_po_change_table(i).document_line_location_id) := l_po_tbl_index;
1299 p_progress := 'G2-1' || to_char(l_po_change_table_count) ||' '|| to_char(i) ||' '|| to_char(p_po_change_table(i).document_line_location_id);
1300
1301 SELECT quantity,
1302 ship_to_location_id,
1303 ship_to_organization_id,
1304 need_by_date
1305 INTO l_ship_quantity,
1306 l_ship_to_location_id,
1307 l_ship_to_organization_id,
1308 l_need_by_date
1309 FROM po_line_locations_all
1310 WHERE line_location_id = p_po_change_table(i).document_line_location_id;
1311
1312 p_progress := 'G2-2' || to_char(l_po_change_table_count) ||' '|| to_char(i) ||' '|| to_char(p_po_change_table(i).document_line_location_id);
1313 p_po_change_table(l_po_tbl_index) := po_chg_request_pvt.create_pos_change_rec(
1314 p_action_type => 'MODIFICATION',
1315 p_initiator => 'REQUESTER',
1316 p_document_type => p_po_change_table(i).document_type,
1317 p_request_level => 'SHIPMENT',
1318 p_request_status => 'PENDING',
1319 p_document_header_id => p_po_change_table(i).document_header_id,
1320 p_request_reason => 'aa',
1321 p_po_release_id => p_po_change_table(i).po_release_id,
1322 p_document_num => p_po_change_table(i).document_num,
1323 p_document_revision_num => p_po_change_table(i).document_revision_num,
1324 p_document_line_id => p_po_change_table(i).document_line_id,
1325 p_document_line_number => p_po_change_table(i).document_line_number,
1326 p_document_line_location_id => p_po_change_table(i).document_line_location_id,
1327 p_document_shipment_number => p_po_change_table(i).document_shipment_number,
1328 p_document_distribution_id => NULL,
1329 p_document_distribution_number => NULL,
1330 p_parent_line_location_id => NULL, --NUMBER,
1331 p_old_quantity => l_ship_quantity, --NUMBER,
1332 p_new_quantity => l_ship_quantity + p_po_change_table(i).new_quantity - p_po_change_table(i).old_quantity,
1333 p_old_promised_date => NULL, --DATE,
1334 p_new_promised_date => NULL, --DATE,
1335 p_old_supplier_part_number => NULL, --VARCHAR2(25),
1336 p_new_supplier_part_number => NULL, --VARCHAR2(25),
1337 p_old_price => NULL,
1338 p_new_price => NULL,
1339 p_old_supplier_reference_num => NULL, --VARCHAR2(30),
1340 p_new_supplier_reference_num => NULL,
1341 p_from_header_id => NULL, --NUMBER
1342 p_recoverable_tax => NULL, --NUMBER
1343 p_non_recoverable_tax => NULL, --NUMBER
1344 p_ship_to_location_id => l_ship_to_location_id,
1345 p_ship_to_organization_id => l_ship_to_organization_id ,
1346 p_old_need_by_date => l_need_by_date,
1347 p_new_need_by_date => NULL,
1348 p_approval_required_flag => NULL,
1349 p_parent_change_request_id => NULL,
1350 p_requester_id => NULL,
1351 p_old_supplier_order_number => NULL,
1352 p_new_supplier_order_number => NULL,
1353 p_old_supplier_order_line_num => NULL,
1354 p_new_supplier_order_line_num => NULL,
1355 p_additional_changes => NULL,
1356 p_old_start_date => NULL,
1357 p_new_start_date => NULL,
1358 p_old_expiration_date => NULL,
1359 p_new_expiration_date => NULL,
1360 p_old_amount => NULL,
1361 p_new_amount => NULL
1362 );
1363
1364 p_progress := 'G2-3' || to_char(l_po_change_table_count) ||' '|| to_char(i) ||' '|| to_char(p_po_change_table(i).document_line_location_id);
1365 l_po_tbl_index := l_po_tbl_index + 1;
1366 END IF;
1367 END IF;
1368 i := i + 1;
1369 END LOOP;
1370 EXCEPTION
1371 WHEN OTHERS THEN
1372 p_progress := p_progress || SQLERRM;
1373 RAISE;
1374 END;
1375
1376 /*
1377 * This API takes in a PLSQL table of requisition changes, transform it into PLSQL tables
1378 * of PO changes (groupd by po_header_id/po_release_id), and call ISP's validate_change_request
1379 * API to validate the changes
1380 */
1381 PROCEDURE validate_changes(p_req_hdr_id IN NUMBER,
1382 p_req_change_table IN OUT NOCOPY change_tbl_type,
1383 x_return_status OUT NOCOPY VARCHAR2,
1384 x_retmsg OUT NOCOPY VARCHAR,
1385 p_errortable IN OUT NOCOPY po_req_change_err_table)
1386 IS
1387 l_api_name VARCHAR2(50) := 'Validate_Changes';
1388 l_po_change_table pos_chg_rec_tbl;
1389 l_error_table error_tbl_type;
1390 l_main_loop_flag VARCHAR2(1) := fnd_api.g_true;
1391 l_get_cur_id_loop_flag VARCHAR2(1) := fnd_api.g_true;
1392 i NUMBER := 2;
1393 j NUMBER;
1394 k NUMBER;
1395 l_table_index NUMBER;
1396 l_po_header_id NUMBER;
1397 l_current_hdr_id NUMBER;
1398 l_current_rel_id NUMBER;
1399 l_hdr_id NUMBER;
1400 l_rel_id NUMBER;
1401 l_current_row_id NUMBER;
1402
1403 l_current_rev_num NUMBER;
1404 l_output_report_id NUMBER;
1405 l_found_clean VARCHAR2(1);
1406 l_doc_check_rec_type doc_check_return_type;
1407 l_online_report_id NUMBER;
1408 l_error_index NUMBER := 1;
1409
1410 l_return_status VARCHAR2(1);
1411 l_return_msg VARCHAR2(2000);
1412 l_err_po_msg VARCHAR2(2000);
1413
1414 l_pos_errors_tbl pos_err_type;
1415 l_decode_status VARCHAR2(1);
1416 l_decode_msg VARCHAR2(2000);
1417 l_val_qty_msg VARCHAR2(2000);
1418 l_val_qty_status VARCHAR2(1);
1419 l_err_count NUMBER;
1420 l_req_org_id NUMBER;
1421 BEGIN
1422 x_retmsg := 'VC000';
1423 x_return_status := fnd_api.g_ret_sts_success;
1424
1425 j := 1;
1426 l_main_loop_flag := fnd_api.g_true;
1427
1428 --Main Loop Starts
1429 --Main Loop continues so as long there exists records with dirty_flag = 'N'
1430 WHILE(l_main_loop_flag = fnd_api.g_true)
1431 LOOP
1432 x_retmsg := 'VC001';
1433 --Get First Clean Row => dirty_flag ='N'
1434 l_get_cur_id_loop_flag := fnd_api.g_true;
1435 l_found_clean := fnd_api.g_true;
1436 WHILE(l_get_cur_id_loop_flag = fnd_api.g_true) LOOP
1437 IF(j = p_req_change_table.count + 1) THEN /*Cannot find any Clean Row, Thus End Procedure*/
1438 l_main_loop_flag := fnd_api.g_false;
1439 l_get_cur_id_loop_flag := fnd_api.g_false;
1440 l_found_clean := fnd_api.g_false;
1441 ELSIF(p_req_change_table(j).dirty_flag = 'N') THEN
1442 l_current_row_id := j;
1443 j := j + 1;
1444 l_get_cur_id_loop_flag := fnd_api.g_false;
1445 ELSE
1446 j := j + 1;
1447 END IF;
1448 END LOOP;
1449
1450 x_retmsg := 'VC002';
1451
1452 --Obtained First Clean Row in l_current_row_id
1453
1454 IF(l_found_clean = fnd_api.g_true) THEN
1455
1456 --Get po_header_id/po_release_id for the current Clean Row
1457 SELECT
1458 plla.po_header_id,
1459 plla.po_release_id
1460 INTO
1461 l_current_hdr_id,
1462 l_current_rel_id
1463 FROM
1464 po_line_locations_all plla,
1465 po_requisition_lines_all prla
1466 WHERE prla.line_location_id = plla.line_location_id
1467 AND prla.requisition_line_id = p_req_change_table(l_current_row_id).document_line_id;
1468
1469 --Refresh l_po_change_table
1470 IF(l_po_change_table IS NOT NULL) THEN
1471 l_po_change_table.delete;
1472 END IF;
1473
1474 k := 2; /*index of l_po_change_table*/
1475 p_req_change_table(l_current_row_id).dirty_flag := 'Y';
1476
1477 l_po_change_table := pos_chg_rec_tbl();
1478 l_po_change_table.extend(1);
1479 copy_change(l_current_hdr_id, l_current_rel_id, p_req_hdr_id,
1480 p_req_change_table, l_current_row_id, 1, l_po_change_table);
1481
1482
1483 --Inner Loop Starts
1484 --Scan through remaining clean Rows in p_req_change_table, and extract those
1485 --clean rows, copy them over, and mark them as dirty..
1486 FOR i IN j .. p_req_change_table.count
1487 LOOP
1488
1489 IF (p_req_change_table(i).dirty_flag = 'N') THEN
1490
1491
1492
1493 --Get po_header_id/po_release_id of this clean row
1494 SELECT
1495 plla.po_header_id,
1496 plla.po_release_id
1497 INTO
1498 l_hdr_id,
1499 l_rel_id
1500 FROM
1501 po_line_locations_all plla,
1502 po_requisition_lines_all prla
1503 WHERE prla.line_location_id = plla.line_location_id
1504 AND prla.requisition_line_id = p_req_change_table(i).document_line_id;
1505
1506
1507
1508 --po_header_id matches
1509 IF(l_current_rel_id IS NULL AND l_rel_id IS NULL AND l_hdr_id = l_current_hdr_id) THEN
1510
1511
1512 l_po_change_table.extend(1);
1513 copy_change(l_current_hdr_id, l_current_rel_id, p_req_hdr_id,
1514 p_req_change_table, i, k, l_po_change_table);
1515
1516 p_req_change_table(i).dirty_flag := 'Y';
1517
1518 k := k + 1;
1519
1520 --po_release_id matches
1521 ELSIF(l_rel_id = l_current_rel_id) THEN
1522
1523
1524 l_po_change_table.extend(1);
1525 copy_change(l_current_hdr_id, l_current_rel_id, p_req_hdr_id,
1526 p_req_change_table, i, k, l_po_change_table);
1527
1528 p_req_change_table(i).dirty_flag := 'Y';
1529 k := k + 1;
1530
1531 END IF;
1532
1533 END IF;
1534
1535 END LOOP;
1536
1537 x_retmsg := 'VC003';
1538
1539
1540 -- Check new quantity against delivered/received/billed quantity
1541 validate_quantity(l_current_hdr_id,
1542 l_current_rel_id,
1543 l_po_change_table,
1544 p_errortable,
1545 l_error_index,
1546 l_val_qty_status,
1547 l_val_qty_msg);
1548
1549
1550
1551 x_retmsg := 'VC0031';
1552 generate_po_change_table(l_po_change_table, x_retmsg);
1553 x_retmsg := 'VC0031-1';
1554
1555 po_chg_request_pvt.validate_change_request(
1556 p_api_version => 1.0,
1557 p_init_msg_list => fnd_api.g_false,
1558 x_return_status => l_return_status,
1559 x_msg_data => l_return_msg,
1560 p_po_header_id => l_current_hdr_id,
1561 p_po_release_id => l_current_rel_id,
1562 p_revision_num => l_current_rev_num,
1563 p_po_change_requests => l_po_change_table,
1564 x_online_report_id => l_online_report_id,
1565 x_pos_errors => l_pos_errors_tbl,
1566 x_doc_check_error_msg => l_doc_check_rec_type);
1567 x_retmsg := 'VC0032';
1568
1569 -- BUG: 3590131
1570 -- validate_change_request API set's org id context
1571 -- to the PO document's org, we need to set it back
1572 SELECT org_id
1573 INTO l_req_org_id
1574 FROM po_requisition_headers_all
1575 WHERE requisition_header_id = p_req_hdr_id;
1576
1577 -- set org context back to req's org
1578 po_moac_utils_pvt.set_org_context(l_req_org_id) ; -- <R12 MOAC>
1579
1580 IF(l_return_status = fnd_api.g_ret_sts_error) THEN
1581 x_retmsg := 'VC0d31:' || l_return_msg;
1582 l_err_count := l_doc_check_rec_type.online_report_id.count;
1583 IF(l_err_count > 0) THEN
1584 FOR y IN 1..l_err_count
1585 LOOP
1586 l_err_po_msg := l_doc_check_rec_type.message_name(y);
1587 decode_poerror(l_current_hdr_id,
1588 l_current_rel_id,
1589 l_err_po_msg,
1590 l_doc_check_rec_type,
1591 y,
1592 p_errortable,
1593 l_error_index,
1594 l_decode_status,
1595 l_decode_msg);
1596 IF(l_decode_status <> fnd_api.g_ret_sts_success) THEN
1597 x_retmsg := 'VC0d41:' || l_decode_msg;
1598 x_return_status := fnd_api.g_ret_sts_error;
1599 RETURN;
1600 END IF;
1601 END LOOP;
1602 END IF;
1603 ELSIF(l_return_status = fnd_api.g_ret_sts_unexp_error) THEN
1604 x_retmsg := 'VC0f31:' || l_return_msg;
1605 x_return_status := fnd_api.g_ret_sts_unexp_error;
1606 RETURN;
1607 END IF;
1608
1609 END IF;
1610
1611 END LOOP;
1612
1613 x_retmsg := 'VC004';
1614
1615 IF(p_errortable.req_line_id.count>0) THEN
1616
1617 x_return_status := fnd_api.g_ret_sts_error;
1618 ELSE
1619
1620 x_return_status := fnd_api.g_ret_sts_success;
1621 END IF;
1622
1623
1624 EXCEPTION WHEN OTHERS THEN
1625 x_return_status := fnd_api.g_ret_sts_unexp_error;
1626 x_retmsg := 'VC_Exp:' || x_retmsg || ':' || SQLERRM;
1627 IF g_fnd_debug = 'Y' THEN
1628 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
1629 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
1630 l_api_name || '.others_exception', x_retmsg);
1631 END IF;
1632 END IF;
1633 END validate_changes;
1634
1635 /*
1636 *Simple API to insert change records into PO_CHANGE_REQUESTS table
1637 */
1638 PROCEDURE insert_reqchange(p_change_table change_tbl_type,
1639 p_chn_req_grp_id NUMBER)
1640 IS
1641 l_api_name VARCHAR2(50) := 'Insert_ReqChange';
1642 l_req_user_id NUMBER;
1643
1644 BEGIN
1645
1646 l_req_user_id := fnd_global.user_id;
1647 FOR i IN 1..p_change_table.count
1648 LOOP
1649
1650 INSERT INTO po_change_requests
1651 (
1652 change_request_group_id,
1653 change_request_id,
1654 initiator,
1655 action_type,
1656 request_reason,
1657 request_level,
1658 request_status,
1659 document_type,
1660 document_header_id,
1661 document_num,
1662 document_revision_num,
1663 created_by,
1664 creation_date,
1665 document_line_id,
1666 document_line_number,
1667 document_distribution_id,
1668 document_distribution_number,
1669 old_quantity,
1670 new_quantity,
1671 old_price,
1672 new_price,
1673 old_need_by_date,
1674 new_need_by_date,
1675 old_currency_unit_price,
1676 new_currency_unit_price,
1677 last_updated_by,
1678 last_update_date,
1679 last_update_login,
1680 requester_id,
1681 change_active_flag,
1682 ref_po_header_id,
1683 ref_po_num,
1684 ref_po_release_id,
1685 ref_po_rel_num,
1686 old_start_date,
1687 new_start_date,
1688 old_expiration_date,
1689 new_expiration_date,
1690 old_amount,
1691 new_amount,
1692 old_currency_amount,
1693 new_currency_amount
1694 )
1695 VALUES
1696 (
1697 p_chn_req_grp_id,
1698 po_chg_request_seq.nextval,
1699 'REQUESTER',
1700 p_change_table(i).action_type,
1701 p_change_table(i).request_reason,
1702 p_change_table(i).request_level,
1703 p_change_table(i).request_status,
1704 'REQ',
1705 p_change_table(i).document_header_id,
1706 p_change_table(i).document_num,
1707 p_change_table(i).document_revision_num,
1708 l_req_user_id,
1709 SYSDATE,
1710 p_change_table(i).document_line_id,
1711 p_change_table(i).document_line_number,
1712 p_change_table(i).document_distribution_id,
1713 p_change_table(i).document_distribution_number,
1714 p_change_table(i).old_quantity,
1715 p_change_table(i).new_quantity,
1716 p_change_table(i).old_price,
1717 p_change_table(i).new_price,
1718 p_change_table(i).old_date,
1719 p_change_table(i).new_date,
1720 p_change_table(i).old_currency_unit_price,
1721 p_change_table(i).new_currency_unit_price,
1722 l_req_user_id,
1723 SYSDATE,
1724 l_req_user_id,
1725 p_change_table(i).requester_id,
1726 'Y',
1727 p_change_table(i).referenced_po_header_id,
1728 p_change_table(i).referenced_po_document_num,
1729 p_change_table(i).referenced_release_id,
1730 p_change_table(i).referenced_release_num,
1731 p_change_table(i).old_start_date,
1732 p_change_table(i).new_start_date,
1733 p_change_table(i).old_end_date,
1734 p_change_table(i).new_end_date,
1735 p_change_table(i).old_budget_amount,
1736 p_change_table(i).new_budget_amount,
1737 p_change_table(i).old_currency_budget_amount,
1738 p_change_table(i).new_currency_budget_amount
1739 );
1740
1741 END LOOP;
1742
1743
1744 EXCEPTION WHEN OTHERS THEN
1745
1746 IF g_fnd_debug = 'Y' THEN
1747 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
1748 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
1749 l_api_name || '.others_exception', SQLERRM);
1750 END IF;
1751 END IF;
1752 RAISE;
1753 END insert_reqchange;
1754
1755 /*
1756 *Calculate recoverable tax and non-recoverable tax for a req dist.
1757 */
1758 PROCEDURE calculate_disttax(p_api_version IN NUMBER,
1759 x_return_status OUT NOCOPY VARCHAR2,
1760 p_dist_id NUMBER,
1761 p_price NUMBER,
1762 p_quantity NUMBER,
1763 p_dist_amount NUMBER,
1764 p_rec_tax OUT NOCOPY NUMBER,
1765 p_nonrec_tax OUT NOCOPY NUMBER)
1766 IS
1767 l_api_name VARCHAR2(50) := 'Calculate_DistTax';
1768 l_dist_total NUMBER;
1769 l_new_total NUMBER;
1770 l_rec_tax NUMBER;
1771 l_nonrec_tax NUMBER;
1772 BEGIN
1773 x_return_status := fnd_api.g_ret_sts_success;
1774
1775 SELECT
1776 decode(prl.matching_basis, 'AMOUNT', prd.req_line_amount, prl.unit_price * prd.req_line_quantity),
1777 decode(prl.matching_basis, 'AMOUNT', p_dist_amount, nvl(p_price, prl.unit_price) * nvl(p_quantity, prd.req_line_quantity)),
1778 prd.recoverable_tax,
1779 prd.nonrecoverable_tax
1780 INTO
1781 l_dist_total,
1782 l_new_total,
1783 l_rec_tax,
1784 l_nonrec_tax
1785 FROM
1786 po_requisition_lines_all prl,
1787 po_req_distributions_all prd
1788 WHERE prd.distribution_id = p_dist_id
1789 AND prd.requisition_line_id = prl.requisition_line_id;
1790
1791 -- Calcualte new tax only if existing total tax amount is
1792 -- greater than zero.
1793 IF((nvl(l_rec_tax, 0) + nvl(l_nonrec_tax, 0) ) > 0) THEN
1794 p_rec_tax := (l_rec_tax / l_dist_total) * l_new_total;
1795
1796 p_nonrec_tax :=
1797 (l_nonrec_tax / l_dist_total) *
1798 l_new_total;
1799 END IF;
1800 EXCEPTION WHEN OTHERS THEN
1801 x_return_status := fnd_api.g_ret_sts_unexp_error;
1802 IF g_fnd_debug = 'Y' THEN
1803 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
1804 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
1805 l_api_name || '.others_exception', SQLERRM);
1806 END IF;
1807 END IF;
1808 END calculate_disttax;
1809
1810 /*------------------------------------------------------+
1811 *Given a change group ID, update all distribution records
1812 *with tax information, if needed
1813 +-------------------------------------------------------*/
1814 PROCEDURE update_recordswithtax(p_chn_req_grp_id NUMBER)
1815 IS
1816 l_api_name VARCHAR2(50) := 'Update_RecordsWithTax';
1817 l_progress VARCHAR2(3) := '000';
1818 l_id NUMBER;
1819 l_line_id NUMBER;
1820 l_dist_id NUMBER;
1821 l_new_quantity NUMBER;
1822 l_quantity NUMBER;
1823 l_price NUMBER;
1824 l_rec_tax NUMBER;
1825 l_nonrec_tax NUMBER;
1826 l_cal_disttax_status VARCHAR2(1);
1827 l_dist_rec_tax NUMBER;
1828 l_dist_nonrec_tax NUMBER;
1829 l_temp_id NUMBER;
1830
1831 CURSOR l_dist_with_chn_csr(grp_id NUMBER, line_id NUMBER) IS
1832 SELECT
1833 change_request_id,
1834 new_quantity,
1835 document_distribution_id
1836 FROM po_change_requests
1837 WHERE change_request_group_id = grp_id
1838 AND document_line_id = line_id
1839 AND request_level = 'DISTRIBUTION';
1840
1841 CURSOR l_line_id_with_qty_chn_csr(grp_id NUMBER) IS
1842 SELECT DISTINCT document_line_id
1843 FROM po_change_requests
1844 WHERE change_request_group_id = grp_id
1845 AND new_quantity IS NOT NULL;
1846
1847 CURSOR l_line_id_with_price_chn_csr(grp_id NUMBER) IS
1848 SELECT
1849 change_request_id,
1850 document_line_id,
1851 new_price
1852 FROM po_change_requests
1853 WHERE change_request_group_id = grp_id
1854 AND new_price IS NOT NULL;
1855
1856 CURSOR l_dist_id_csr(line_id NUMBER) IS
1857 SELECT
1858 distribution_id,
1859 req_line_quantity
1860 FROM po_req_distributions_all
1861 WHERE requisition_line_id = l_line_id;
1862
1863
1864 CURSOR l_dist_exist_chn_csr(dist_id NUMBER, grp_id NUMBER) IS
1865 SELECT
1866 change_request_id,
1867 recoverable_tax,
1868 nonrecoverable_tax
1869 FROM po_change_requests
1870 WHERE change_request_group_id = p_chn_req_grp_id
1871 AND document_distribution_id = l_dist_id;
1872
1873
1874 BEGIN
1875
1876 --OUTER LOOP: loops through req distribution records with quantity change, and get the req line ID.
1877 --Objective is to populate tax attributes for distribution records (with quantity change)
1878 OPEN l_line_id_with_qty_chn_csr(p_chn_req_grp_id);
1879 LOOP
1880 FETCH l_line_id_with_qty_chn_csr INTO
1881 l_line_id;
1882 EXIT WHEN l_line_id_with_qty_chn_csr%notfound;
1883
1884 BEGIN
1885 SELECT nvl(new_currency_unit_price, new_price)
1886 INTO l_price
1887 FROM po_change_requests
1888 WHERE change_request_group_id = p_chn_req_grp_id
1889 AND document_line_id = l_line_id
1890 AND request_level = 'LINE'
1891 AND new_price IS NOT NULL;
1892 EXCEPTION WHEN OTHERS THEN
1893 SELECT nvl(currency_unit_price, unit_price)
1894 INTO l_price
1895 FROM po_requisition_lines_all
1896 WHERE requisition_line_id = l_line_id;
1897 END;
1898 l_progress := '001';
1899 --INNER LOOP: After getting the most recent price, update child distribution records with tax information.
1900 OPEN l_dist_with_chn_csr(p_chn_req_grp_id, l_line_id);
1901 LOOP
1902 FETCH l_dist_with_chn_csr INTO l_id, l_new_quantity, l_dist_id ;
1903 EXIT WHEN l_dist_with_chn_csr %notfound;
1904
1905 IF(l_new_quantity IS NOT NULL) THEN
1906 calculate_disttax(1.0, l_cal_disttax_status, l_dist_id, l_price, l_new_quantity, NULL, l_rec_tax, l_nonrec_tax);
1907 ELSE
1908 SELECT req_line_quantity
1909 INTO l_quantity
1910 FROM po_req_distributions_all
1911 WHERE distribution_id = l_dist_id;
1912 calculate_disttax(1.0, l_cal_disttax_status, l_dist_id, l_price, l_quantity, NULL, l_rec_tax, l_nonrec_tax);
1913 END IF;
1914 UPDATE po_change_requests
1915 SET recoverable_tax = l_rec_tax,
1916 nonrecoverable_tax = l_nonrec_tax
1917 WHERE change_request_id = l_id;
1918
1919
1920 END LOOP;
1921 CLOSE l_dist_with_chn_csr;
1922 END LOOP;
1923 CLOSE l_line_id_with_qty_chn_csr;
1924
1925 l_dist_id := NULL;
1926 l_price := NULL;
1927 l_quantity := NULL;
1928
1929 l_progress := '002';
1930 --2nd OUTER LOOP: update recoverable and non recoverable tax attributes of Line Records (with Price Change)
1931 OPEN l_line_id_with_price_chn_csr(p_chn_req_grp_id);
1932 LOOP
1933 FETCH l_line_id_with_price_chn_csr INTO l_id, l_line_id, l_price;
1934 EXIT WHEN l_line_id_with_price_chn_csr%notfound;
1935
1936 l_rec_tax := 0;
1937 l_nonrec_tax := 0;
1938
1939 OPEN l_dist_id_csr(l_line_id);
1940 LOOP
1941 FETCH l_dist_id_csr INTO
1942 l_dist_id,
1943 l_quantity;
1944 EXIT WHEN l_dist_id_csr%notfound;
1945
1946 OPEN l_dist_exist_chn_csr(l_dist_id, p_chn_req_grp_id);
1947 FETCH l_dist_exist_chn_csr INTO
1948 l_temp_id,
1949 l_dist_rec_tax,
1950 l_dist_nonrec_tax;
1951 CLOSE l_dist_exist_chn_csr;
1952
1953 IF(l_temp_id IS NOT NULL) THEN -- Distribution exist in po_change_requests table
1954 l_rec_tax := l_rec_tax + l_dist_rec_tax;
1955 l_nonrec_tax := l_nonrec_tax + l_dist_nonrec_tax;
1956 ELSE -- Distribution does NOT exist in change table, thus need to calculate
1957 calculate_disttax(1.0, l_cal_disttax_status, l_dist_id, l_price, l_quantity, NULL, l_dist_rec_tax, l_dist_nonrec_tax);
1958 l_rec_tax := l_rec_tax + l_dist_rec_tax;
1959 l_nonrec_tax := l_nonrec_tax + l_dist_nonrec_tax;
1960 END IF;
1961
1962 END LOOP;
1963 CLOSE l_dist_id_csr;
1964
1965 l_progress := '003';
1966 UPDATE po_change_requests
1967 SET recoverable_tax = l_rec_tax,
1968 nonrecoverable_tax = l_nonrec_tax
1969 WHERE change_request_id = l_id;
1970 END LOOP;
1971 CLOSE l_line_id_with_price_chn_csr;
1972
1973 EXCEPTION WHEN OTHERS THEN
1974 IF g_fnd_debug = 'Y' THEN
1975 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
1976 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
1977 l_api_name || '.others_exception',
1978 p_chn_req_grp_id || '*' || l_progress || ':' || SQLERRM);
1979 END IF;
1980 END IF;
1981 RAISE;
1982 END update_recordswithtax;
1983
1984 /*------------------------------------------------------+
1985 *Given a change group ID, update all line records
1986 *with tax information, if qunatity is changed needed
1987 +-------------------------------------------------------*/
1988 PROCEDURE update_internalrecordswithtax(p_chn_req_grp_id NUMBER)
1989 IS
1990 l_id NUMBER;
1991 l_line_id NUMBER;
1992 l_dist_id NUMBER;
1993 l_new_quantity NUMBER;
1994 l_quantity NUMBER;
1995 l_price NUMBER;
1996 l_rec_tax NUMBER;
1997 l_nonrec_tax NUMBER;
1998 l_cal_disttax_status VARCHAR2(1);
1999 l_dist_rec_tax NUMBER;
2000 l_dist_nonrec_tax NUMBER;
2001 l_temp_id NUMBER;
2002
2003 CURSOR l_line_id_with_qty_chn_csr(grp_id NUMBER) IS
2004 SELECT DISTINCT document_line_id
2005 FROM po_change_requests
2006 WHERE change_request_group_id = grp_id
2007 AND new_quantity IS NOT NULL;
2008
2009
2010 CURSOR l_dist_id_csr(line_id NUMBER) IS
2011 SELECT
2012 distribution_id,
2013 req_line_quantity
2014 FROM po_req_distributions_all
2015 WHERE requisition_line_id = l_line_id;
2016
2017
2018 CURSOR l_dist_exist_chn_csr(dist_id NUMBER, grp_id NUMBER) IS
2019 SELECT
2020 change_request_id,
2021 recoverable_tax,
2022 nonrecoverable_tax
2023 FROM po_change_requests
2024 WHERE change_request_group_id = p_chn_req_grp_id
2025 AND document_distribution_id = l_dist_id;
2026
2027 CURSOR l_dist_with_chn_csr(grp_id NUMBER, line_id NUMBER) IS
2028 SELECT
2029 change_request_id,
2030 new_quantity,
2031 document_distribution_id
2032 FROM po_change_requests
2033 WHERE change_request_group_id = grp_id
2034 AND document_line_id = line_id
2035 AND request_level = 'LINE';
2036
2037
2038 l_api_name CONSTANT VARCHAR(30) := 'Update_InternalRecordsWithTax';
2039 l_log_head CONSTANT VARCHAR2(100) := c_log_head || l_api_name;
2040 l_progress VARCHAR2(3) := '000';
2041
2042 BEGIN
2043
2044 IF g_debug_stmt THEN
2045 po_debug.debug_begin(l_log_head);
2046 po_debug.debug_var(l_log_head, l_progress, 'p_chn_req_grp_id', p_chn_req_grp_id);
2047 END IF;
2048
2049 --OUTER LOOP: loops through req distribution records with quantity change, and get the req line ID.
2050 --Objective is to populate tax attributes for distribution records (with quantity change)
2051 OPEN l_line_id_with_qty_chn_csr(p_chn_req_grp_id);
2052 LOOP
2053 FETCH l_line_id_with_qty_chn_csr INTO
2054 l_line_id;
2055 EXIT WHEN l_line_id_with_qty_chn_csr%notfound;
2056
2057 BEGIN
2058 SELECT nvl(currency_unit_price, unit_price)
2059 INTO l_price
2060 FROM po_requisition_lines_all
2061 WHERE requisition_line_id = l_line_id;
2062 EXCEPTION WHEN OTHERS THEN
2063 l_price := NULL;
2064 END;
2065 l_progress := '001';
2066
2067 IF g_debug_stmt THEN
2068 po_debug.debug_var(l_log_head, l_progress, 'l_line_id', l_line_id);
2069 po_debug.debug_var(l_log_head, l_progress, 'l_price', l_price);
2070 END IF;
2071
2072
2073 --INNER LOOP: After getting the most recent price, update child distribution records with tax information.
2074 OPEN l_dist_with_chn_csr(p_chn_req_grp_id, l_line_id);
2075 LOOP
2076 FETCH l_dist_with_chn_csr INTO l_id, l_new_quantity, l_dist_id ;
2077 EXIT WHEN l_dist_with_chn_csr %notfound;
2078
2079 calculate_disttax(1.0, l_cal_disttax_status, l_dist_id, l_price, l_new_quantity, NULL, l_rec_tax, l_nonrec_tax);
2080
2081 l_progress := '002';
2082
2083 IF g_debug_stmt THEN
2084 po_debug.debug_var(l_log_head, l_progress, 'l_rec_tax', l_rec_tax);
2085 po_debug.debug_var(l_log_head, l_progress, 'l_nonrec_tax', l_nonrec_tax);
2086 po_debug.debug_stmt(l_log_head, l_progress,'Updating taxes in po_change_request table');
2087 END IF;
2088
2089
2090 UPDATE po_change_requests
2091 SET recoverable_tax = l_rec_tax,
2092 nonrecoverable_tax = l_nonrec_tax
2093 WHERE change_request_id = l_id;
2094
2095
2096 END LOOP;
2097 CLOSE l_dist_with_chn_csr;
2098 END LOOP;
2099 CLOSE l_line_id_with_qty_chn_csr;
2100
2101 EXCEPTION WHEN OTHERS THEN
2102 IF g_fnd_debug = 'Y' THEN
2103 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
2104 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
2105 l_api_name || '.others_exception',
2106 p_chn_req_grp_id || '*' || l_progress || ':' || SQLERRM);
2107 END IF;
2108 END IF;
2109 RAISE;
2110 END update_internalrecordswithtax;
2111 /*--------------------------------------------------------------------
2112 *Copy a requisition change record into a PO change record,
2113 *meanwhile updating the req change record with more information
2114 -----------------------------------------------------------------*/
2115 PROCEDURE copy_change(p_header_id NUMBER,
2116 p_release_id NUMBER,
2117 p_req_hdr_id NUMBER,
2118 req_change_record_tbl IN OUT NOCOPY change_tbl_type,
2119 req_index IN NUMBER,
2120 po_index IN NUMBER,
2121 po_change_record_tbl IN OUT NOCOPY pos_chg_rec_tbl)
2122 IS
2123 l_api_name VARCHAR2(50) := 'Copy_Change';
2124 l_progress VARCHAR2(3) := '000';
2125 l_po_doc_type VARCHAR2(30);
2126 l_po_num po_headers_all.segment1%TYPE;
2127 l_po_revision_num NUMBER;
2128 l_po_line_id NUMBER;
2129 l_po_line_number NUMBER;
2130 l_po_line_location_id NUMBER;
2131 l_po_shipment_number NUMBER;
2132 l_po_distribution_id NUMBER;
2133 l_po_distribution_number NUMBER;
2134 l_recoverable_tax NUMBER;
2135 l_non_recoverable_tax NUMBER;
2136 l_po_request_level po_change_requests.request_level%TYPE;
2137 l_req_request_level po_change_requests.request_level%TYPE;
2138 l_req_header_id NUMBER;
2139 l_req_num po_requisition_headers_all.segment1%TYPE;
2140 l_req_line_number NUMBER;
2141 l_req_dist_number NUMBER;
2142 l_new_functional_price NUMBER;
2143 l_old_curr_unit_price NUMBER;
2144 l_old_po_price NUMBER;
2145 l_old_req_price NUMBER;
2146 l_old_po_quantity NUMBER;
2147 l_old_req_quantity NUMBER;
2148 l_old_po_date DATE;
2149 l_old_req_date DATE;
2150 l_new_po_price NUMBER;
2151 l_new_po_quantity NUMBER;
2152 l_price_temp NUMBER;
2153 l_preparer_id NUMBER;
2154 l_po_ship_to_loc_id NUMBER;
2155 l_po_ship_to_org_id NUMBER;
2156 l_item_id NUMBER;
2157 l_req_uom po_requisition_lines_all.unit_meas_lookup_code%TYPE;
2158 l_po_uom po_line_locations_all.unit_meas_lookup_code%TYPE;
2159 l_po_to_req_rate NUMBER;
2160 l_release_num NUMBER;
2161 l_old_start_date DATE;
2162 l_old_end_date DATE;
2163 l_old_amount NUMBER;
2164 l_old_curr_amount NUMBER;
2165 l_old_po_amount NUMBER;
2166 l_new_start_date DATE;
2167 l_new_end_date DATE;
2168 l_new_amount NUMBER;
2169 l_new_curr_amount NUMBER;
2170 l_new_po_amount NUMBER;
2171 l_new_functional_amount NUMBER;
2172 l_amount_temp NUMBER;
2173
2174 BEGIN
2175
2176
2177 IF(p_release_id IS NULL) THEN
2178 IF(req_change_record_tbl(req_index).document_distribution_id IS NOT NULL) THEN
2179
2180 --Standard PO Distribution Change
2181 l_po_request_level := 'DISTRIBUTION';
2182 l_req_request_level := 'DISTRIBUTION';
2183 l_progress := '001';
2184 SELECT
2185 'PO',
2186 pha.segment1,
2187 pha.revision_num,
2188 pla.po_line_id,
2189 pla.line_num,
2190 plla.line_location_id,
2191 plla.shipment_num,
2192 pda.po_distribution_id,
2193 pda.distribution_num,
2194 prha.segment1,
2195 prla.line_num,
2196 prda.distribution_num,
2197 prda.req_line_quantity,
2198 pda.quantity_ordered,
2199 prha.preparer_id,
2200 plla.ship_to_location_id,
2201 plla.ship_to_organization_id,
2202 prla.unit_meas_lookup_code,
2203 nvl(plla.unit_meas_lookup_code, pla.unit_meas_lookup_code),
2204 prla.item_id,
2205 pha.rate,
2206 prla.unit_price,
2207 prla.need_by_date,
2208 prla.assignment_start_date,
2209 prla.assignment_end_date,
2210 prda.req_line_amount,
2211 prda.req_line_currency_amount,
2212 pda.amount_ordered
2213 INTO
2214 l_po_doc_type,
2215 l_po_num,
2216 l_po_revision_num,
2217 l_po_line_id,
2218 l_po_line_number,
2219 l_po_line_location_id,
2220 l_po_shipment_number,
2221 l_po_distribution_id,
2222 l_po_distribution_number,
2223 l_req_num,
2224 l_req_line_number,
2225 l_req_dist_number,
2226 l_old_req_quantity,
2227 l_old_po_quantity,
2228 l_preparer_id,
2229 l_po_ship_to_loc_id,
2230 l_po_ship_to_org_id,
2231 l_req_uom,
2232 l_po_uom,
2233 l_item_id,
2234 l_po_to_req_rate,
2235 l_old_req_price,
2236 l_old_req_date,
2237 l_old_start_date,
2238 l_old_end_date,
2239 l_old_amount,
2240 l_old_curr_amount,
2241 l_old_po_amount
2242 FROM
2243 po_headers_all pha,
2244 po_lines_all pla,
2245 po_line_locations_all plla,
2246 po_req_distributions_all prda,
2247 po_requisition_lines_all prla,
2248 po_requisition_headers_all prha,
2249 po_distributions_all pda
2250 WHERE
2251 prda.distribution_id = req_change_record_tbl(req_index).document_distribution_id
2252 AND prda.requisition_line_id = prla.requisition_line_id
2253 AND prla.line_location_id = plla.line_location_id
2254 AND plla.po_line_id = pla.po_line_id
2255 AND pla.po_header_id = pha.po_header_id
2256 AND prha.requisition_header_id = prla.requisition_header_id
2257 AND pda.req_distribution_id = prda.distribution_id
2258 AND pda.line_location_id = prla.line_location_id;
2259
2260 ELSE
2261
2262 l_req_request_level := 'LINE';
2263
2264 l_progress := '002';
2265 SELECT
2266 'PO',
2267 pha.segment1,
2268 pha.revision_num,
2269 pla.po_line_id,
2270 pla.line_num,
2271 plla.line_location_id,
2272 plla.shipment_num,
2273 prha.segment1,
2274 prla.line_num,
2275 pla.unit_price,
2276 prla.currency_unit_price,
2277 prla.unit_price,
2278 prla.need_by_date,
2279 plla.need_by_date,
2280 prha.preparer_id,
2281 plla.ship_to_location_id,
2282 plla.ship_to_organization_id,
2283 prla.unit_meas_lookup_code,
2284 nvl(plla.unit_meas_lookup_code, pla.unit_meas_lookup_code),
2285 prla.item_id,
2286 pha.rate,
2287 prla.quantity,
2288 plla.quantity,
2289 prla.assignment_start_date,
2290 prla.assignment_end_date,
2291 prla.amount,
2292 prla.currency_amount,
2293 plla.amount
2294 INTO
2295 l_po_doc_type,
2296 l_po_num,
2297 l_po_revision_num,
2298 l_po_line_id,
2299 l_po_line_number,
2300 l_po_line_location_id,
2301 l_po_shipment_number,
2302 l_req_num,
2303 l_req_line_number,
2304 l_old_po_price,
2305 l_old_curr_unit_price,
2306 l_old_req_price,
2307 l_old_req_date,
2308 l_old_po_date,
2309 l_preparer_id,
2310 l_po_ship_to_loc_id,
2311 l_po_ship_to_org_id,
2312 l_req_uom,
2313 l_po_uom,
2314 l_item_id,
2315 l_po_to_req_rate,
2316 l_old_req_quantity,
2317 l_old_po_quantity,
2318 l_old_start_date,
2319 l_old_end_date,
2320 l_old_amount,
2321 l_old_curr_amount,
2322 l_old_po_amount
2323 FROM
2324 po_headers_all pha,
2325 po_lines_all pla,
2326 po_line_locations_all plla,
2327 po_requisition_lines_all prla,
2328 po_requisition_headers_all prha
2329 WHERE
2330 prla.requisition_line_id = req_change_record_tbl(req_index).document_line_id
2331 AND prla.line_location_id = plla.line_location_id
2332 AND plla.po_line_id = pla.po_line_id
2333 AND pla.po_header_id = pha.po_header_id
2334 AND prha.requisition_header_id = prla.requisition_header_id;
2335 IF(req_change_record_tbl(req_index).new_price IS NOT NULL) THEN
2336 l_po_request_level := 'LINE';
2337 l_po_line_location_id := NULL;
2338 l_po_shipment_number := NULL;
2339 l_po_ship_to_loc_id := NULL;
2340 l_po_ship_to_org_id := NULL;
2341 l_old_po_quantity := NULL;
2342 ELSE
2343 l_po_request_level := 'SHIPMENT';
2344 END IF;
2345
2346 END IF;
2347 ELSE
2348 IF(req_change_record_tbl(req_index).document_distribution_id IS NOT NULL) THEN
2349
2350 --Standard PO Distribution Change
2351 l_po_request_level := 'DISTRIBUTION';
2352 l_req_request_level := 'DISTRIBUTION';
2353 l_progress := '003';
2354 SELECT
2355 'PO',
2356 pha.segment1,
2357 pra.revision_num,
2358 plla.po_line_id,
2359 plla.line_location_id,
2360 plla.shipment_num,
2361 pda.po_distribution_id,
2362 pda.distribution_num,
2363 prha.segment1,
2364 prla.line_num,
2365 prda.distribution_num,
2366 prda.req_line_quantity,
2367 pda.quantity_ordered,
2368 prha.preparer_id,
2369 plla.ship_to_location_id,
2370 plla.ship_to_organization_id,
2371 prla.unit_meas_lookup_code,
2372 nvl(plla.unit_meas_lookup_code, pla.unit_meas_lookup_code),
2373 prla.item_id,
2374 pha.rate,
2375 prla.unit_price,
2376 prla.need_by_date,
2377 pra.release_num,
2378 prla.assignment_start_date,
2379 prla.assignment_end_date,
2380 prda.req_line_amount,
2381 prda.req_line_currency_amount,
2382 pda.amount_ordered
2383 INTO
2384 l_po_doc_type,
2385 l_po_num,
2386 l_po_revision_num,
2387 l_po_line_id,
2388 l_po_line_location_id,
2389 l_po_shipment_number,
2390 l_po_distribution_id,
2391 l_po_distribution_number,
2392 l_req_num,
2393 l_req_line_number,
2394 l_req_dist_number,
2395 l_old_req_quantity,
2396 l_old_po_quantity,
2397 l_preparer_id,
2398 l_po_ship_to_loc_id,
2399 l_po_ship_to_org_id,
2400 l_req_uom,
2401 l_po_uom,
2402 l_item_id,
2403 l_po_to_req_rate,
2404 l_old_req_price,
2405 l_old_req_date,
2406 l_release_num,
2407 l_old_start_date,
2408 l_old_end_date,
2409 l_old_amount,
2410 l_old_curr_amount,
2411 l_old_po_amount
2412 FROM
2413 po_headers_all pha,
2414 po_releases_all pra,
2415 po_lines_all pla,
2416 po_line_locations_all plla,
2417 po_distributions_all pda,
2418 po_req_distributions_all prda,
2419 po_requisition_lines_all prla,
2420 po_requisition_headers_all prha
2421 WHERE
2422 prda.distribution_id = req_change_record_tbl(req_index).document_distribution_id
2423 AND prda.distribution_id = pda.req_distribution_id
2424 AND pda.line_location_id = plla.line_location_id
2425 AND plla.po_release_id = pra.po_release_id
2426 AND pra.po_header_id = pha.po_header_id
2427 AND prla.requisition_line_id = req_change_record_tbl(req_index).document_line_id
2428 AND prha.requisition_header_id = prla.requisition_header_id
2429 AND prla.line_location_id = pda.line_location_id
2430 AND pla.po_line_id = plla.po_line_id;
2431
2432 ELSE
2433
2434 l_req_request_level := 'LINE';
2435 l_po_request_level := 'SHIPMENT';
2436 l_progress := '004';
2437 SELECT
2438 'PO',
2439 pha.segment1,
2440 pra.revision_num,
2441 plla.po_line_id,
2442 plla.line_location_id,
2443 plla.shipment_num,
2444 prha.segment1,
2445 prla.line_num,
2446 plla.price_override,
2447 prla.currency_unit_price,
2448 prla.unit_price,
2449 prla.need_by_date,
2450 plla.need_by_date,
2451 prha.preparer_id,
2452 plla.ship_to_location_id,
2453 plla.ship_to_organization_id,
2454 prla.unit_meas_lookup_code,
2455 nvl(plla.unit_meas_lookup_code, pla.unit_meas_lookup_code),
2456 prla.item_id,
2457 pha.rate,
2458 prla.quantity,
2459 plla.quantity,
2460 pra.release_num,
2461 prla.assignment_start_date,
2462 prla.assignment_end_date,
2463 prla.amount,
2464 prla.currency_amount,
2465 plla.amount
2466 INTO
2467 l_po_doc_type,
2468 l_po_num,
2469 l_po_revision_num,
2470 l_po_line_id,
2471 l_po_line_location_id,
2472 l_po_shipment_number,
2473 l_req_num,
2474 l_req_line_number,
2475 l_old_po_price,
2476 l_old_curr_unit_price,
2477 l_old_req_price,
2478 l_old_req_date,
2479 l_old_po_date,
2480 l_preparer_id,
2481 l_po_ship_to_loc_id,
2482 l_po_ship_to_org_id,
2483 l_req_uom,
2484 l_po_uom,
2485 l_item_id,
2486 l_po_to_req_rate,
2487 l_old_req_quantity,
2488 l_old_po_quantity,
2489 l_release_num,
2490 l_old_start_date,
2491 l_old_end_date,
2492 l_old_amount,
2493 l_old_curr_amount,
2494 l_old_po_amount
2495 FROM
2496 po_headers_all pha,
2497 po_releases_all pra,
2498 po_lines_all pla,
2499 po_line_locations_all plla,
2500 po_requisition_lines_all prla,
2501 po_requisition_headers_all prha
2502 WHERE
2503 prla.requisition_line_id = req_change_record_tbl(req_index).document_line_id
2504 AND prla.line_location_id = plla.line_location_id
2505 AND plla.po_release_id = pra.po_release_id
2506 AND pra.po_header_id = pha.po_header_id
2507 AND prha.requisition_header_id = prla.requisition_header_id
2508 AND pla.po_line_id = plla.po_line_id;
2509 END IF;
2510 END IF;
2511
2512 -- Calculate New PO Quantity based on UOM Conversion
2513 IF(l_req_uom <> l_po_uom) THEN
2514 po_uom_s.uom_convert(
2515 from_quantity => req_change_record_tbl(req_index).new_quantity,
2516 from_uom => l_req_uom,
2517 item_id => l_item_id,
2518 to_uom => l_po_uom,
2519 to_quantity => l_new_po_quantity);
2520 ELSE
2521 l_new_po_quantity := req_change_record_tbl(req_index).new_quantity;
2522 END IF;
2523
2524 -- Calculate New PO Price based on Currency Conversion
2525 IF(req_change_record_tbl(req_index).new_price IS NOT NULL) THEN
2526
2527 l_new_functional_price := calculate_newunitprice(req_change_record_tbl(req_index).document_line_id,
2528 req_change_record_tbl(req_index).new_price);
2529 IF(l_new_functional_price IS NOT NULL) THEN
2530 l_price_temp := req_change_record_tbl(req_index).new_price;
2531 req_change_record_tbl(req_index).new_price := l_new_functional_price;
2532 req_change_record_tbl(req_index).new_currency_unit_price := l_price_temp;
2533 req_change_record_tbl(req_index).old_currency_unit_price := l_old_curr_unit_price;
2534
2535 IF(l_po_to_req_rate IS NULL) THEN
2536 l_new_po_price := l_new_functional_price;
2537 ELSE
2538 l_new_po_price := l_new_functional_price / l_po_to_req_rate;
2539 END IF;
2540 ELSE
2541 IF(l_po_to_req_rate IS NULL) THEN
2542 l_new_po_price := req_change_record_tbl(req_index).new_price;
2543 ELSE
2544 l_new_po_price := req_change_record_tbl(req_index).new_price / l_po_to_req_rate;
2545 END IF;
2546 END IF;
2547 END IF;
2548
2549 l_new_start_date := req_change_record_tbl(req_index).new_start_date;
2550 l_new_end_date := req_change_record_tbl(req_index).new_end_date;
2551
2552 -- Calculate New PO AMOUNT based on Currency Conversion
2553 IF(req_change_record_tbl(req_index).new_budget_amount IS NOT NULL) THEN
2554
2555 l_new_functional_amount := calculate_newunitprice(req_change_record_tbl(req_index).document_line_id, req_change_record_tbl(req_index).new_budget_amount);
2556 IF(l_new_functional_amount IS NOT NULL) THEN
2557 l_amount_temp := req_change_record_tbl(req_index).new_budget_amount;
2558 req_change_record_tbl(req_index).new_budget_amount := l_new_functional_amount;
2559 req_change_record_tbl(req_index).new_currency_budget_amount := l_amount_temp;
2560 req_change_record_tbl(req_index).old_currency_budget_amount := l_old_curr_amount;
2561
2562 IF(l_po_to_req_rate IS NULL) THEN
2563 l_new_po_amount := l_new_functional_amount;
2564 ELSE
2565 l_new_po_amount := l_new_functional_amount / l_po_to_req_rate;
2566 END IF;
2567 ELSE
2568 IF(l_po_to_req_rate IS NULL) THEN
2569 l_new_po_amount := req_change_record_tbl(req_index).new_budget_amount;
2570 ELSE
2571 l_new_po_amount := req_change_record_tbl(req_index).new_budget_amount / l_po_to_req_rate;
2572 END IF;
2573 END IF;
2574 END IF;
2575
2576
2577 po_change_record_tbl(po_index) := po_chg_request_pvt.create_pos_change_rec(
2578 p_action_type => 'MODIFICATION',
2579 p_initiator => 'REQUESTER',
2580 p_document_type => l_po_doc_type,
2581 p_request_level => l_po_request_level,
2582 p_request_status => 'SYSTEMSAVE',
2583 p_document_header_id => p_header_id,
2584 p_request_reason => req_change_record_tbl(req_index).request_reason,
2585 p_po_release_id => p_release_id,
2586 p_document_num => l_po_num,
2587 p_document_revision_num => l_po_revision_num,
2588 p_document_line_id => l_po_line_id,
2589 p_document_line_number => l_po_line_number,
2590 p_document_line_location_id => l_po_line_location_id,
2591 p_document_shipment_number => l_po_shipment_number,
2592 p_document_distribution_id => l_po_distribution_id,
2593 p_document_distribution_number => l_po_distribution_number,
2594 p_parent_line_location_id => NULL,
2595 p_old_quantity => l_old_po_quantity, --OLD_QUANTITY
2596 p_new_quantity => l_new_po_quantity, -- NEW_QUANTITY **
2597 p_old_promised_date => NULL, -- OLD_PROMISED_DATE
2598 p_new_promised_date => NULL, --NEW_PROMISED_DATE
2599 p_old_supplier_part_number => NULL, --OLD_SUPPLIER_PART_NUMBER
2600 p_new_supplier_part_number => NULL, --NEW_SUPPLIER_PART_NUMBER
2601 p_old_price => l_old_po_price, --OLD_PRICE
2602 p_new_price => l_new_po_price, -- NEW_PRICE **
2603 p_old_supplier_reference_num => NULL, --OLD_SUPPLIER_REFERENCE_NUMBER
2604 p_new_supplier_reference_num => NULL, --NEW_SUPPLIER_REFERENCE_NUMBER
2605 p_from_header_id => NULL, --FROM_HEADER_ID
2606 p_recoverable_tax => NULL, --RECOVERABLE_TAX
2607 p_non_recoverable_tax => NULL, --NON_RECOVERABLE_TAX
2608 p_ship_to_location_id => l_po_ship_to_loc_id,-- SHIP_TO_LOCATION_ID
2609 p_ship_to_organization_id => l_po_ship_to_org_id,-- SHIP_TO_ORGANIZATION_ID
2610 p_old_need_by_date => l_old_po_date, --OLD_NEED_BY_DATE
2611 p_new_need_by_date => req_change_record_tbl(req_index).new_date, --NEW_NEED_BY_DATE
2612 p_approval_required_flag => NULL,
2613 p_parent_change_request_id => NULL,
2614 p_requester_id => NULL,
2615 p_old_supplier_order_number => NULL,
2616 p_new_supplier_order_number => NULL,
2617 p_old_supplier_order_line_num => NULL,
2618 p_new_supplier_order_line_num => NULL,
2619 p_additional_changes => NULL, -- additional_change
2620 p_old_start_date => l_old_start_date,
2621 p_new_start_date => l_new_start_date,
2622 p_old_expiration_date => l_old_end_date,
2623 p_new_expiration_date => l_new_end_date,
2624 p_old_amount => l_old_po_amount,
2625 p_new_amount => l_new_po_amount);
2626
2627
2628 req_change_record_tbl(req_index).action_type := 'MODIFICATION';
2629
2630 req_change_record_tbl(req_index).initiator := 'REQUESTER';
2631 req_change_record_tbl(req_index).request_level := l_req_request_level;
2632 req_change_record_tbl(req_index).request_status := 'SYSTEMSAVE';
2633 req_change_record_tbl(req_index).document_header_id := p_req_hdr_id;
2634 req_change_record_tbl(req_index).document_num := l_req_num;
2635 req_change_record_tbl(req_index).document_revision_num := l_po_revision_num;
2636
2637 req_change_record_tbl(req_index).document_line_number := l_req_line_number;
2638 req_change_record_tbl(req_index).document_distribution_number := l_req_dist_number;
2639
2640 req_change_record_tbl(req_index).old_quantity := l_old_req_quantity;
2641 req_change_record_tbl(req_index).old_price := l_old_req_price;
2642 req_change_record_tbl(req_index).old_date := l_old_req_date;
2643 req_change_record_tbl(req_index).requester_id := l_preparer_id;
2644
2645 req_change_record_tbl(req_index).referenced_po_header_id := p_header_id;
2646 req_change_record_tbl(req_index).referenced_po_document_num := l_po_num;
2647 req_change_record_tbl(req_index).referenced_release_id := p_release_id;
2648 req_change_record_tbl(req_index).referenced_release_num := l_release_num;
2649
2650 req_change_record_tbl(req_index).old_start_date := l_old_start_date;
2651 req_change_record_tbl(req_index).old_end_date := l_old_end_date;
2652 req_change_record_tbl(req_index).old_budget_amount := l_old_amount;
2653 req_change_record_tbl(req_index).old_currency_budget_amount := l_old_curr_amount;
2654
2655 --Exception Handling will be taken care of in parent procedures
2656 EXCEPTION WHEN OTHERS THEN
2657 IF g_fnd_debug = 'Y' THEN
2658 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
2659 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
2660 l_api_name || '.others_exception',
2661 l_progress || ':' || SQLERRM);
2662 END IF;
2663 END IF;
2664 RAISE;
2665 END copy_change;
2666
2667 /*--------------------------------------------------------------
2668 * IS_ON_COMPLEX_WORK_ORDER: For a particular Requisition dwishipment,
2669 * this API checks if the shipment is linked to a complex work order
2670 ----------------------------------------------------------------*/
2671 PROCEDURE is_on_complex_work_order(p_line_loc_id IN NUMBER,
2672 x_return_status OUT NOCOPY VARCHAR2)
2673 IS
2674 l_header_id po_line_locations_all.po_header_id%TYPE;
2675 l_api_name VARCHAR2(100) := 'is_on_complex_work_order()';
2676 BEGIN
2677
2678 x_return_status := 'N';
2679
2680 IF(p_line_loc_id IS NOT NULL) THEN
2681 SELECT po_header_id INTO l_header_id
2682 FROM po_line_locations_all
2683 WHERE line_location_id = p_line_loc_id;
2684
2685 --Call the PO API to check whether the passed PO is complex work order.
2686 IF (po_complex_work_pvt.is_complex_work_po(l_header_id)) THEN
2687 x_return_status := 'Y';
2688 END IF;
2689 END IF;
2690
2691 EXCEPTION
2692 WHEN OTHERS THEN
2693 x_return_status := fnd_api.g_ret_sts_unexp_error;
2694 fnd_msg_pub.add_exc_msg(g_module_prefix, l_api_name);
2695 END is_on_complex_work_order;
2696
2697 /*--------------------------------------------------------------
2698 * IS_COMPLEX_WORK_ORDER: For a particular Award slected for a particular requisition line,
2699 * this API checks if the award is a complex work order
2700 ----------------------------------------------------------------*/
2701 PROCEDURE is_complex_work_order(p_header_id IN NUMBER,
2702 x_return_status OUT NOCOPY VARCHAR2)
2703 IS
2704 l_api_name VARCHAR2(100) := 'is_complex_work_order()';
2705 BEGIN
2706
2707 x_return_status := 'N';
2708
2709 IF(p_header_id IS NOT NULL) THEN
2710
2711 --Call the PO API to check whether the passed PO is complex work order.
2712 IF (po_complex_work_pvt.is_complex_work_po(p_header_id)) THEN
2713 x_return_status := 'Y';
2714 END IF;
2715 END IF;
2716
2717 EXCEPTION
2718 WHEN OTHERS THEN
2719 x_return_status := fnd_api.g_ret_sts_unexp_error;
2720 fnd_msg_pub.add_exc_msg(g_module_prefix, l_api_name);
2721 END is_complex_work_order;
2722
2723
2724 /*-----------------------------------------------------------------------
2725 * IS_REQ_LINE_CANCELLABLE: checks if a requisition line can be cancelled.
2726 * It is called from 2 places
2727 * 1. Called from api IS_REQ_LINE_CHANGEABLE, with p_origin = 'Y'
2728 * 2. Called from the UI directly, with p_origin set to default (null)
2729 ------------------------------------------------------------------------*/
2730 PROCEDURE is_req_line_cancellable(p_api_version IN NUMBER,
2731 x_return_status OUT NOCOPY VARCHAR2,
2732 p_req_line_id IN NUMBER,
2733 p_origin IN VARCHAR2)
2734 IS
2735 l_api_name VARCHAR2(50) := 'IS_REQ_LINE_CANCELLABLE';
2736 l_progress VARCHAR2(3) := '000';
2737 --bug# 13999194
2738 l_auction_display_number po_requisition_lines_all.auction_display_number%TYPE;
2739 l_auction_line_number NUMBER;
2740 l_reqs_in_pool_flag VARCHAR2(1);
2741 l_source_type_code po_requisition_lines_all.source_type_code%TYPE;
2742 l_return_status VARCHAR2(1);
2743 l_po_header_id NUMBER;
2744 l_po_release_id NUMBER;
2745 l_po_line_id NUMBER;
2746 l_po_line_loc_id NUMBER;
2747 l_po_doc_type VARCHAR2(30);
2748 l_po_doc_subtype VARCHAR2(30);
2749 l_count NUMBER;
2750 l_req_change_pending_flag VARCHAR2(1);
2751 l_agent_id NUMBER;
2752 l_modified_by_agent VARCHAR2(1);
2753 l_req_org_id NUMBER;
2754 l_po_org_id NUMBER;
2755 l_quantity NUMBER;
2756 l_received_quantity NUMBER;
2757 l_billed_quantity NUMBER;
2758 l_amount NUMBER;
2759 l_received_amount NUMBER;
2760 l_billed_amount NUMBER;
2761 l_receipt_required_flag po_line_locations.receipt_required_flag%TYPE;
2762 l_rcv_transaction_exist NUMBER := 0;
2763 l_asn_exist NUMBER := 0;
2764 l_not_delivered NUMBER := 0;
2765 l_dist_not_valid NUMBER := 0;
2766 l_is_on_complex_work_po VARCHAR2(1);
2767 l_transferred_to_oe_flag varchar(1) := null;
2768 l_cancelled varchar(1) :=null;
2769 is_so_cancel varchar2(1):='N';
2770 l_sts varchar2(3);
2771 BEGIN
2772
2773 x_return_status := fnd_api.g_ret_sts_success;
2774 /*
2775 * If called directly from the UI, we will need to make some extra validations,
2776 * which are also included in IS_REQ_LINE_CHANGEABLE.
2777 */
2778 IF (p_origin IS NULL) THEN
2779
2780 SELECT
2781 prla.source_type_code,
2782 prla.auction_display_number,
2783 prla.auction_line_number,
2784 prla.reqs_in_pool_flag,
2785 prla.line_location_id,
2786 prha.change_pending_flag,
2787 nvl(prla.modified_by_agent_flag, 'N'),
2788 prha.transferred_to_oe_flag,
2789 nvl(prla.cancel_flag,'N')
2790 INTO
2791 l_source_type_code,
2792 l_auction_display_number,
2793 l_auction_line_number,
2794 l_reqs_in_pool_flag,
2795 l_po_line_loc_id,
2796 l_req_change_pending_flag,
2797 l_modified_by_agent,
2798 l_transferred_to_oe_flag,
2799 l_cancelled
2800 FROM
2801 po_requisition_lines_all prla,
2802 po_requisition_headers_all prha
2803 WHERE
2804 prla.requisition_line_id = p_req_line_id AND
2805 prla.requisition_header_id = prha.requisition_header_id;
2806
2807
2808 IF (l_cancelled = 'Y' ) THEN
2809
2810 IF (g_fnd_debug = 'Y') THEN
2811 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
2812 fnd_log.string(fnd_log.level_statement,
2813 g_module_prefix || l_api_name,
2814 'Req Line ID:' || p_req_line_id || ' ' ||
2815 'is Already cancelled');
2816 END IF;
2817 END IF;
2818 x_return_status := fnd_api.g_ret_sts_error;
2819 RETURN;
2820 END IF;
2821
2822
2823 IF (l_source_type_code = 'INVENTORY') THEN
2824 IF ( nvl(l_transferred_to_oe_flag,'N') = 'Y' ) THEN
2825
2826 is_SO_line_cancellable(p_api_version =>1.0,
2827 x_return_status =>l_sts,
2828 p_req_line_id =>p_req_line_id,
2829 p_req_header_id =>null,
2830 x_cancellable =>is_so_cancel);
2831
2832 IF (g_fnd_debug = 'Y') THEN
2833 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
2834 fnd_log.string(fnd_log.level_statement,
2835 g_module_prefix || l_api_name,
2836 'Req Line ID:' || p_req_line_id || ' ' ||
2837 'transferred to so ='||is_so_cancel||' status'||l_sts);
2838 END IF;
2839 END IF;
2840 IF( l_sts <> fnd_api.g_ret_sts_success OR ( l_sts = fnd_api.g_ret_sts_success AND is_so_cancel = 'N') )THEN
2841 x_return_status := fnd_api.g_ret_sts_error;
2842 END IF;
2843 Else
2844 is_internal_line_cancellable(1.0, x_return_status, p_req_line_id);
2845 END IF;
2846 END IF;
2847
2848 ELSE
2849
2850 SELECT
2851 prla.line_location_id,
2852 prha.change_pending_flag,
2853 nvl(prla.modified_by_agent_flag, 'N')
2854 INTO
2855 l_po_line_loc_id,
2856 l_req_change_pending_flag,
2857 l_modified_by_agent
2858 FROM
2859 po_requisition_lines_all prla,
2860 po_requisition_headers_all prha
2861 WHERE
2862 prla.requisition_line_id = p_req_line_id AND
2863 prla.requisition_header_id = prha.requisition_header_id;
2864 END IF;
2865
2866 -- If the line is linked to a complex work PO, is not cancellable.
2867 IF(l_po_line_loc_id IS NOT NULL) THEN
2868 is_on_complex_work_order(l_po_line_loc_id, l_is_on_complex_work_po);
2869 IF(l_is_on_complex_work_po = 'Y') THEN
2870 x_return_status := fnd_api.g_ret_sts_error;
2871 END IF;
2872 END IF;
2873
2874 -- Line is placed on PO. Check if the req is in change pending status
2875 IF (l_req_change_pending_flag = 'Y' AND l_po_line_loc_id IS NOT NULL) THEN
2876 x_return_status := fnd_api.g_ret_sts_error;
2877 END IF;
2878
2879 IF (l_modified_by_agent = 'Y') THEN
2880 x_return_status := fnd_api.g_ret_sts_error;
2881 END IF;
2882
2883 l_progress := '001';
2884
2885 /*
2886 * Final Validation to check if a line can be cancelled will be done by
2887 * calling PO Cancel API to check if the corresponding shipment can be cancelled
2888 */
2889 IF (x_return_status = fnd_api.g_ret_sts_success AND l_po_line_loc_id IS NOT NULL) THEN
2890 IF (p_origin IS NULL) THEN
2891 SELECT COUNT(DISTINCT nvl(prda.requisition_line_id, - 1))
2892 INTO l_count
2893 FROM
2894 po_req_distributions_all prda,
2895 po_distributions_all pda,
2896 po_requisition_lines_all prla
2897 WHERE pda.line_location_id = prla.line_location_id
2898 AND prla.requisition_line_id = p_req_line_id
2899 AND pda.req_distribution_id = prda.distribution_id(+ );
2900
2901 IF (l_count > 1) THEN
2902 x_return_status := fnd_api.g_ret_sts_error;
2903 RETURN;
2904 END IF;
2905 END IF;
2906
2907 l_progress := '002';
2908
2909 SELECT
2910 pha.po_header_id,
2911 pla.po_line_id,
2912 plla.po_release_id,
2913 plla.line_location_id,
2914 pha.agent_id,
2915 prla.quantity - nvl(prla.quantity_cancelled, 0),
2916 plla.quantity_received,
2917 plla.quantity_billed,
2918 prla.amount,
2919 plla.amount_received,
2920 plla.amount_billed,
2921 plla.receipt_required_flag
2922 INTO
2923 l_po_header_id,
2924 l_po_line_id,
2925 l_po_release_id,
2926 l_po_line_loc_id,
2927 l_agent_id,
2928 l_quantity,
2929 l_received_quantity,
2930 l_billed_quantity,
2931 l_amount,
2932 l_received_amount,
2933 l_billed_amount,
2934 l_receipt_required_flag
2935 FROM
2936 po_headers_all pha,
2937 po_lines_all pla,
2938 po_line_locations_all plla,
2939 po_requisition_lines_all prla
2940 WHERE
2941 prla.requisition_line_id = p_req_line_id
2942 AND prla.line_location_id = plla.line_location_id
2943 AND plla.po_line_id = pla.po_line_id
2944 AND pla.po_header_id = pha.po_header_id;
2945
2946 l_progress := '003';
2947
2948 -- Bug : 3578699. If req line is fully received, user cannot cancel
2949 IF (l_received_quantity >= l_quantity OR
2950 l_received_amount >= l_amount) THEN
2951
2952 IF (g_fnd_debug = 'Y') THEN
2953 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
2954 fnd_log.string(fnd_log.level_statement,
2955 g_module_prefix || l_api_name,
2956 'Req Line ID:' || p_req_line_id || ' ' ||
2957 'Shipment Fully Received');
2958 END IF;
2959 END IF;
2960
2961 x_return_status := fnd_api.g_ret_sts_error;
2962 RETURN;
2963 END IF;
2964
2965 l_progress := '004';
2966
2967 -- Fully Billed Check (BUG: 3658317)
2968 IF (l_billed_quantity > l_quantity OR
2969 l_billed_amount > l_amount) THEN
2970
2971 IF (g_fnd_debug = 'Y') THEN
2972 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
2973 fnd_log.string(fnd_log.level_statement,
2974 g_module_prefix || l_api_name,
2975 'Req Line ID:' || p_req_line_id || ' ' ||
2976 'Shipment Fully Billed');
2977 END IF;
2978 END IF;
2979
2980 x_return_status := fnd_api.g_ret_sts_error;
2981 RETURN;
2982 END IF;
2983
2984 l_progress := '005';
2985
2986 -- Over Billed Check (If Match Approval Level is set to 3-way or 4-way only, this check is done)
2987 IF ((l_quantity >= l_billed_quantity AND
2988 nvl(l_receipt_required_flag, 'Y') <> 'N' AND
2989 l_billed_quantity > l_received_quantity) OR
2990 (l_amount >= l_billed_amount AND
2991 nvl(l_receipt_required_flag, 'Y') <> 'N' AND
2992 l_billed_amount > l_received_amount)) THEN
2993
2994 IF (g_fnd_debug = 'Y') THEN
2995 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
2996 fnd_log.string(fnd_log.level_statement,
2997 g_module_prefix || l_api_name,
2998 'Req Line ID:' || p_req_line_id || ' ' ||
2999 'Shipment Over Billed');
3000 END IF;
3001 END IF;
3002
3003 x_return_status := fnd_api.g_ret_sts_error;
3004 RETURN;
3005 END IF;
3006
3007 l_progress := '006';
3008
3009 -- Check for any Receiving Transaction exists
3010 BEGIN
3011 SELECT 1
3012 INTO l_rcv_transaction_exist
3013 FROM rcv_transactions_interface
3014 WHERE
3015 processing_status_code = 'PENDING' AND
3016 po_line_location_id = l_po_line_loc_id;
3017
3018 IF (l_rcv_transaction_exist = 1) THEN
3019
3020 IF (g_fnd_debug = 'Y') THEN
3021 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
3022 fnd_log.string(fnd_log.level_statement,
3023 g_module_prefix || l_api_name,
3024 'Req Line ID:' || p_req_line_id || ' ' ||
3025 'RCV transaction exists for Shipment');
3026 END IF;
3027 END IF;
3028
3029 x_return_status := fnd_api.g_ret_sts_error;
3030 RETURN;
3031 END IF;
3032
3033 EXCEPTION
3034 WHEN no_data_found THEN
3035 NULL;
3036 END;
3037
3038 l_progress := '007';
3039
3040 -- Check for ASN not being fully received
3041 BEGIN
3042 SELECT 1
3043 INTO l_asn_exist
3044 FROM rcv_shipment_lines
3045 WHERE
3046 po_line_location_id = l_po_line_loc_id AND
3047 nvl(quantity_shipped, 0) > nvl(quantity_received, 0) AND
3048 nvl(asn_line_flag, 'N') = 'Y' AND
3049 nvl(shipment_line_status_code, 'EXPECTED') <> 'CANCELLED';
3050
3051 IF (l_asn_exist = 1) THEN
3052
3053 IF (g_fnd_debug = 'Y') THEN
3054 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
3055 fnd_log.string(fnd_log.level_statement,
3056 g_module_prefix || l_api_name,
3057 'Req Line ID:' || p_req_line_id || ' ' ||
3058 'ASN not Fully Received');
3059 END IF;
3060 END IF;
3061
3062 x_return_status := fnd_api.g_ret_sts_error;
3063 RETURN;
3064 END IF;
3065
3066 EXCEPTION
3067 WHEN no_data_found THEN
3068 NULL;
3069 END;
3070
3071 l_progress := '008';
3072
3073 -- Check if shipment is received but not delivered
3074 BEGIN
3075
3076 SELECT 1
3077 INTO l_not_delivered
3078 FROM po_line_locations_all plla
3079 WHERE
3080 plla.line_location_id = l_po_line_loc_id AND
3081 ((nvl(plla.quantity_received, 0) >
3082 (SELECT SUM(nvl(pod.quantity_delivered, 0))
3083 FROM po_distributions pod
3084 WHERE pod.line_location_id = plla.line_location_id)) OR
3085 (nvl(plla.amount_received, 0) >
3086 (SELECT SUM(nvl(pod.amount_delivered, 0))
3087 FROM po_distributions pod
3088 WHERE pod.line_location_id = plla.line_location_id)));
3089
3090 IF (l_not_delivered = 1) THEN
3091
3092 IF (g_fnd_debug = 'Y') THEN
3093 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
3094 fnd_log.string(fnd_log.level_statement,
3095 g_module_prefix || l_api_name,
3096 'Req Line ID:' || p_req_line_id || ' ' ||
3097 'Shipment Received but not Delivered');
3098 END IF;
3099 END IF;
3100
3101 x_return_status := fnd_api.g_ret_sts_error;
3102 RETURN;
3103 END IF;
3104
3105 EXCEPTION
3106 WHEN no_data_found THEN
3107 NULL;
3108 END;
3109
3110 l_progress := '009';
3111
3112 -- PO distribution checks
3113 BEGIN
3114
3115 SELECT 1
3116 INTO l_dist_not_valid
3117 FROM
3118 po_line_locations_all poll,
3119 po_distributions_all pod,
3120 gl_code_combinations gcc
3121 WHERE
3122 poll.line_location_id = l_po_line_loc_id AND
3123 pod.line_location_id = poll.line_location_id AND
3124 gcc.code_combination_id = pod.code_combination_id AND
3125 ((trunc(SYSDATE) NOT BETWEEN
3126 nvl(gcc.start_date_active, trunc(SYSDATE) - 1) AND
3127 nvl(gcc.end_date_active, trunc(SYSDATE) + 1)
3128 ) OR
3129 pod.quantity_billed > pod.quantity_ordered OR -- fully billed
3130 pod.quantity_delivered > pod.quantity_ordered OR -- over delivered
3131 (pod.quantity_ordered >= pod.quantity_billed AND -- over billed
3132 nvl(poll.receipt_required_flag, 'Y') <> 'N' AND
3133 pod.quantity_billed > pod.quantity_delivered) OR
3134 pod.amount_billed > pod.amount_ordered OR
3135 pod.amount_delivered > pod.amount_ordered OR
3136 (pod.amount_ordered >= pod.amount_billed AND
3137 nvl(poll.receipt_required_flag, 'Y') <> 'N' AND
3138 pod.amount_billed > pod.amount_delivered));
3139
3140 IF (l_dist_not_valid = 1) THEN
3141
3142 IF (g_fnd_debug = 'Y') THEN
3143 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
3144 fnd_log.string(fnd_log.level_statement,
3145 g_module_prefix || l_api_name,
3146 'Req Line ID:' || p_req_line_id || ' ' ||
3147 'Distribution Checks Failed');
3148 END IF;
3149 END IF;
3150
3151 x_return_status := fnd_api.g_ret_sts_error;
3152 RETURN;
3153 END IF;
3154
3155 EXCEPTION
3156 WHEN no_data_found THEN
3157 NULL;
3158 END;
3159
3160 l_progress := '010';
3161
3162 IF (l_po_release_id IS NULL) THEN
3163 l_po_doc_type := 'PO';
3164 l_po_doc_subtype := 'STANDARD';
3165
3166 -- get org id of the PO
3167 SELECT org_id
3168 INTO l_po_org_id
3169 FROM po_headers_all
3170 WHERE po_header_id = l_po_header_id;
3171 ELSE
3172 l_po_doc_type := 'RELEASE';
3173 l_po_doc_subtype := 'BLANKET';
3174 l_po_line_id := NULL;
3175
3176 -- select org id of the release
3177 SELECT agent_id, org_id
3178 INTO l_agent_id, l_po_org_id
3179 FROM po_releases_all
3180 WHERE po_release_id = l_po_release_id;
3181 END IF;
3182
3183 l_progress := '011';
3184
3185 -- save current org id
3186 l_req_org_id := mo_global.get_current_org_id();
3187
3188 -- Set the org context before calling the cancel api
3189 po_moac_utils_pvt.set_org_context(l_po_org_id) ; -- <R12 MOAC>
3190
3191 l_progress := '012';
3192
3193 po_document_control_grp.check_control_action(
3194 p_api_version => 1.0,
3195 p_init_msg_list => fnd_api.g_true,
3196 x_return_status => l_return_status,
3197 p_doc_type => l_po_doc_type,
3198 p_doc_subtype => l_po_doc_subtype,
3199 p_doc_id => l_po_header_id,
3200 p_doc_num => NULL,
3201 p_release_id => l_po_release_id,
3202 p_release_num => NULL,
3203 p_doc_line_id => l_po_line_id,
3204 p_doc_line_num => NULL,
3205 p_doc_line_loc_id => l_po_line_loc_id,
3206 p_doc_shipment_num => NULL,
3207 p_action => 'CANCEL');
3208
3209 l_progress := '013';
3210
3211 -- set org context to the original value
3212 po_moac_utils_pvt.set_org_context(l_req_org_id) ; -- <R12 MOAC>
3213
3214 IF (g_fnd_debug = 'Y') THEN
3215 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
3216 fnd_log.string(fnd_log.level_statement,
3217 g_module_prefix || l_api_name,
3218 'PO_Document_Control_GRP.check_control_action result:' || l_return_status);
3219 END IF;
3220 END IF;
3221
3222 IF (l_return_status = fnd_api.g_ret_sts_success) THEN
3223 x_return_status := fnd_api.g_ret_sts_success;
3224 ELSE
3225 x_return_status := fnd_api.g_ret_sts_error;
3226 END IF;
3227
3228 END IF;
3229 EXCEPTION WHEN OTHERS THEN
3230 x_return_status := fnd_api.g_ret_sts_unexp_error;
3231 IF (g_fnd_debug = 'Y') THEN
3232 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
3233 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
3234 l_api_name || '.others_exception',
3235 p_req_line_id || '*' || l_progress || ':' || SQLERRM);
3236 END IF;
3237 END IF;
3238 END is_req_line_cancellable;
3239
3240 /*--------------------------------------------------------------
3241 * IS_REQ_LINE_CHANGEABLE: For a particular Requisition line,
3242 * this API checks if the line be changed/cancelled, or if price,
3243 * date, and quantity associated with that the line can be changed.
3244 * Called Directly from UI, per req line.
3245 ----------------------------------------------------------------*/
3246 PROCEDURE is_req_line_changeable(p_api_version IN NUMBER,
3247 x_return_status OUT NOCOPY VARCHAR2,
3248 p_req_line_id IN NUMBER,
3249 p_price_changeable_flag OUT NOCOPY VARCHAR2,
3250 p_date_changeable_flag OUT NOCOPY VARCHAR2,
3251 p_qty_changeable_flag OUT NOCOPY VARCHAR2,
3252 p_start_date_changeable_flag OUT NOCOPY VARCHAR2,
3253 p_end_date_changeable_flag OUT NOCOPY VARCHAR2,
3254 p_amount_changeable_flag OUT NOCOPY VARCHAR2,
3255 p_cancellable_flag OUT NOCOPY VARCHAR2)
3256 IS
3257 l_api_name VARCHAR2(50) := 'IS_REQ_LINE_CHANGEABLE';
3258 l_progress VARCHAR2(100) := '000';
3259 l_line_changeable_flag VARCHAR2(1);
3260 l_line_loc_id NUMBER;
3261 l_source_type_code po_requisition_lines_all.source_type_code%TYPE;
3262 l_auction_display_number po_requisition_lines_all.auction_display_number%TYPE;
3263 l_auction_line_number NUMBER;
3264 l_reqs_in_pool_flag po_requisition_lines_all.reqs_in_pool_flag%TYPE;
3265 l_authorization_status po_headers_all.authorization_status%TYPE;
3266 l_frozen_flag VARCHAR2(1);
3267 l_closed_code po_headers_all.closed_code%TYPE;
3268 l_cancel_flag po_headers_all.cancel_flag%TYPE;
3269 l_catalog_type po_requisition_lines_all.catalog_type%TYPE;
3270 l_allow_price_override_flag po_lines_all.allow_price_override_flag%TYPE;
3271 l_accrue_on_receipt_flag po_line_locations_all.accrue_on_receipt_flag%TYPE;
3272 l_qty_received NUMBER;
3273 l_qty_billed NUMBER;
3274 l_count NUMBER;
3275 l_release_id NUMBER;
3276 l_return_status VARCHAR2(1);
3277 l_line_type po_line_types.purchase_basis%TYPE;
3278 l_global_agreement_flag po_headers_all.global_agreement_flag%TYPE;
3279 l_order_type_lookup_code po_requisition_lines_all.order_type_lookup_code%TYPE ;
3280 l_po_header_id po_headers_all.po_header_id%TYPE;
3281 l_template_id po_requisition_lines_all.noncat_template_id%TYPE;
3282 l_price_editable_flag por_noncat_templates_all_b.price_editable_flag%TYPE;
3283 l_amount_editable_flag por_noncat_templates_all_b.amount_editable_flag%TYPE;
3284 -- added for retroactive pricing checks
3285 l_retropricing VARCHAR2(20) := '';
3286 l_amount_based_service_line BOOLEAN := FALSE;
3287 l_destination_type_code po_requisition_lines_all.destination_type_code%TYPE;
3288 l_is_on_complex_work_po VARCHAR2(1);
3289 l_transferred_to_oe_flag varchar2(1);
3290 l_price_updateable varchar2(1);
3291 BEGIN
3292
3293
3294 x_return_status := fnd_api.g_ret_sts_success;
3295 l_line_changeable_flag := 'Y';
3296 p_price_changeable_flag := 'Y';
3297 p_date_changeable_flag := 'Y';
3298 p_qty_changeable_flag := 'Y';
3299 p_start_date_changeable_flag := 'Y';
3300 p_end_date_changeable_flag := 'Y';
3301 p_amount_changeable_flag := 'Y';
3302 p_cancellable_flag := 'Y';
3303
3304 l_progress := '000';
3305
3306 l_retropricing := fnd_profile.value('PO_ALLOW_RETROPRICING_OF_PO');
3307
3308 SELECT
3309 prla.purchase_basis,
3310 prla.line_location_id,
3311 prla.source_type_code,
3312 prla.auction_display_number,
3313 prla.auction_line_number,
3314 prla.reqs_in_pool_flag,
3315 nvl(prla.catalog_type,' '),
3316 prla.noncat_template_id,
3317 prla.destination_type_code,
3318 prha.transferred_to_oe_flag
3319 INTO
3320 l_line_type,
3321 l_line_loc_id,
3322 l_source_type_code,
3323 l_auction_display_number,
3324 l_auction_line_number,
3325 l_reqs_in_pool_flag,
3326 l_catalog_type,
3327 l_template_id,
3328 l_destination_type_code,
3329 l_transferred_to_oe_flag
3330 FROM
3331 po_requisition_lines_all prla,
3332 po_requisition_headers_all prha
3333 WHERE
3334 prla.requisition_line_id = p_req_line_id AND
3335 prla.requisition_header_id = prha.requisition_header_id;
3336
3337 -- for non catalog items with templates amount and price
3338 -- update depends on template definition
3339 IF (l_template_id IS NOT NULL) THEN
3340 BEGIN
3341 SELECT price_editable_flag, amount_editable_flag
3342 INTO l_price_editable_flag, l_amount_editable_flag
3343 FROM por_noncat_templates_all_b
3344 WHERE template_id = l_template_id;
3345
3346 exception when NO_DATA_FOUND then
3347 l_price_editable_flag:='Y';
3348 l_amount_editable_flag:='Y';
3349 end;
3350
3351 IF (l_price_editable_flag = 'N') THEN
3352 p_price_changeable_flag := 'N';
3353 END IF;
3354
3355 IF (l_amount_editable_flag = 'N') THEN
3356 p_amount_changeable_flag := 'N';
3357 END IF;
3358
3359 END IF;
3360
3361 -- If Req is linked to complex work.. RCO can not be done.
3362 is_on_complex_work_order(l_line_loc_id, l_is_on_complex_work_po);
3363
3364 IF(l_destination_type_code = 'EXPENSE' AND l_is_on_complex_work_po = 'Y') THEN
3365 l_line_changeable_flag := 'N';
3366 p_price_changeable_flag := 'N';
3367 p_date_changeable_flag := 'N';
3368 p_qty_changeable_flag := 'N';
3369 p_start_date_changeable_flag := 'N';
3370 p_end_date_changeable_flag := 'N';
3371 p_amount_changeable_flag := 'N';
3372 p_cancellable_flag := 'N';
3373 END IF;
3374
3375 IF(l_line_changeable_flag = 'Y') THEN
3376 IF (l_line_type = 'GOODS') THEN
3377 IF (l_template_id IS NULL) THEN
3378 p_amount_changeable_flag := 'N';
3379 END IF;
3380 p_start_date_changeable_flag := 'N';
3381 p_end_date_changeable_flag := 'N';
3382
3383 ELSIF(l_line_type = 'TEMP LABOR' OR l_line_type = 'SERVICES') THEN
3384
3385 p_qty_changeable_flag := 'N';
3386 p_price_changeable_flag := 'N';
3387 p_date_changeable_flag := 'N';
3388 p_start_date_changeable_flag := 'Y';
3389 p_end_date_changeable_flag := 'Y';
3390
3391 SELECT order_type_lookup_code
3392 INTO l_order_type_lookup_code
3393 FROM po_requisition_lines_all
3394 WHERE requisition_line_id = p_req_line_id;
3395
3396 IF (l_line_type = 'SERVICES') THEN
3397 p_date_changeable_flag := 'Y';
3398 p_start_date_changeable_flag := 'N';
3399 p_end_date_changeable_flag := 'N';
3400
3401 -- checking order type lookup code for amount based service lines
3402 IF (l_order_type_lookup_code <> 'FIXED PRICE') THEN
3403 p_qty_changeable_flag := 'Y';
3404 p_amount_changeable_flag := 'N';
3405 l_amount_based_service_line := TRUE;
3406 END IF;
3407
3408 END IF;
3409
3410 IF(l_line_type = 'TEMP LABOR' AND l_order_type_lookup_code = 'RATE') THEN
3411 -- for rate-based temp labor line, the budget amount can be modified
3412 p_amount_changeable_flag := 'Y';
3413
3414 ELSIF (NOT l_amount_based_service_line) THEN
3415 -- for fixed price temp labor line and fixed price services line,
3416 -- if there is a backing GBPA,
3417 -- if the price override allowed flag is Y, the labor amount can be changed
3418 -- if the price override allowed flag is N, the labor amount can not be changed.
3419 -- if there is not a backing GBPA, the labor anount can be changed
3420
3421 SELECT pha.global_agreement_flag, pha.po_header_id
3422 INTO l_global_agreement_flag, l_po_header_id
3423 FROM po_headers_all pha,
3424 po_requisition_lines_all prla
3425 WHERE pha.po_header_id (+ ) = prla.blanket_po_header_id
3426 AND prla.requisition_line_id = p_req_line_id;
3427
3428 IF(l_global_agreement_flag = 'Y') THEN
3429 BEGIN
3430 SELECT pla.allow_price_override_flag
3431 INTO l_allow_price_override_flag
3432 FROM po_requisition_lines_all prl,
3433 po_headers_all pha,
3434 po_lines_all pla
3435 WHERE pha.po_header_id = l_po_header_id
3436 AND pla.po_header_id = pha.po_header_id
3437 AND prl.blanket_po_line_num = pla.line_num
3438 AND prl.requisition_line_id = p_req_line_id;
3439
3440 -- in GCPA case, there is no po line associated with po header
3441 -- above query will result in no_data_found exception. catch GCPA case in exception block
3442
3443 IF(l_allow_price_override_flag = 'Y') THEN
3444 p_amount_changeable_flag := 'Y';
3445 ELSE
3446 p_amount_changeable_flag := 'N';
3447 END IF;
3448
3449 -- in GCPA case, user is allowed to change amount
3450
3451 EXCEPTION
3452 WHEN no_data_found THEN
3453 p_amount_changeable_flag := 'Y';
3454 END;
3455
3456
3457 ELSE
3458 p_amount_changeable_flag := 'Y';
3459 END IF;
3460 END IF;
3461
3462 END IF;
3463
3464 /*
3465 **Validation #1,#2,#3,#7 in DLD
3466 */
3467
3468
3469 l_progress := '001';
3470
3471 --In the following validation,
3472 --#1-#6 are shared by different type of requisition lines: GOODS, TEMP LABOR, SERVICES
3473 --#7-#11 are only for GOODS
3474 -- bug 13983258: able to edit price for catalog items based on profile
3475 l_price_updateable := fnd_profile.value('POR_ALLOW_PRICE_UPDATE');
3476 --Is there an internal order associated with line?(Validation #2 in DLD)
3477 IF (l_source_type_code = 'INVENTORY') THEN
3478 l_line_changeable_flag := 'N';
3479
3480 IF ( nvl(l_transferred_to_oe_flag,'N') = 'Y' ) THEN
3481 l_return_status := FND_API.G_RET_STS_ERROR;
3482 Else
3483 is_internal_line_cancellable(1.0, l_return_status, p_req_line_id);
3484 END IF;
3485
3486 IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
3487 p_cancellable_flag := 'N';
3488 END IF;
3489
3490 --Is there any PO associated with line?(Validation #1 in DLD)
3491 ELSIF(l_line_loc_id IS NULL) THEN
3492 l_line_changeable_flag := 'N';
3493 --Price change is allowed ONLY on non-catalog items(Validation #7 in DLD)
3494 ELSIF(l_line_type = 'GOODS' AND l_catalog_type <> 'NONCATALOG' AND l_price_updateable <> 'Y' )THEN
3495 p_price_changeable_flag := 'N';
3496 END IF;
3497 END IF;-- end of l_line_changeable_flag='Y' check
3498
3499 l_progress := '002';
3500
3501 /*
3502 **Validation #4,#5,#8,#10,#11 in DLD
3503 */
3504 IF(l_line_changeable_flag = 'Y') THEN
3505
3506 SELECT po_release_id INTO l_release_id
3507 FROM po_line_locations_all
3508 WHERE line_location_id = l_line_loc_id;
3509
3510 IF(l_release_id IS NULL) THEN
3511
3512
3513 SELECT
3514 nvl(pha.authorization_status,' '),
3515 nvl(plla.closed_code, 'OPEN'),
3516 nvl(plla.cancel_flag, 'N'),
3517 --pla.allow_price_override_flag,
3518 plla.accrue_on_receipt_flag,
3519 plla.quantity_received,
3520 plla.quantity_billed,
3521 nvl(pha.frozen_flag, 'N')
3522 INTO
3523 l_authorization_status ,
3524 l_closed_code,
3525 l_cancel_flag,
3526 --l_allow_price_override_flag,
3527 l_accrue_on_receipt_flag,
3528 l_qty_received,
3529 l_qty_billed,
3530 l_frozen_flag
3531 FROM
3532 po_headers_all pha,
3533 po_lines_all pla,
3534 po_line_locations_all plla,
3535 po_requisition_lines_all prla
3536 WHERE pha.po_header_id = plla.po_header_id
3537 AND pla.po_line_id = plla.po_line_id
3538 AND plla.line_location_id = prla.line_location_id
3539 AND prla.requisition_line_id = p_req_line_id;
3540
3541 ELSE
3542
3543 SELECT
3544 nvl(pra.authorization_status,' '),
3545 nvl(plla.closed_code, 'OPEN'),
3546 nvl(plla.cancel_flag, 'N'),
3547 --pla.allow_price_override_flag,
3548 plla.accrue_on_receipt_flag,
3549 plla.quantity_received,
3550 plla.quantity_billed,
3551 nvl(pra.frozen_flag,' ')
3552 INTO
3553 l_authorization_status ,
3554 l_closed_code,
3555 l_cancel_flag,
3556 --l_allow_price_override_flag,
3557 l_accrue_on_receipt_flag,
3558 l_qty_received,
3559 l_qty_billed,
3560 l_frozen_flag
3561 FROM
3562 po_lines_all pla,
3563 po_line_locations_all plla,
3564 po_requisition_lines_all prla,
3565 po_releases_all pra
3566 WHERE pla.po_line_id = plla.po_line_id
3567 AND plla.line_location_id = prla.line_location_id
3568 AND prla.requisition_line_id = p_req_line_id
3569 AND pra.po_release_id = plla.po_release_id;
3570
3571
3572 END IF;
3573
3574 --Bug:16423039 Consider the override flag on GBPA/BPA in RCO,NOT SPO/BPA Release
3575 SELECT DECODE(prla.document_type_code,'BLANKET',NVL(pla.allow_price_override_flag, 'N'),'Y')
3576 INTO l_allow_price_override_flag
3577 FROM po_lines_all pla,
3578 po_requisition_lines_all prla
3579 WHERE pla.line_num(+) = prla.blanket_po_line_num
3580 AND pla.po_header_id(+) = prla.blanket_po_header_id
3581 and prla.requisition_line_id = p_req_line_id;
3582
3583 l_progress := '003';
3584 --Check authorization status, closed code, cancel flag (Validation #4 and #5 in DLD)
3585 IF(l_frozen_flag = 'Y' OR l_authorization_status NOT IN('APPROVED') OR l_closed_code IN ('CLOSED','FINALLY CLOSED') OR l_cancel_flag <> 'N') THEN
3586 l_line_changeable_flag := 'N';
3587 p_cancellable_flag := 'N';
3588
3589 ELSIF (l_closed_code IN ('CLOSED FOR INVOICE', 'CLOSED FOR RECEIVING') AND l_retropricing <> 'ALL_RELEASES') THEN
3590 p_price_changeable_flag := 'N';
3591
3592 --Check for price override flag (Validation #8)
3593 ELSIF(l_line_type = 'GOODS' AND l_allow_price_override_flag = 'N') THEN
3594 p_price_changeable_flag := 'N';
3595
3596 --Check accrue on receipt flag (Validation #10)
3597 ELSIF(l_line_type = 'GOODS' AND l_accrue_on_receipt_flag = 'Y' AND
3598 l_retropricing <> 'ALL_RELEASES') THEN
3599 p_price_changeable_flag := 'N';
3600
3601 --If PO line has been partially received or invoiced (Validation #11)
3602 ELSIF(l_line_type = 'GOODS' AND l_retropricing <> 'ALL_RELEASES' AND
3603 (l_qty_received > 0 OR l_qty_billed >0)) THEN
3604 p_price_changeable_flag := 'N';
3605 END IF;
3606
3607
3608
3609 /*
3610 * Valiation #6: Checking if p_req_line_id corresponds to PO Shipment PS1, and PS1 has multiple PO distributions, which correspond to
3611 * multiple req distributions of multiple req lines or does not correspond to any req distributions:
3612 * In this case, no change, no cancel
3613 */
3614
3615 IF(l_line_changeable_flag = 'Y') THEN
3616 l_progress := '004';
3617 SELECT COUNT(DISTINCT nvl(prda.requisition_line_id, - 1))
3618 INTO l_count
3619 FROM
3620 po_req_distributions_all prda,
3621 po_distributions_all pda,
3622 po_requisition_lines_all prla
3623 WHERE pda.line_location_id = prla.line_location_id
3624 AND prla.requisition_line_id = p_req_line_id
3625 AND pda.req_distribution_id = prda.distribution_id(+ );
3626
3627 IF(l_count > 1) THEN
3628 l_line_changeable_flag := 'N';
3629 p_cancellable_flag := 'N';
3630 END IF;
3631 END IF;
3632
3633 IF(l_line_changeable_flag = 'N') THEN
3634 p_price_changeable_flag := 'N';
3635 p_date_changeable_flag := 'N';
3636 p_qty_changeable_flag := 'N';
3637 p_start_date_changeable_flag := 'N';
3638 p_end_date_changeable_flag := 'N';
3639 p_amount_changeable_flag := 'N';
3640 END IF;
3641
3642 /*
3643 * Extending Validation #6, if a req line correspond to the line of a Standard PO, its price can only be changed if
3644 * the req line is associated with a PO Shipment, which is the only shipment of its parent Line.
3645 */
3646 IF(l_release_id IS NULL AND p_price_changeable_flag = 'Y') THEN
3647 l_progress := '005';
3648 SELECT COUNT(1)
3649 INTO l_count
3650 FROM
3651 po_requisition_lines_all prla,
3652 po_line_locations_all plla,
3653 po_line_locations_all plla2
3654 WHERE plla.line_location_id = prla.line_location_id
3655 AND prla.requisition_line_id = p_req_line_id
3656 AND plla2.po_line_id = plla.po_line_id;
3657
3658 IF(l_count > 1) THEN
3659 p_price_changeable_flag := 'N';
3660
3661 END IF;
3662
3663 END IF;
3664
3665
3666 END IF;
3667
3668
3669 l_progress := '007';
3670
3671 /*
3672 * At this point, if cancel_flag = 'Y', we will need to call another API which further checks if the line
3673 * can be cancelled.
3674 */
3675 IF(p_cancellable_flag = 'Y') THEN
3676 is_req_line_cancellable(1.0, l_return_status, p_req_line_id, 'Y');
3677 IF(l_return_status = fnd_api.g_ret_sts_error) THEN
3678 p_cancellable_flag := 'N';
3679 END IF;
3680 END IF;
3681
3682 EXCEPTION WHEN OTHERS THEN
3683 IF g_fnd_debug = 'Y' THEN
3684 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
3685 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
3686 l_api_name || '.others_exception',
3687 p_req_line_id || '*' || l_progress || ':' || SQLERRM);
3688 END IF;
3689 END IF;
3690 x_return_status := fnd_api.g_ret_sts_unexp_error;
3691 END is_req_line_changeable;
3692
3693 /*-------------------------------------------------------------------------------------------------
3694 *This API is called directly from the UI. It will have PLSQL tables as input, which contain change/cancel requests
3695 *1. Validate the requests
3696 *2. If ALL valid, same them into PO_CHANGE_REQUESTS table
3697 *x_return_status = FND_API.G_RET_STS_SUCCESS => Everything is Valid, and records are saved into change table
3698 * FND_API.G_RET_STS_ERROR => Caught Errors, thus no records are saved into change table
3699 * FND_API.G_RET_STS_UNEXP_ERROR => Unexpected Errors Occur in the API
3700 *x_retMsg will indicate details/location of errors.
3701 ---------------------------------------------------------------------------------------------------*/
3702 PROCEDURE save_reqchange(p_api_version IN NUMBER,
3703 x_return_status OUT NOCOPY VARCHAR2,
3704 p_req_hdr_id IN NUMBER,
3705 p_change_table IN po_req_change_table,
3706 p_cancel_table IN po_req_cancel_table,
3707 p_change_request_group_id OUT NOCOPY NUMBER,
3708 x_retmsg OUT NOCOPY VARCHAR2,
3709 x_errtable OUT NOCOPY po_req_change_err_table)
3710 IS
3711 l_api_name VARCHAR2(50) := 'Save_ReqChange';
3712 l_req_change_table change_tbl_type;
3713 l_dummy NUMBER;
3714 y NUMBER := 1;
3715 l_change_result VARCHAR2(1) := fnd_api.g_ret_sts_success;
3716 l_cancel_result VARCHAR2(1);
3717 l_err_line_id_tbl po_tbl_number;
3718 l_err_line_num_tbl po_tbl_number;
3719 l_err_dist_id_tbl po_tbl_number;
3720 l_err_dist_num_tbl po_tbl_number;
3721 l_err_error_attr_tbl po_tbl_varchar30;
3722 l_err_msg_count_tbl po_tbl_number;
3723 l_err_msg_data_tbl po_tbl_varchar2000;
3724 l_irc_status VARCHAR2(1);
3725 l_irc_err_msg VARCHAR2(2000);
3726 l_catch_exception EXCEPTION;
3727 l_req_dist_id NUMBER;
3728 l_lineqty_status VARCHAR2(1);
3729 l_lineqty_msg VARCHAR2(2000);
3730
3731
3732 BEGIN
3733
3734 DELETE FROM po_change_requests
3735 WHERE document_header_id = p_req_hdr_id
3736 AND request_status = 'SYSTEMSAVE'
3737 AND initiator = 'REQUESTER';
3738
3739
3740
3741 x_retmsg := 'SRCH000';
3742
3743 IF(p_change_table IS NOT NULL) THEN
3744 --Input Change Table is p_change_table, which is a table of objects. The following "for" loop
3745 --Copy the data from p_change_table to l_req_change_table, which is a table of record
3746 FOR x IN 1..p_change_table.req_line_id.count
3747 LOOP
3748 /* Start Date, End Date and Amount changes
3749 Check if there is any change in start date or end date or amount
3750 Set DOCUMENT_DISTRIBUTION_ID only when there is any change in amount
3751 Handled Amount and Need By Date Combination for Fixed Price Lines*/
3752 IF((p_change_table.need_by(x) IS NOT NULL AND p_change_table.amount(x) IS NOT NULL)
3753 OR p_change_table.start_date(x) IS NOT NULL
3754 OR p_change_table.end_date(x) IS NOT NULL
3755 OR p_change_table.amount(x) IS NOT NULL) THEN
3756 IF(p_change_table.start_date(x) IS NOT NULL) THEN
3757 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3758 l_req_change_table(y).new_start_date := p_change_table.start_date(x);
3759 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3760 y := y + 1;
3761 END IF;
3762 IF(p_change_table.end_date(x) IS NOT NULL) THEN
3763 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3764 l_req_change_table(y).new_end_date := p_change_table.end_date(x);
3765 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3766 y := y + 1;
3767 END IF;
3768 IF(p_change_table.amount(x) IS NOT NULL) THEN
3769 IF(p_change_table.req_dist_id(x) IS NULL) THEN
3770 BEGIN
3771 SELECT distribution_id
3772 INTO l_req_dist_id
3773 FROM po_req_distributions_all
3774 WHERE requisition_line_id = p_change_table.req_line_id(x);
3775 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3776 l_req_change_table(y).document_distribution_id := l_req_dist_id;
3777 l_req_change_table(y).new_budget_amount := p_change_table.amount(x);
3778 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3779 y := y + 1;
3780 EXCEPTION
3781 WHEN OTHERS THEN
3782 NULL;
3783 END;
3784 ELSE
3785 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3786 l_req_change_table(y).document_distribution_id := p_change_table.req_dist_id(x);
3787 l_req_change_table(y).new_budget_amount := p_change_table.amount(x);
3788 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3789 y := y + 1;
3790 END IF;
3791 IF (p_change_table.need_by(x) IS NOT NULL) THEN
3792 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3793 l_req_change_table(y).new_date := p_change_table.need_by(x);
3794 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3795 y := y + 1;
3796 END IF;
3797 END IF;
3798 /* Price, Need By, Quantity changes
3799 Check if there is any change in price or need_by or quantity
3800 Set DOCUMENT_DISTRIBUTION_ID only when there is any change in quantity */
3801 ELSIF(p_change_table.price(x) IS NOT NULL
3802 OR p_change_table.need_by(x) IS NOT NULL
3803 OR p_change_table.quantity(x) IS NOT NULL) THEN
3804 IF(p_change_table.need_by(x) IS NOT NULL) THEN
3805 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3806 l_req_change_table(y).new_date := p_change_table.need_by(x);
3807 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3808 y := y + 1;
3809 END IF;
3810 IF(p_change_table.price(x) IS NOT NULL) THEN
3811 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3812 l_req_change_table(y).new_price := p_change_table.price(x);
3813 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3814 y := y + 1;
3815 END IF;
3816 IF(p_change_table.quantity(x) IS NOT NULL) THEN
3817 IF(p_change_table.req_dist_id(x) IS NULL) THEN
3818 BEGIN
3819 SELECT distribution_id
3820 INTO l_req_dist_id
3821 FROM po_req_distributions_all
3822 WHERE requisition_line_id = p_change_table.req_line_id(x);
3823 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3824 l_req_change_table(y).document_distribution_id := l_req_dist_id;
3825 l_req_change_table(y).new_quantity := p_change_table.quantity(x);
3826 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3827 y := y + 1;
3828 EXCEPTION
3829 WHEN OTHERS THEN
3830 NULL;
3831 END;
3832 ELSE
3833 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
3834 l_req_change_table(y).document_distribution_id := p_change_table.req_dist_id(x);
3835 l_req_change_table(y).new_quantity := p_change_table.quantity(x);
3836 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
3837 y := y + 1;
3838 END IF;
3839 END IF;
3840 END IF;
3841
3842 END LOOP;
3843
3844
3845
3846 --Validate the Change Requests, by passing in l_req_change_table, a table of records
3847 --Initialize the Error Table
3848 l_err_line_id_tbl := po_tbl_number();
3849 l_err_line_num_tbl := po_tbl_number();
3850 l_err_dist_id_tbl := po_tbl_number();
3851 l_err_dist_num_tbl := po_tbl_number();
3852 l_err_error_attr_tbl := po_tbl_varchar30();
3853 l_err_msg_count_tbl := po_tbl_number();
3854 l_err_msg_data_tbl := po_tbl_varchar2000();
3855 x_errtable := po_req_change_err_table(
3856 l_err_line_id_tbl,
3857 l_err_line_num_tbl,
3858 l_err_dist_id_tbl,
3859 l_err_dist_num_tbl,
3860 l_err_error_attr_tbl,
3861 l_err_msg_count_tbl,
3862 l_err_msg_data_tbl);
3863
3864 validate_changes(p_req_hdr_id, l_req_change_table, l_change_result, x_retmsg, x_errtable);
3865 END IF;
3866
3867 --If ALL changes are valid, we will insert change records, and insert cancel records(if any)
3868 IF(l_change_result = fnd_api.g_ret_sts_success) THEN
3869 x_retmsg := 'SRCH004';
3870 SELECT po_chg_request_seq.nextval INTO p_change_request_group_id FROM dual;
3871
3872 insert_reqchange(l_req_change_table, p_change_request_group_id);
3873 x_retmsg := 'SRCH005';
3874
3875 update_recordswithtax(p_change_request_group_id);
3876 x_retmsg := 'SRCH006';
3877
3878 insert_linequantityoramount(p_change_request_group_id);
3879
3880 x_retmsg := 'SRCH0061';
3881
3882 insert_pricebreakrows(p_change_request_group_id);
3883
3884 x_retmsg := 'SRCH0062';
3885
3886 --Process Cancellation Requests
3887 l_cancel_result := fnd_api.g_ret_sts_success;
3888
3889 IF(p_cancel_table IS NOT NULL) THEN
3890 save_reqcancel(1.0, l_cancel_result, p_req_hdr_id, p_cancel_table, l_dummy, x_retmsg, p_change_request_group_id);
3891 END IF;
3892
3893 x_return_status := l_cancel_result;
3894 ELSIF(l_change_result = fnd_api.g_ret_sts_error) THEN
3895 x_return_status := fnd_api.g_ret_sts_error;
3896 x_retmsg := 'SRCH007';
3897 ELSE
3898 x_return_status := fnd_api.g_ret_sts_error;
3899
3900 END IF;
3901
3902 EXCEPTION
3903 WHEN OTHERS THEN
3904 x_retmsg := 'SRCHUNEXP:' || x_retmsg || ':' || SQLERRM;
3905 x_return_status := fnd_api.g_ret_sts_unexp_error;
3906 IF g_fnd_debug = 'Y' THEN
3907 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
3908 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
3909 l_api_name || '.others_exception', x_retmsg);
3910 END IF;
3911 END IF;
3912 END save_reqchange;
3913
3914 /*--------------------------------------------------------------
3915 **Save_ReqCancel: takes in a PLSQL table as input, containing
3916 **cancellation request. No Validation is done here. This API
3917 **simply insert records into PO_CHANGE_REQUESTS table
3918 ---------------------------------------------------------------*/
3919 PROCEDURE save_reqcancel(p_api_version IN NUMBER,
3920 x_return_status OUT NOCOPY VARCHAR2,
3921 p_req_hdr_id IN NUMBER,
3922 p_cancel_table IN po_req_cancel_table,
3923 p_change_request_group_id OUT NOCOPY NUMBER,
3924 x_retmsg OUT NOCOPY VARCHAR2,
3925 p_grp_id IN NUMBER)
3926 IS
3927 l_api_name VARCHAR2(50) := 'Save_ReqCancel';
3928 l_chn_req_id NUMBER;
3929 l_req_num po_requisition_headers_all.segment1%TYPE;
3930 l_req_line_num NUMBER;
3931 l_req_user_id NUMBER;
3932 l_line_loc_id NUMBER;
3933 l_po_header_id NUMBER;
3934 l_po_release_id NUMBER;
3935 l_po_revision_num NUMBER;
3936 l_preparer_id NUMBER;
3937 l_req_price NUMBER;
3938 l_req_currency_price NUMBER;
3939 l_req_quantity NUMBER;
3940 l_req_date DATE;
3941 l_po_num po_change_requests.ref_po_num%TYPE;
3942 l_po_release_num NUMBER;
3943 BEGIN
3944 x_retmsg := '000';
3945 l_req_user_id := fnd_global.user_id;
3946
3947
3948 IF(p_grp_id IS NULL) THEN
3949 SELECT po_chg_request_seq.nextval INTO p_change_request_group_id FROM dual;
3950 DELETE FROM po_change_requests
3951 WHERE document_header_id = p_req_hdr_id
3952 AND initiator = 'REQUESTER'
3953 AND request_status = 'SYSTEMSAVE';
3954 ELSE
3955 p_change_request_group_id := p_grp_id;
3956 END IF;
3957 x_retmsg := '001';
3958 FOR i IN 1..p_cancel_table.req_line_id.count
3959 LOOP
3960
3961 SELECT po_chg_request_seq.nextval INTO l_chn_req_id FROM dual;
3962 SELECT
3963 prha.segment1,
3964 prla.line_num,
3965 prla.line_location_id,
3966 prha.preparer_id,
3967 prla.unit_price,
3968 prla.quantity,
3969 prla.need_by_date,
3970 prla.currency_unit_price
3971 INTO
3972 l_req_num,
3973 l_req_line_num,
3974 l_line_loc_id,
3975 l_preparer_id,
3976 l_req_price,
3977 l_req_quantity,
3978 l_req_date,
3979 l_req_currency_price
3980 FROM
3981 po_requisition_headers_all prha,
3982 po_requisition_lines_all prla
3983 WHERE prla.requisition_line_id = p_cancel_table.req_line_id(i)
3984 AND prla.requisition_header_id = prha.requisition_header_id;
3985
3986 IF(l_line_loc_id IS NOT NULL) THEN
3987 SELECT
3988 po_release_id,
3989 po_header_id
3990 INTO
3991 l_po_release_id,
3992 l_po_header_id
3993 FROM po_line_locations_all
3994 WHERE line_location_id = l_line_loc_id;
3995 IF(l_po_release_id IS NULL) THEN
3996 SELECT revision_num, segment1 INTO
3997 l_po_revision_num, l_po_num
3998 FROM po_headers_all
3999 WHERE po_header_id = l_po_header_id;
4000
4001 -- bug 5191164.
4002 -- Need to null out l_po_release_num for PO records
4003 l_po_release_num := NULL;
4004
4005 ELSE
4006 -- get po_number of the source document for RELEASE
4007 SELECT segment1 INTO l_po_num
4008 FROM po_headers_all
4009 WHERE po_header_id = l_po_header_id;
4010
4011 SELECT revision_num, release_num
4012 INTO l_po_revision_num, l_po_release_num
4013 FROM po_releases_all
4014 WHERE po_release_id = l_po_release_id;
4015 END IF;
4016 END IF;
4017 x_retmsg := '002';
4018 INSERT INTO po_change_requests
4019 (
4020 change_request_group_id,
4021 change_request_id,
4022 initiator,
4023 action_type,
4024 request_reason,
4025 request_level,
4026 request_status,
4027 document_type,
4028 document_header_id,
4029 document_num,
4030 document_revision_num,
4031 created_by,
4032 creation_date,
4033 document_line_id,
4034 document_line_number,
4035 last_updated_by,
4036 last_update_date,
4037 last_update_login,
4038 requester_id,
4039 change_active_flag,
4040 old_price,
4041 old_quantity,
4042 old_need_by_date,
4043 old_currency_unit_price,
4044 ref_po_header_id,
4045 ref_po_num,
4046 ref_po_release_id,
4047 ref_po_rel_num )
4048 VALUES
4049 (
4050 p_change_request_group_id,
4051 l_chn_req_id,
4052 'REQUESTER',
4053 'CANCELLATION',
4054 p_cancel_table.change_reason(i),
4055 'LINE',
4056 'SYSTEMSAVE',
4057 'REQ',
4058 p_req_hdr_id,
4059 l_req_num,
4060 l_po_revision_num,
4061 l_req_user_id,
4062 SYSDATE,
4063 p_cancel_table.req_line_id(i),
4064 l_req_line_num,
4065 l_req_user_id,
4066 SYSDATE,
4067 l_req_user_id,
4068 l_preparer_id,
4069 'Y',
4070 l_req_price,
4071 l_req_quantity,
4072 l_req_date,
4073 l_req_currency_price,
4074 l_po_header_id,
4075 l_po_num,
4076 l_po_release_id,
4077 l_po_release_num
4078 );
4079
4080
4081 END LOOP;
4082
4083
4084 x_return_status := fnd_api.g_ret_sts_success;
4085 EXCEPTION WHEN OTHERS THEN
4086 x_return_status := fnd_api.g_ret_sts_unexp_error;
4087 IF g_fnd_debug = 'Y' THEN
4088 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
4089 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
4090 l_api_name || '.others_exception', x_retmsg || ':' || SQLERRM);
4091 END IF;
4092 END IF;
4093 END save_reqcancel;
4094
4095 /*-----------------------------------------------------------------------------------------------------
4096 * At the Final Stage of Requester Creating Change request, SUBMIT_REQCHANGE will be executed to complete
4097 * the transaction. This API takes care of funds Check, and does a final round of validation against
4098 * all change/cancel requests before kicking off the Workflow.
4099 ----------------------------------------------------------------------------------------------------*/
4100 PROCEDURE submit_reqchange (
4101 p_api_version IN NUMBER,
4102 x_return_status OUT NOCOPY VARCHAR2,
4103 p_group_id IN NUMBER,
4104 p_fundscheck_flag IN VARCHAR2,
4105 p_note_to_approver IN VARCHAR2,
4106 p_initiator IN VARCHAR2,
4107 x_retmsg OUT NOCOPY VARCHAR2,
4108 x_errcode OUT NOCOPY VARCHAR2,
4109 x_errtable OUT NOCOPY po_req_change_err_table)
4110 IS
4111 l_api_name VARCHAR2(50) := 'Submit_ReqChange';
4112 i NUMBER := 1;
4113 l_cancelerrorsize NUMBER;
4114 l_flag_one VARCHAR2(1);
4115 l_flag_two VARCHAR2(1);
4116 --l_FC_Tbl po_fcin_type;
4117 l_req_dist_id NUMBER;
4118 l_req_line_id NUMBER;
4119 l_req_hdr_id NUMBER;
4120 l_req_num po_requisition_headers_all.segment1%TYPE;
4121 l_po_num po_headers_all.segment1%TYPE;
4122 l_header_id NUMBER;
4123 l_release_id NUMBER;
4124 l_line_id NUMBER;
4125 l_shipment_id NUMBER;
4126 l_distribution_id NUMBER;
4127 l_budget_account_id NUMBER;
4128 l_gl_date DATE;
4129 l_vendor_id NUMBER;
4130 l_old_price NUMBER;
4131 l_old_quantity NUMBER;
4132 l_old_tax NUMBER;
4133 l_ship_to_org_id NUMBER;
4134 l_ship_to_loc_id NUMBER;
4135 l_price_changed_flag VARCHAR2(1) := fnd_api.g_false;
4136 l_qty_changed_flag VARCHAR2(1) := fnd_api.g_false;
4137 l_change_exist VARCHAR2(1);
4138 l_cancel_exist VARCHAR2(1);
4139 l_new_price NUMBER;
4140 l_new_quantity NUMBER;
4141 l_new_po_quantity NUMBER;
4142 l_rec_tax NUMBER;
4143 l_nonrec_tax NUMBER;
4144 l_new_tax NUMBER;
4145 l_entered_dr NUMBER;
4146 l_entered_cr NUMBER;
4147 l_org_id NUMBER;
4148 l_fc_out_tbl po_fcout_type;
4149 l_fc_result_code VARCHAR2(1);
4150 l_fc_result_status VARCHAR2(1);
4151 l_fc_msg_count NUMBER;
4152 l_fc_msg_data VARCHAR2(2000);
4153 l_fc_req_line_id NUMBER;
4154 l_fc_req_line_num NUMBER;
4155 l_fc_req_distr_id NUMBER;
4156 l_fc_req_distr_num NUMBER;
4157 l_req_change_table change_tbl_type;
4158 l_new_date DATE;
4159 l_new_need_by_date DATE;
4160 l_old_need_by_date DATE;
4161 l_old_amount NUMBER;
4162 l_new_amount NUMBER;
4163 l_price_break VARCHAR2(1);
4164 -- l_set_of_books_id NUMBER;
4165 -- l_gl_period GL_PERIOD_STATUSES.PERIOD_NAME%TYPE;
4166
4167 l_request_reason po_change_requests.request_reason%TYPE;
4168 l_cancel_errtable po_req_change_err_table;
4169 l_cal_disttax_status VARCHAR2(1);
4170 l_item_id NUMBER;
4171 l_req_uom po_requisition_lines_all.unit_meas_lookup_code%TYPE;
4172 l_po_uom po_line_locations_all.unit_meas_lookup_code%TYPE;
4173 l_po_to_req_rate NUMBER;
4174
4175 l_po_return_code VARCHAR2(100) := '';
4176 l_err_line_id_tbl po_tbl_number;
4177 l_err_line_num_tbl po_tbl_number;
4178 l_err_dist_id_tbl po_tbl_number;
4179 l_err_dist_num_tbl po_tbl_number;
4180 l_err_error_attr_tbl po_tbl_varchar30;
4181 l_err_msg_count_tbl po_tbl_number;
4182 l_err_msg_data_tbl po_tbl_varchar2000;
4183 l_wf_status VARCHAR2(1);
4184 l_distribution_id_tbl po_tbl_number;
4185
4186 CURSOR l_changes_csr(grp_id NUMBER) IS
4187 SELECT
4188 document_header_id,
4189 document_line_id,
4190 document_distribution_id,
4191 new_quantity,
4192 new_price,
4193 new_need_by_date,
4194 request_reason
4195 FROM po_change_requests
4196 WHERE change_request_group_id = grp_id
4197 AND action_type = 'MODIFICATION';
4198
4199 CURSOR l_cancel_csr(grp_id NUMBER) IS
4200 SELECT
4201 document_header_id,
4202 document_line_id,
4203 request_reason
4204 FROM po_change_requests
4205 WHERE change_request_group_id = grp_id
4206 AND action_type = 'CANCELLATION';
4207
4208
4209 CURSOR l_dist_qty_price_chn_csr(grp_id NUMBER) IS
4210 SELECT
4211 document_line_id line_id,
4212 document_distribution_id dist_id,
4213 document_header_id hdr_id,
4214 document_num req_num
4215 FROM
4216 po_change_requests
4217 WHERE
4218 change_request_group_id = grp_id AND
4219 (new_quantity IS NOT NULL OR new_amount IS NOT NULL) AND
4220 action_type = 'MODIFICATION'
4221 UNION
4222 SELECT
4223 prda.requisition_line_id line_id,
4224 prda.distribution_id dist_id,
4225 prla.requisition_header_id hdr_id,
4226 prha.segment1 req_num
4227 FROM
4228 po_req_distributions_all prda,
4229 po_requisition_lines_all prla,
4230 po_change_requests pcr,
4231 po_requisition_headers_all prha
4232 WHERE
4233 prha.requisition_header_id = prla.requisition_header_id AND
4234 prla.requisition_line_id = prda.requisition_line_id AND
4235 pcr.document_line_id = prla.requisition_line_id AND
4236 pcr.change_request_group_id = grp_id AND
4237 pcr.action_type = 'MODIFICATION' AND (pcr.new_price IS NOT NULL OR
4238 pcr.new_need_by_date IS NOT NULL);
4239
4240 -- list of standard po distributions effected with the req changes
4241 CURSOR l_changed_po_dists_csr(grp_id NUMBER) IS
4242 SELECT -- any quantity or amount change
4243 pda.po_distribution_id
4244 FROM
4245 po_change_requests pcr,
4246 po_req_distributions_all prda,
4247 po_distributions_all pda,
4248 po_headers_all pha
4249 WHERE
4250 pcr.change_request_group_id = grp_id AND
4251 (pcr.new_quantity IS NOT NULL OR pcr.new_amount IS NOT NULL) AND
4252 pcr.action_type = 'MODIFICATION' AND
4253 pcr.document_distribution_id = prda.distribution_id AND
4254 prda.distribution_id = pda.req_distribution_id AND
4255 pda.po_header_id = pha.po_header_id AND
4256 pha.type_lookup_code = 'STANDARD'
4257 UNION
4258 SELECT -- select distributions that are effected with any line change
4259 pda.po_distribution_id
4260 FROM
4261 po_change_requests pcr,
4262 po_requisition_lines_all prla,
4263 po_req_distributions_all prda,
4264 po_distributions_all pda,
4265 po_headers_all pha
4266 WHERE
4267 pcr.change_request_group_id = grp_id AND
4268 pcr.action_type = 'MODIFICATION' AND
4269 (pcr.new_price IS NOT NULL OR pcr.new_need_by_date IS NOT NULL) AND
4270 pcr.document_line_id = prla.requisition_line_id AND
4271 prla.requisition_line_id = prda.requisition_line_id AND
4272 prda.distribution_id = pda.req_distribution_id AND
4273 pda.po_header_id = pha.po_header_id AND
4274 pha.type_lookup_code = 'STANDARD';
4275
4276 -- list of release distributions effected with the req changes
4277 CURSOR l_changed_rel_dists_csr(grp_id NUMBER) IS
4278 SELECT -- any quantity or amount change
4279 pda.po_distribution_id
4280 FROM
4281 po_change_requests pcr,
4282 po_req_distributions_all prda,
4283 po_distributions_all pda,
4284 po_requisition_lines_all prla,
4285 po_line_locations_all plla
4286 WHERE
4287 pcr.change_request_group_id = grp_id AND
4288 (pcr.new_quantity IS NOT NULL OR pcr.new_amount IS NOT NULL) AND
4289 pcr.action_type = 'MODIFICATION' AND
4290 pcr.document_distribution_id = prda.distribution_id AND
4291 prda.distribution_id = pda.req_distribution_id AND
4292 prla.requisition_line_id = prda.requisition_line_id AND
4293 prla.line_location_id = plla.line_location_id AND
4294 plla.po_release_id IS NOT NULL
4295 UNION -- select distributions that are effected with any line change
4296 SELECT
4297 pda.po_distribution_id
4298 FROM
4299 po_change_requests pcr,
4300 po_requisition_lines_all prla,
4301 po_req_distributions_all prda,
4302 po_distributions_all pda,
4303 po_line_locations_all plla
4304 WHERE
4305 pcr.change_request_group_id = grp_id AND
4306 pcr.action_type = 'MODIFICATION' AND
4307 (pcr.new_price IS NOT NULL OR pcr.new_need_by_date IS NOT NULL) AND
4308 pcr.document_line_id = prla.requisition_line_id AND
4309 prla.requisition_line_id = prda.requisition_line_id AND
4310 prda.distribution_id = pda.req_distribution_id AND
4311 prla.line_location_id = plla.line_location_id AND
4312 plla.po_release_id IS NOT NULL;
4313
4314
4315 BEGIN
4316 x_retmsg := 'SMRCH000';
4317 x_return_status := fnd_api.g_ret_sts_success;
4318
4319 --Check if Funds Check is needed
4320 SELECT
4321 nvl(fsp.req_encumbrance_flag, 'N'),
4322 nvl(fsp.purch_encumbrance_flag, 'N')
4323 INTO
4324 l_flag_one,
4325 l_flag_two
4326 FROM financials_system_parameters fsp;
4327
4328 --Check if change request exist
4329 l_change_exist := 'N';
4330 OPEN l_changes_csr(p_group_id);
4331 FETCH l_changes_csr
4332 INTO l_req_hdr_id, l_req_line_id, l_req_dist_id, l_new_quantity, l_new_price, l_new_date, l_request_reason;
4333 IF(l_req_hdr_id IS NOT NULL) THEN
4334 l_change_exist := 'Y';
4335 END IF;
4336 CLOSE l_changes_csr;
4337
4338 --Check if cancel request exist
4339 l_cancel_exist := 'N';
4340 OPEN l_cancel_csr(p_group_id);
4341 FETCH l_cancel_csr
4342 INTO l_req_hdr_id, l_req_line_id, l_request_reason;
4343 IF(l_req_hdr_id IS NOT NULL) THEN
4344 l_cancel_exist := 'Y';
4345 END IF;
4346 CLOSE l_cancel_csr;
4347
4348
4349 x_retmsg := 'SMRCH001';
4350
4351 --Funds Check Starts
4352 IF (l_change_exist = 'Y' AND p_fundscheck_flag = 'Y' AND (l_flag_one <> 'N' OR l_flag_two <> 'N')) THEN
4353
4354 x_retmsg := 'SMRCH002';
4355 --Check if any records require funds check.
4356 OPEN l_dist_qty_price_chn_csr(p_group_id);
4357 FETCH l_dist_qty_price_chn_csr INTO
4358 l_req_line_id,
4359 l_req_dist_id,
4360 l_req_hdr_id,
4361 l_req_num;
4362 CLOSE l_dist_qty_price_chn_csr;
4363
4364 IF (l_req_num IS NOT NULL) THEN
4365
4366 -- initialize distributions list table
4367 l_distribution_id_tbl := po_tbl_number();
4368
4369 -- insert NEW/OLD records of standard po distributions into PO_ENCUMBRANCE_GT
4370 OPEN l_changed_po_dists_csr(p_group_id);
4371
4372 FETCH l_changed_po_dists_csr BULK COLLECT
4373 INTO l_distribution_id_tbl;
4374
4375 CLOSE l_changed_po_dists_csr;
4376
4377 po_document_funds_grp.populate_encumbrance_gt(
4378 p_api_version => 1.0,
4379 x_return_status => x_return_status,
4380 p_doc_type => po_document_funds_grp.g_doc_type_po,
4381 p_doc_level => po_document_funds_grp.g_doc_level_distribution,
4382 p_doc_level_id_tbl => l_distribution_id_tbl,
4383 p_make_old_copies_flag => po_document_funds_grp.g_parameter_yes,
4384 p_make_new_copies_flag => po_document_funds_grp.g_parameter_yes,
4385 p_check_only_flag => po_document_funds_grp.g_parameter_yes);
4386
4387 -- error handling after calling populate_encumbrance_gt
4388 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
4389 x_retmsg := 'After calling populate_encumbrance_gt';
4390 x_errcode := 'FC_FAIL';
4391 RETURN;
4392 END IF;
4393
4394 -- insert NEW/OLD records of release distributions into PO_ENCUMBRANCE_GT
4395
4396 -- re-initialize distributions list table
4397 l_distribution_id_tbl.delete;
4398
4399 -- insert standard po distributions into PO_ENCUMBRANCE_GT
4400 OPEN l_changed_rel_dists_csr(p_group_id);
4401
4402 FETCH l_changed_rel_dists_csr BULK COLLECT
4403 INTO l_distribution_id_tbl;
4404
4405 CLOSE l_changed_rel_dists_csr;
4406
4407 po_document_funds_grp.populate_encumbrance_gt(
4408 p_api_version => 1.0,
4409 x_return_status => x_return_status,
4410 p_doc_type => po_document_funds_grp.g_doc_type_release,
4411 p_doc_level => po_document_funds_grp.g_doc_level_distribution,
4412 p_doc_level_id_tbl => l_distribution_id_tbl,
4413 p_make_old_copies_flag => po_document_funds_grp.g_parameter_yes,
4414 p_make_new_copies_flag => po_document_funds_grp.g_parameter_yes,
4415 p_check_only_flag => po_document_funds_grp.g_parameter_yes);
4416
4417 -- error handling after calling populate_encumbrance_gt
4418 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
4419 x_retmsg := 'After calling populate_encumbrance_gt (release)';
4420 x_errcode := 'FC_FAIL';
4421 RETURN;
4422 END IF;
4423
4424 -- Update NEW record in PO_ENCUMBRANCE_GT with the new
4425 -- values
4426
4427
4428 x_retmsg := 'SMRCH003';
4429 /*
4430 *Looping through the distribution records which requires fundscheck, and populating the fundscheck
4431 *input table with the appropriate data.
4432 */
4433 OPEN l_dist_qty_price_chn_csr(p_group_id);
4434
4435 LOOP
4436 FETCH l_dist_qty_price_chn_csr INTO
4437 l_req_line_id,
4438 l_req_dist_id,
4439 l_req_hdr_id,
4440 l_req_num;
4441
4442 EXIT WHEN l_dist_qty_price_chn_csr%notfound;
4443 x_retmsg := 'SMRCH0031:' || l_req_line_id || '*' || l_req_dist_id || '*' || l_req_hdr_id || '*' || l_req_num;
4444
4445 SELECT
4446 plla.line_location_id,
4447 pda.po_distribution_id,
4448 plla.po_line_id,
4449 nvl(plla.price_override, pla.unit_price),
4450 pda.quantity_ordered,
4451 pda.amount_ordered,
4452 prla.item_id,
4453 prla.unit_meas_lookup_code,
4454 nvl(plla.unit_meas_lookup_code, pla.unit_meas_lookup_code),
4455 pha.rate,
4456 plla.need_by_date,
4457 plla.ship_to_organization_id,
4458 plla.ship_to_location_id
4459 INTO
4460 l_shipment_id,
4461 l_distribution_id,
4462 l_line_id,
4463 l_old_price,
4464 l_old_quantity,
4465 l_old_amount,
4466 l_item_id,
4467 l_req_uom,
4468 l_po_uom,
4469 l_po_to_req_rate,
4470 l_old_need_by_date,
4471 l_ship_to_org_id,
4472 l_ship_to_loc_id
4473 FROM
4474 po_req_distributions_all prda,
4475 po_requisition_lines_all prla,
4476 po_line_locations_all plla,
4477 po_distributions_all pda,
4478 po_lines_all pla,
4479 po_headers_all pha
4480 WHERE
4481 prda.distribution_id = l_req_dist_id
4482 AND prda.requisition_line_id = prla.requisition_line_id
4483 AND pda.req_distribution_id = prda.distribution_id
4484 AND pda.line_location_id = prla.line_location_id
4485 AND plla.line_location_id = prla.line_location_id
4486 AND plla.po_header_id = plla.po_header_id
4487 AND plla.po_line_id = pla.po_line_id
4488 AND pla.po_header_id = pha.po_header_id;
4489
4490 -- Following Period check has been removed as part of fix for 14198490.
4491
4492 /* BEGIN
4493 SELECT pda.SET_OF_BOOKS_ID,
4494 pda.GL_ENCUMBERED_DATE
4495 INTO l_set_of_books_id,
4496 l_gl_date
4497 FROM po_distributions_All pda
4498 WHERE pda.po_distribution_id = l_distribution_id
4499 AND pda.ENCUMBERED_FLAG = 'Y';
4500
4501 -- check if GL period is open
4502 SELECT GL_PS.PERIOD_NAME
4503 INTO l_gl_period
4504 FROM
4505 GL_PERIOD_STATUSES GL_PS,
4506 GL_PERIOD_STATUSES PO_PS,
4507 GL_SETS_OF_BOOKS GL_SOB
4508 WHERE
4509 -- Join conditions:
4510 GL_SOB.set_of_books_id = (l_set_of_books_id)
4511 AND GL_PS.set_of_books_id = GL_SOB.set_of_books_id
4512 AND PO_PS.set_of_books_id = GL_SOB.set_of_books_id
4513 AND GL_PS.period_name = PO_PS.period_name
4514 -- GL period conditions:
4515 AND GL_PS.application_id = 101
4516 -- bug 5206339 <11.5.10 GL PERIOD VALIDATION>
4517 AND (( (nvl(FND_PROFILE.VALUE('PO_VALIDATE_GL_PERIOD'),'Y')) = 'Y'
4518 and GL_PS.closing_status IN ('O', 'F'))
4519 OR
4520 ((nvl(FND_PROFILE.VALUE('PO_VALIDATE_GL_PERIOD'),'Y')) = 'N'))
4521 -- AND GL_PS.closing_status IN ('O', 'F')
4522 AND GL_PS.adjustment_period_flag = 'N'
4523 AND GL_PS.period_year <= GL_SOB.latest_encumbrance_year
4524 -- PO period conditions:
4525 AND PO_PS.application_id = 201
4526 AND PO_PS.closing_status = 'O'
4527 AND PO_PS.adjustment_period_flag = 'N'
4528 -- Period date conditions:
4529 AND (l_gl_date BETWEEN GL_PS.start_date AND GL_PS.end_date);
4530
4531
4532 EXCEPTION
4533 WHEN NO_DATA_FOUND THEN
4534 x_return_status := FND_API.G_RET_STS_ERROR;
4535 x_retMsg := 'SMRCH0033: No Open GL Period';
4536 x_errCode := 'FC_GL_PERIOD_ERROR';
4537 RETURN;
4538 END; */
4539
4540 -- Obtain new amount (for service lines)
4541 BEGIN
4542
4543 SELECT new_amount
4544 INTO l_new_amount
4545 FROM po_change_requests
4546 WHERE
4547 change_request_group_id = p_group_id AND
4548 document_distribution_id = l_req_dist_id AND
4549 new_amount IS NOT NULL;
4550
4551 EXCEPTION WHEN no_data_found THEN
4552 l_new_amount := l_old_amount;
4553 END;
4554
4555 --Obtain most recent quantity
4556 l_price_break := 'N';
4557 BEGIN
4558 SELECT new_quantity
4559 INTO l_new_quantity
4560 FROM po_change_requests
4561 WHERE change_request_group_id = p_group_id
4562 AND document_distribution_id = l_req_dist_id
4563 AND new_quantity IS NOT NULL;
4564
4565 l_price_break := 'Y';
4566
4567 IF(l_req_uom <> l_po_uom) THEN
4568 po_uom_s.uom_convert(
4569 from_quantity => l_new_quantity,
4570 from_uom => l_req_uom,
4571 item_id => l_item_id,
4572 to_uom => l_po_uom,
4573 to_quantity => l_new_po_quantity);
4574
4575 l_new_quantity := l_new_po_quantity;
4576 END IF;
4577
4578 EXCEPTION WHEN no_data_found THEN
4579 l_new_quantity := l_old_quantity;
4580 END;
4581
4582 --Obtain most recent price
4583 BEGIN
4584 SELECT new_price
4585 INTO l_new_price
4586 FROM po_change_requests
4587 WHERE change_request_group_id = p_group_id
4588 AND document_line_id = l_req_line_id
4589 AND new_price IS NOT NULL;
4590
4591 IF(l_po_to_req_rate IS NOT NULL) THEN
4592 l_new_price := l_new_price / l_po_to_req_rate;
4593 END IF;
4594
4595 EXCEPTION WHEN no_data_found THEN
4596 BEGIN
4597 SELECT new_need_by_date
4598 INTO l_new_need_by_date
4599 FROM po_change_requests
4600 WHERE change_request_group_id = p_group_id
4601 AND document_line_id = l_req_line_id
4602 AND new_need_by_date IS NOT NULL;
4603
4604 l_price_break := 'Y';
4605 EXCEPTION WHEN no_data_found THEN
4606 l_new_need_by_date := l_old_need_by_date;
4607 END;
4608
4609 IF(l_price_break = 'Y') THEN
4610 l_new_price := po_sourcing2_sv.get_break_price(
4611 x_order_quantity => l_new_quantity,
4612 x_ship_to_org => l_ship_to_org_id,
4613 x_ship_to_loc => l_ship_to_loc_id,
4614 x_po_line_id => l_line_id,
4615 x_cum_flag => FALSE,
4616 p_need_by_date => l_new_need_by_date,
4617 x_line_location_id => l_shipment_id);
4618 ELSE
4619 l_new_price := l_old_price;
4620 END IF;
4621
4622 END;
4623
4624 --Calculate new tax
4625 calculate_disttax(1.0, l_cal_disttax_status, l_req_dist_id, l_new_price, l_new_quantity, NULL,
4626 l_rec_tax, l_nonrec_tax);
4627 l_new_tax := l_nonrec_tax;
4628
4629
4630 -- update new values in PO_ENCUMBRANCE_GT
4631 UPDATE po_encumbrance_gt
4632 SET
4633 amount_ordered = l_new_amount,
4634 quantity_ordered = l_new_quantity,
4635 price = l_new_price,
4636 nonrecoverable_tax = l_new_tax
4637 WHERE
4638 distribution_id = l_distribution_id AND
4639 adjustment_status = po_document_funds_grp.g_adjustment_status_new;
4640
4641 END LOOP;
4642 CLOSE l_dist_qty_price_chn_csr;
4643
4644
4645 x_retmsg := 'SMRCH0032';
4646 --Execute PO Funds Check API
4647
4648 po_document_funds_grp.check_adjust(
4649 p_api_version => 1.0,
4650 x_return_status => l_fc_result_status,
4651 p_doc_type => po_document_funds_grp.g_doc_type_mixed_po_release,
4652 p_doc_subtype => NULL,
4653 p_override_funds => po_document_funds_grp.g_parameter_use_profile,
4654 p_use_gl_date => po_document_funds_grp.g_parameter_yes,
4655 p_override_date => SYSDATE,
4656 p_report_successes => po_document_funds_grp.g_parameter_no,
4657 x_po_return_code => l_po_return_code,
4658 x_detailed_results => l_fc_out_tbl);
4659
4660 x_retmsg := 'SMRCH004';
4661
4662 IF (g_fnd_debug = 'Y') THEN
4663 IF (fnd_log.g_current_runtime_level <= fnd_log.level_statement) THEN
4664 fnd_log.string(fnd_log.level_statement,
4665 g_module_prefix || l_api_name,
4666 'FUNDS CHECK:' || l_fc_result_status ||' PO RETURN CODE:' || l_po_return_code);
4667 END IF;
4668 END IF;
4669
4670 IF (l_fc_result_status = fnd_api.g_ret_sts_unexp_error) THEN
4671 x_errcode := 'FC_ERROR';
4672 x_return_status := fnd_api.g_ret_sts_error;
4673 RETURN;
4674
4675 ELSE
4676
4677 IF (l_po_return_code = po_document_funds_grp.g_return_success) THEN
4678 x_return_status := fnd_api.g_ret_sts_success;
4679
4680 ELSE -- there can be warning/error message for other cases
4681 IF (l_po_return_code = po_document_funds_grp.g_return_WARNING) THEN
4682 x_errCode := 'FC_WARN';
4683 ELSE
4684 x_errcode := 'FC_FAIL';
4685 END IF;
4686 x_return_status := fnd_api.g_ret_sts_error;
4687
4688 -- populate x_errTable (output PLSQL table) with the corresponding
4689 -- funds check error messages.
4690
4691 l_err_line_id_tbl := po_tbl_number();
4692 l_err_line_num_tbl := po_tbl_number();
4693 l_err_dist_id_tbl := po_tbl_number();
4694 l_err_dist_num_tbl := po_tbl_number();
4695 l_err_error_attr_tbl := po_tbl_varchar30();
4696 l_err_msg_count_tbl := po_tbl_number();
4697 l_err_msg_data_tbl := po_tbl_varchar2000();
4698
4699 x_errtable := po_req_change_err_table(
4700 l_err_line_id_tbl,
4701 l_err_line_num_tbl,
4702 l_err_dist_id_tbl,
4703 l_err_dist_num_tbl,
4704 l_err_error_attr_tbl,
4705 l_err_msg_count_tbl,
4706 l_err_msg_data_tbl);
4707
4708
4709 x_errtable.req_line_id.extend(l_fc_out_tbl.row_index.count);
4710 x_errtable.req_line_num.extend(l_fc_out_tbl.row_index.count);
4711 x_errtable.req_dist_id.extend(l_fc_out_tbl.row_index.count);
4712 x_errtable.req_dist_num.extend(l_fc_out_tbl.row_index.count);
4713 x_errtable.msg_count.extend(l_fc_out_tbl.row_index.count);
4714 x_errtable.msg_data.extend(l_fc_out_tbl.row_index.count);
4715 FOR x IN 1..l_fc_out_tbl.row_index.count LOOP
4716
4717 SELECT
4718 prda.distribution_id,
4719 prda.distribution_num,
4720 prda.requisition_line_id,
4721 prla.line_num
4722 INTO
4723 l_fc_req_distr_id,
4724 l_fc_req_distr_num,
4725 l_fc_req_line_id,
4726 l_fc_req_line_num
4727 FROM
4728 po_requisition_lines_all prla,
4729 po_req_distributions_all prda,
4730 po_distributions_all pda
4731 WHERE
4732 pda.po_distribution_id = l_fc_out_tbl.distribution_id(x)
4733 AND pda.req_distribution_id = prda.distribution_id
4734 AND prla.requisition_line_id = prda.requisition_line_id;
4735
4736 x_errtable.req_line_id(x) := l_fc_req_line_id;
4737 x_errtable.req_line_num(x) := l_fc_req_line_num;
4738 x_errtable.req_dist_id(x) := l_fc_req_distr_id;
4739 x_errtable.req_dist_num(x) := l_fc_req_distr_num;
4740 x_errtable.msg_data(x) := l_fc_out_tbl.error_msg(x);
4741
4742 END LOOP;
4743 RETURN;
4744 END IF;
4745 END IF;
4746 END IF;
4747
4748 END IF;
4749 --Funds Check Ends
4750
4751
4752 i := 1;
4753 OPEN l_changes_csr(p_group_id);
4754 LOOP
4755 FETCH l_changes_csr
4756 INTO
4757 l_req_hdr_id,
4758 l_req_line_id,
4759 l_req_dist_id,
4760 l_new_quantity,
4761 l_new_price,
4762 l_new_date,
4763 l_request_reason;
4764 EXIT WHEN l_changes_csr%notfound;
4765 l_req_change_table(i).document_line_id := l_req_line_id;
4766 l_req_change_table(i).document_distribution_id := l_req_dist_id;
4767 l_req_change_table(i).new_price := l_new_price;
4768 l_req_change_table(i).new_quantity := l_new_quantity;
4769 l_req_change_table(i).new_date := l_new_date;
4770 l_req_change_table(i).request_reason := l_request_reason;
4771
4772 i := i + 1;
4773 END LOOP;
4774 CLOSE l_changes_csr;
4775 x_retmsg := 'SMRCH006';
4776 l_err_line_id_tbl := po_tbl_number();
4777 l_err_line_num_tbl := po_tbl_number();
4778 l_err_dist_id_tbl := po_tbl_number();
4779 l_err_dist_num_tbl := po_tbl_number();
4780 l_err_error_attr_tbl := po_tbl_varchar30();
4781 l_err_msg_count_tbl := po_tbl_number();
4782 l_err_msg_data_tbl := po_tbl_varchar2000();
4783
4784 x_errtable := po_req_change_err_table(
4785 l_err_line_id_tbl,
4786 l_err_line_num_tbl,
4787 l_err_dist_id_tbl,
4788 l_err_dist_num_tbl,
4789 l_err_error_attr_tbl,
4790 l_err_msg_count_tbl,
4791 l_err_msg_data_tbl);
4792
4793 --Final Round of Validations Against Changes
4794 IF(l_change_exist = 'Y') THEN
4795 validate_changes(l_req_hdr_id, l_req_change_table, x_return_status, x_retmsg, x_errtable);
4796 END IF;
4797 x_retmsg := 'SMRCH007';
4798 --Submit Cancel Requests
4799 IF(l_cancel_exist = 'Y') THEN
4800 submit_reqcancel(1.0, x_return_status, p_group_id, x_retmsg, l_cancel_errtable, 'Y');
4801 END IF;
4802
4803 x_retmsg := 'SMRCH008';
4804
4805
4806
4807
4808 i := x_errtable.req_line_id.count + 1;
4809 l_cancelerrorsize := l_cancel_errtable.req_line_id.count;
4810 IF(l_cancelerrorsize > 0) THEN
4811 x_errtable.req_line_id.extend(l_cancelerrorsize);
4812 x_errtable.msg_count.extend(l_cancelerrorsize);
4813 x_errtable.msg_data.extend(l_cancelerrorsize);
4814
4815
4816 FOR k IN 1..l_cancelerrorsize
4817 LOOP
4818 x_errtable.req_line_id(i) := l_cancel_errtable.req_line_id(k);
4819 x_errtable.msg_count(i) := 1;
4820 x_errtable.msg_data(i) :='CANNOT CANCEL';
4821 i := i + 1;
4822 END LOOP;
4823 END IF;
4824
4825 /*
4826 * If all requests are valid, update status to "NEW" and kick off workflow
4827 */
4828 IF(x_errtable.req_line_id.count = 0) THEN
4829 UPDATE po_change_requests
4830 SET request_status = 'NEW'
4831 WHERE change_request_group_id = p_group_id
4832 AND request_status = 'SYSTEMSAVE';
4833
4834 --Kick Off Workflow
4835 x_retmsg := 'SMRCH009';
4836 po_reqchangerequestwf_pvt.submit_req_change(
4837 p_api_version => 1.0,
4838 p_commit => fnd_api.g_false,
4839
4840 p_req_header_id => l_req_hdr_id,
4841 p_note_to_approver => p_note_to_approver,
4842 p_initiator => p_initiator,
4843 x_return_status => l_wf_status);
4844 ELSE
4845 x_errcode := 'VC_FAIL';
4846 x_return_status := fnd_api.g_ret_sts_error;
4847 END IF;
4848 EXCEPTION WHEN OTHERS THEN
4849 x_return_status := fnd_api.g_ret_sts_unexp_error;
4850 x_retmsg := x_retmsg || ':' || SQLERRM;
4851 IF g_fnd_debug = 'Y' THEN
4852 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
4853 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
4854 l_api_name || '.others_exception', x_retmsg );
4855 END IF;
4856 END IF;
4857 END submit_reqchange;
4858
4859 /*
4860 **Submit_ReqCancel: Final procedure call for transaction which involves requester
4861 **cancelling a req line.
4862 **This API could be called from the Cancel Flow UI directly, or from Submit_ReqChange API.
4863 */
4864 PROCEDURE submit_reqcancel (
4865 p_api_version IN NUMBER,
4866 x_return_status OUT NOCOPY VARCHAR2,
4867 p_group_id IN NUMBER,
4868 x_retmsg OUT NOCOPY VARCHAR2,
4869 p_errtable OUT NOCOPY po_req_change_err_table,
4870 p_origin IN VARCHAR2)
4871 IS
4872 l_api_name VARCHAR2(50) := 'Submit_ReqCancel';
4873 l_line_id NUMBER;
4874 l_result VARCHAR2(1);
4875 i NUMBER := 1;
4876 l_canerr_line_id_tbl po_tbl_number;
4877 l_canerr_line_num_tbl po_tbl_number;
4878 l_canerr_dist_id_tbl po_tbl_number;
4879 l_canerr_dist_num_tbl po_tbl_number;
4880 l_canerr_error_attr_tbl po_tbl_varchar30;
4881 l_canerr_msg_count_tbl po_tbl_number;
4882 l_canerr_msg_data_tbl po_tbl_varchar2000;
4883 l_line_location_id NUMBER;
4884 l_chn_req_id NUMBER;
4885 l_req_hdr_id NUMBER;
4886 l_wf_status VARCHAR2(1);
4887 l_workflow_needed VARCHAR2(1) := 'N';
4888 CURSOR l_cancels_csr(grp_id NUMBER) IS
4889 SELECT
4890 pcr.document_header_id,
4891 pcr.document_line_id,
4892 prla.line_location_id,
4893 pcr.change_request_id
4894 FROM
4895 po_change_requests pcr,
4896 po_requisition_lines_all prla
4897 WHERE pcr.action_type = 'CANCELLATION'
4898 AND pcr.change_request_group_id = grp_id
4899 AND pcr.document_line_id = prla.requisition_line_id;
4900 BEGIN
4901
4902
4903 l_canerr_line_id_tbl := po_tbl_number();
4904 l_canerr_line_num_tbl := po_tbl_number();
4905 l_canerr_dist_id_tbl := po_tbl_number();
4906 l_canerr_dist_num_tbl := po_tbl_number();
4907 l_canerr_error_attr_tbl := po_tbl_varchar30();
4908 l_canerr_msg_count_tbl := po_tbl_number();
4909 l_canerr_msg_data_tbl := po_tbl_varchar2000();
4910
4911 p_errtable := po_req_change_err_table(
4912 l_canerr_line_id_tbl ,
4913 l_canerr_line_num_tbl,
4914 l_canerr_dist_id_tbl ,
4915 l_canerr_dist_num_tbl,
4916 l_canerr_error_attr_tbl,
4917 l_canerr_msg_count_tbl ,
4918 l_canerr_msg_data_tbl );
4919
4920 --Calling PO Cancel API to check if the corresponding PO Shipment Can be cancelled.
4921 OPEN l_cancels_csr(p_group_id);
4922 LOOP
4923 FETCH l_cancels_csr INTO
4924 l_req_hdr_id, l_line_id, l_line_location_id, l_chn_req_id;
4925 EXIT WHEN l_cancels_csr%notfound;
4926 IF(l_line_location_id IS NULL) THEN
4927 UPDATE po_change_requests
4928 SET request_status = 'ACCEPTED'
4929 WHERE change_request_id = l_chn_req_id;
4930 ELSE
4931 l_workflow_needed := 'Y';
4932 is_req_line_cancellable(1.0, x_return_status, l_line_id, l_result);
4933 IF(l_result = 'N') THEN
4934 p_errtable.req_line_id.extend(1);
4935 p_errtable.req_line_id(i) := l_line_id;
4936 i := i + 1;
4937 END IF;
4938 END IF;
4939 END LOOP;
4940
4941 CLOSE l_cancels_csr;
4942
4943 x_return_status := fnd_api.g_ret_sts_success;
4944
4945 --If all requests are valid, update status to "NEW", and kick off Workflow
4946
4947 IF(p_errtable.req_line_id.count = 0) THEN
4948 UPDATE po_change_requests
4949 SET request_status = 'NEW'
4950 WHERE change_request_group_id = p_group_id
4951 AND request_status = 'SYSTEMSAVE';
4952
4953 IF (p_origin IS NULL AND l_workflow_needed = 'Y') THEN
4954
4955 po_reqchangerequestwf_pvt.submit_req_change(
4956 p_api_version => 1.0,
4957 p_commit => fnd_api.g_false,
4958 x_return_status => l_wf_status,
4959 p_req_header_id => l_req_hdr_id,
4960 p_note_to_approver => NULL,
4961 p_initiator => 'REQUESTER');
4962 END IF;
4963 ELSE
4964 x_return_status := fnd_api.g_ret_sts_error;
4965 END IF;
4966
4967 EXCEPTION WHEN OTHERS THEN
4968 x_return_status := fnd_api.g_ret_sts_unexp_error ;
4969 IF g_fnd_debug = 'Y' THEN
4970 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
4971 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
4972 l_api_name || '.others_exception', SQLERRM);
4973 END IF;
4974 END IF;
4975 END submit_reqcancel;
4976
4977 /**
4978 * This procedure returns whether an internal line can be cancelled or not
4979 * If the corresponding internal order is cancelled, it returns 'S'.
4980 * It also checks if the line is in oe interface table.
4981 **/
4982 PROCEDURE IS_INTERNAL_LINE_CANCELLABLE(p_api_version IN NUMBER,
4983 x_return_status OUT NOCOPY VARCHAR2,
4984 p_req_line_id IN NUMBER)
4985 IS
4986 l_req_line_id NUMBER:= 0;
4987 l_req_header_id NUMBER := 0;
4988 l_api_name varchar2(50):= 'Is_Internal_Line_Cancellable';
4989 BEGIN
4990 BEGIN
4991
4992 x_return_status := FND_API.G_RET_STS_SUCCESS;
4993
4994 SELECT
4995 prl.requisition_line_id,
4996 prh.requisition_header_id
4997 INTO
4998 l_req_line_id,
4999 l_req_header_id
5000 FROM po_requisition_lines prl,
5001 po_requisition_headers_all prh -- <R12 MOAC>
5002 WHERE prl.requisition_line_id = p_req_line_id AND
5003 prh.requisition_header_id = prl.requisition_header_id AND
5004 (NOT EXISTS
5005 (SELECT 'so line is not cancelled'
5006 FROM
5007 po_requisition_lines PORL,
5008 po_requisition_headers_all PORH, -- <R12 MOAC>
5009 po_system_parameters POSP
5010 WHERE
5011 PORL.requisition_line_id = p_req_line_id AND
5012 PORL.requisition_header_id = PORH.requisition_header_id AND
5013 (OE_ORDER_IMPORT_INTEROP_PUB.Get_Open_Qty(posp.order_source_id, porh.requisition_header_id, porl.requisition_line_id))>0)
5014 AND NOT EXISTS
5015 (SELECT 'line in interface table'
5016 FROM
5017 oe_headers_iface_all SOHI,
5018 po_system_parameters POSP
5019 WHERE
5020 SOHI.orig_sys_document_ref = to_char(PRH.requisition_header_id)
5021 AND SOHI.order_source_id = POSP.order_source_id));
5022
5023 EXCEPTION
5024
5025 WHEN NO_DATA_FOUND THEN
5026 x_return_status := FND_API.G_RET_STS_ERROR;
5027 RETURN;
5028
5029 WHEN OTHERS THEN
5030 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5031 IF (g_fnd_debug = 'Y') THEN
5032 IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
5033 FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
5034 l_api_name || '.others_exception',
5035 p_req_line_id||':'||sqlerrm);
5036 END IF;
5037 END IF;
5038 RETURN;
5039 END;
5040
5041 /* Bug : 4639448
5042 ** Call to check whether the SO shipments are still in process..*/
5043 BEGIN
5044 IF po_req_lines_sv.val_oe_shipment_in_proc(l_req_header_id,
5045 p_req_line_id) = FALSE
5046 THEN
5047 x_return_status := FND_API.G_RET_STS_ERROR;
5048 RETURN;
5049 END IF;
5050 EXCEPTION
5051 WHEN NO_DATA_FOUND THEN
5052 x_return_status := FND_API.G_RET_STS_ERROR;
5053 RETURN;
5054 END;
5055
5056 /* Bug : 4639448
5057 ** Call po_req_lines_sv.val_reqs_qty_received to verify if internal
5058 ** requisition lines which are sourced from inventory, have been received or not.*/
5059 BEGIN
5060 IF po_req_lines_sv.val_reqs_qty_received (l_req_header_id,
5061 p_req_line_id ) = FALSE
5062 THEN
5063 x_return_status := FND_API.G_RET_STS_ERROR;
5064 RETURN;
5065 END IF;
5066 EXCEPTION
5067 WHEN NO_DATA_FOUND THEN
5068 x_return_status := FND_API.G_RET_STS_ERROR;
5069 RETURN;
5070 END;
5071
5072 END IS_INTERNAL_LINE_CANCELLABLE;
5073
5074 PROCEDURE is_SO_line_cancellable(p_api_version IN NUMBER,
5075 x_return_status OUT NOCOPY VARCHAR2,
5076 p_req_line_id IN NUMBER,
5077 p_req_header_id IN NUMBER,
5078 x_cancellable OUT NOCOPY VARCHAR2 )
5079 IS
5080 l_req_line_id NUMBER := 0;
5081 l_req_header_id NUMBER := 0;
5082 l_api_name VARCHAR2(50) := 'is_SO_line_cancellable';
5083 l_log_head CONSTANT VARCHAR2(100) := c_log_head || l_api_name;
5084 l_progress VARCHAR2(3) := '000';
5085 x_update_allowed BOOLEAN := FALSE;
5086 x_cancel_allowed BOOLEAN := FALSE;
5087 X_msg_count number;
5088 X_msg_data varchar2(3000);
5089 l_orgid number;
5090 l_api_version CONSTANT NUMBER := 1.0;
5091 BEGIN
5092 x_return_status := fnd_api.g_ret_sts_success;
5093
5094 IF g_debug_stmt THEN
5095 po_debug.debug_begin(l_log_head);
5096 po_debug.debug_var(l_log_head, l_progress, 'p_api_version', p_api_version);
5097 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
5098 po_debug.debug_var(l_log_head, l_progress, 'p_req_header_id', p_req_header_id);
5099 END IF;
5100
5101 IF NOT FND_API.Compatible_API_Call ( l_api_version ,
5102 p_api_version,
5103 l_api_name ,
5104 G_PKG_NAME )
5105 THEN
5106 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5107 END IF;
5108
5109 IF (p_req_line_id is null and p_req_header_id is null ) then
5110 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5111 END if;
5112
5113 IF (p_req_line_id is null and p_req_header_id is not null ) then
5114 l_progress := '001';
5115
5116
5117 l_orgid := PO_ReqChangeRequestWF_PVT.get_sales_order_org(p_req_hdr_id => p_req_header_id);
5118
5119 IF g_debug_stmt THEN
5120 po_debug.debug_var(l_log_head, l_progress, 'Sales order l_orgid', l_orgid);
5121 END IF;
5122
5123 IF l_orgid is NOT NULL THEN
5124 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
5125 END IF;
5126
5127 l_progress := '002';
5128 -- OM_API.is_req_line_cancellable(l_req_header_id,l_req_line_id,x_return_status);
5129 -- OM API OM_API provided is
5130 OE_Internal_Requisition_Pvt.Is_IReq_Changable
5131 ( P_API_Version => 1.0
5132 , P_internal_req_line_id =>p_req_line_id
5133 , P_internal_req_header_id =>p_req_header_id
5134 , X_Update_Allowed =>x_update_allowed
5135 , X_Cancel_Allowed =>x_cancel_allowed
5136 , X_msg_count =>X_msg_count
5137 , X_msg_data =>X_msg_data
5138 , X_return_status =>x_return_status
5139 );
5140
5141
5142 l_orgid := PO_ReqChangeRequestWF_PVT.get_requisition_org( p_req_hdr_id => p_req_header_id);
5143
5144 IF g_debug_stmt THEN
5145 po_debug.debug_var(l_log_head, l_progress, 'requisition l_orgid', l_orgid);
5146 END IF;
5147
5148 IF l_orgid is NOT NULL THEN
5149 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
5150 END IF;
5151
5152 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
5153 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5154 ElsE
5155 x_cancellable := por_util_pkg.bool_to_varchar(X_Cancel_Allowed);
5156 END IF;
5157
5158 else
5159
5160
5161 SELECT
5162 prl.requisition_line_id,
5163 prh.requisition_header_id
5164 INTO
5165 l_req_line_id,
5166 l_req_header_id
5167 FROM po_requisition_lines prl,
5168 po_requisition_headers_all prh -- <R12 MOAC>
5169 WHERE prl.requisition_line_id = p_req_line_id AND
5170 prh.requisition_header_id = prl.requisition_header_id ;
5171
5172 l_progress := '002';
5173 l_orgid := PO_ReqChangeRequestWF_PVT.get_sales_order_org( p_req_line_id=> p_req_line_id);
5174
5175 IF g_debug_stmt THEN
5176 po_debug.debug_var(l_log_head, l_progress, 'Sales order l_orgid', l_orgid);
5177 END IF;
5178
5179 IF l_orgid is NOT NULL THEN
5180 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
5181 END IF;
5182
5183 l_progress := '003';
5184 -- OM_API.is_req_line_cancellable(l_req_header_id,l_req_line_id,x_return_status);
5185 -- OM API OM_API provided is
5186 OE_Internal_Requisition_Pvt.Is_IReq_Changable
5187 ( P_API_Version => 1.0
5188 , P_internal_req_line_id =>l_req_line_id
5189 , P_internal_req_header_id =>l_req_header_id
5190 , X_Update_Allowed =>x_update_allowed
5191 , X_Cancel_Allowed =>x_cancel_allowed
5192 , X_msg_count =>X_msg_count
5193 , X_msg_data =>X_msg_data
5194 , X_return_status =>x_return_status
5195 );
5196
5197
5198 l_orgid := PO_ReqChangeRequestWF_PVT.get_requisition_org( p_req_line_id=> p_req_line_id );
5199
5200 IF g_debug_stmt THEN
5201 po_debug.debug_var(l_log_head, l_progress, 'Requisition l_orgid', l_orgid);
5202 END IF;
5203
5204 IF l_orgid is NOT NULL THEN
5205 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
5206 END IF;
5207
5208 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
5209 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5210 ElsE
5211 x_cancellable := por_util_pkg.bool_to_varchar(X_Cancel_Allowed);
5212 END IF;
5213 end if;
5214
5215 IF g_debug_stmt THEN
5216 po_debug.debug_var(l_log_head, l_progress, 'x_cancellable', x_cancellable);
5217 po_debug.debug_end(l_log_head);
5218 end if;
5219 EXCEPTION
5220 WHEN no_data_found THEN
5221 x_return_status := fnd_api.g_ret_sts_error;
5222 RETURN;
5223
5224 WHEN OTHERS THEN
5225 x_return_status := fnd_api.g_ret_sts_unexp_error;
5226 IF (g_fnd_debug = 'Y') THEN
5227 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
5228 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
5229 l_api_name || '.others_exception',
5230 p_req_line_id || ':' || SQLERRM);
5231 END IF;
5232 END IF;
5233 RETURN;
5234
5235 END is_SO_line_cancellable;
5236
5237 /**
5238 * This procedure returns whether an internal line can be updated
5239 * with quantity and need by date or not
5240 **/
5241 PROCEDURE is_internal_line_changeable(p_api_version IN NUMBER
5242 , X_Update_Allowed OUT NOCOPY VARCHAR2
5243 , X_Cancel_Allowed OUT NOCOPY VARCHAR2
5244 , x_return_status OUT NOCOPY VARCHAR2
5245 , p_req_line_id IN NUMBER)
5246 IS
5247 l_req_line_id NUMBER := 0;
5248 l_req_header_id NUMBER := 0;
5249 l_api_name VARCHAR2(50) := 'Is_Internal_Line_Changeable';
5250 l_log_head CONSTANT VARCHAR2(100) := c_log_head || l_api_name;
5251 l_progress VARCHAR2(3) := '000';
5252 X_msg_count number;
5253 X_msg_data varchar2(3000);
5254 l_Update_Allowed boolean :=FALSE;
5255 l_Cancel_Allowed boolean :=FALSE;
5256 l_api_version CONSTANT NUMBER := 1.0;
5257 l_orgid number;
5258 BEGIN
5259
5260 IF NOT FND_API.Compatible_API_Call ( l_api_version ,
5261 p_api_version,
5262 l_api_name ,
5263 G_PKG_NAME )
5264 THEN
5265 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5266 END IF;
5267
5268 x_return_status := fnd_api.g_ret_sts_success;
5269 l_update_allowed := FALSE;
5270 l_cancel_allowed := FALSE;
5271
5272 IF g_debug_stmt THEN
5273 po_debug.debug_begin(l_log_head);
5274 po_debug.debug_var(l_log_head, l_progress, 'p_api_version', p_api_version);
5275 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
5276 END IF;
5277
5278 SELECT
5279 prl.requisition_line_id,
5280 prl.requisition_header_id
5281 INTO
5282 l_req_line_id,
5283 l_req_header_id
5284 FROM po_requisition_lines_all prl
5285 WHERE prl.requisition_line_id = p_req_line_id;
5286
5287 l_progress := '001';
5288
5289 l_orgid := PO_ReqChangeRequestWF_PVT.get_sales_order_org(p_req_line_id => p_req_line_id);
5290 IF g_debug_stmt THEN
5291 po_debug.debug_var(l_log_head, l_progress, 'Sales order l_orgid', l_orgid);
5292 END IF;
5293
5294 IF l_orgid is NOT NULL THEN
5295 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
5296 END IF;
5297
5298
5299 -- OM_API.is_req_line_changeable(l_req_header_id,l_req_line_id,x_return_status);
5300 -- OM API OM_API provided is
5301 OE_Internal_Requisition_Pvt.Is_IReq_Changable
5302 ( P_API_Version => 1.0
5303 , P_internal_req_line_id =>l_req_line_id
5304 , P_internal_req_header_id =>l_req_header_id
5305 , X_Update_Allowed =>l_update_allowed
5306 , X_Cancel_Allowed =>l_cancel_allowed
5307 , X_msg_count =>X_msg_count
5308 , X_msg_data =>X_msg_data
5309 , X_return_status =>x_return_status
5310 );
5311
5312
5313 l_orgid := PO_ReqChangeRequestWF_PVT.get_requisition_org(p_req_line_id => p_req_line_id);
5314 IF g_debug_stmt THEN
5315 po_debug.debug_var(l_log_head, l_progress, 'Requisition l_orgid', l_orgid);
5316 END IF;
5317
5318 IF l_orgid is NOT NULL THEN
5319 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
5320 END IF;
5321
5322 x_update_allowed := POR_UTIL_PKG.bool_to_varchar(l_update_allowed);
5323 x_cancel_allowed := POR_UTIL_PKG.bool_to_varchar(l_cancel_allowed);
5324
5325 IF g_debug_stmt THEN
5326 po_debug.debug_var(l_log_head, l_progress, 'x_update_allowed', x_update_allowed);
5327 po_debug.debug_var(l_log_head, l_progress, 'x_cancel_allowed', x_cancel_allowed);
5328 po_debug.debug_end(l_log_head);
5329
5330 END IF;
5331 EXCEPTION
5332
5333 WHEN no_data_found THEN
5334 x_return_status := fnd_api.g_ret_sts_error;
5335 RETURN;
5336
5337 WHEN OTHERS THEN
5338 x_return_status := fnd_api.g_ret_sts_unexp_error;
5339 IF (g_fnd_debug = 'Y') THEN
5340 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
5341 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
5342 l_api_name || '.others_exception',
5343 p_req_line_id || ':' || SQLERRM);
5344 END IF;
5345 END IF;
5346 RETURN;
5347
5348 END is_internal_line_changeable;
5349
5350 /*--------------------------------------------------------------
5351 **Save_IReqCancel: takes in a PLSQL table as input, containing
5352 **cancellation request. No Validation is done here. This API
5353 **simply insert records into PO_CHANGE_REQUESTS table
5354 ---------------------------------------------------------------*/
5355
5356
5357 PROCEDURE save_ireqcancel(p_api_version IN NUMBER,
5358 x_return_status OUT NOCOPY VARCHAR2,
5359 p_req_hdr_id IN NUMBER,
5360 p_cancel_table IN po_req_cancel_table,
5361 p_change_request_group_id OUT NOCOPY NUMBER,
5362 l_progress OUT NOCOPY VARCHAR2,
5363 p_grp_id IN NUMBER)
5364 IS
5365 l_api_name VARCHAR2(50) := 'Save_IReqCancel';
5366 l_chn_req_id NUMBER;
5367 l_req_num po_requisition_headers_all.segment1%TYPE;
5368 l_req_line_num NUMBER;
5369 l_req_user_id NUMBER;
5370 l_line_loc_id NUMBER;
5371 l_po_header_id NUMBER;
5372 l_po_release_id NUMBER;
5373 l_po_revision_num NUMBER;
5374 l_preparer_id NUMBER;
5375 l_req_price NUMBER;
5376 l_req_currency_price NUMBER;
5377 l_req_quantity NUMBER;
5378 l_req_date DATE;
5379 l_po_num po_change_requests.ref_po_num%TYPE;
5380 l_po_release_num NUMBER;
5381 l_log_head CONSTANT VARCHAR2(100) := c_log_head || l_api_name;
5382
5383 BEGIN
5384 l_progress := '000';
5385 l_req_user_id := fnd_global.user_id;
5386 IF g_debug_stmt THEN
5387 po_debug.debug_var(l_log_head, l_progress, 'p_api_version=', p_api_version);
5388 po_debug.debug_var(l_log_head, l_progress, 'p_req_hdr_id=', p_req_hdr_id);
5389 po_debug.debug_var(l_log_head, l_progress, 'p_grp_id=', p_grp_id);
5390 END IF;
5391
5392 IF(p_grp_id IS NULL) THEN
5393 SELECT po_chg_request_seq.nextval INTO p_change_request_group_id FROM dual;
5394 DELETE FROM po_change_requests
5395 WHERE document_header_id = p_req_hdr_id
5396 AND initiator = 'REQUESTER'
5397 AND request_status = 'SYSTEMSAVE';
5398
5399 IF g_debug_stmt THEN
5400 po_debug.debug_var(l_log_head, l_progress,'In PO_CHANGE_REQUESTS records deleted=', SQL%rowcount);
5401 po_debug.debug_var(l_log_head, l_progress, 'p_change_request_group_id=', p_change_request_group_id);
5402 END IF;
5403
5404 ELSE
5405 p_change_request_group_id := p_grp_id;
5406 END IF;
5407 l_progress := '001';
5408
5409 IF g_debug_stmt THEN
5410 po_debug.debug_var(l_log_head, l_progress,'In PO_CHANGE_REQUESTS records deleted=', SQL%rowcount);
5411 po_debug.debug_var(l_log_head, l_progress, 'p_cancel_table.req_line_id.count=', p_cancel_table.req_line_id.count);
5412 END IF;
5413
5414
5415
5416 FOR i IN 1..p_cancel_table.req_line_id.count
5417 LOOP
5418
5419 SELECT po_chg_request_seq.nextval INTO l_chn_req_id FROM dual;
5420 SELECT
5421 prha.segment1,
5422 prla.line_num,
5423 prha.preparer_id,
5424 prla.unit_price,
5425 prla.quantity,
5426 prla.need_by_date
5427 INTO
5428 l_req_num,
5429 l_req_line_num,
5430 l_preparer_id,
5431 l_req_price,
5432 l_req_quantity,
5433 l_req_date
5434 FROM
5435 po_requisition_headers_all prha,
5436 po_requisition_lines_all prla
5437 WHERE prla.requisition_line_id = p_cancel_table.req_line_id(i)
5438 AND prla.requisition_header_id = prha.requisition_header_id;
5439
5440 /* if(l_line_loc_id is not null) then
5441 select
5442 po_release_id,
5443 po_header_id
5444 into
5445 l_po_release_id,
5446 l_po_header_id
5447 from po_line_locations_all
5448 where line_location_id = l_line_loc_id;
5449 if(l_po_release_id is null) then
5450 select revision_num,segment1 into
5451 l_po_revision_num, l_po_num
5452 from po_headers_all
5453 where po_header_id = l_po_header_id;
5454
5455 -- bug 5191164.
5456 -- Need to null out l_po_release_num for PO records
5457 l_po_release_num := null;
5458
5459 else
5460 -- get po_number of the source document for RELEASE
5461 select segment1 into l_po_num
5462 from po_headers_all
5463 where po_header_id = l_po_header_id;
5464
5465 select revision_num, release_num
5466 into l_po_revision_num, l_po_release_num
5467 from po_releases_all
5468 where po_release_id = l_po_release_id;
5469 end if;
5470 end if;
5471 */
5472 l_progress := '002';
5473 INSERT INTO po_change_requests
5474 (
5475 change_request_group_id,
5476 change_request_id,
5477 initiator,
5478 action_type,
5479 request_reason,
5480 request_level,
5481 request_status,
5482 document_type,
5483 document_header_id,
5484 document_num,
5485 created_by,
5486 creation_date,
5487 document_line_id,
5488 document_line_number,
5489 last_updated_by,
5490 last_update_date,
5491 last_update_login,
5492 requester_id,
5493 change_active_flag,
5494 old_price,
5495 old_quantity,
5496 old_need_by_date
5497 )
5498 VALUES
5499 (
5500 p_change_request_group_id,
5501 l_chn_req_id,
5502 'REQUESTER',
5503 'CANCELLATION',
5504 p_cancel_table.change_reason(i),
5505 'LINE',
5506 'SYSTEMSAVE',
5507 'REQ',
5508 p_req_hdr_id,
5509 l_req_num,
5510 l_req_user_id,
5511 SYSDATE,
5512 p_cancel_table.req_line_id(i),
5513 l_req_line_num,
5514 l_req_user_id,
5515 SYSDATE,
5516 l_req_user_id,
5517 l_preparer_id,
5518 'Y',
5519 l_req_price,
5520 l_req_quantity,
5521 l_req_date
5522 );
5523
5524 IF g_debug_stmt THEN
5525 po_debug.debug_var(l_log_head, l_progress,'NO of records inderted in po_change_requests =', SQL%rowcount);
5526 po_debug.debug_var(l_log_head, l_progress, 'p_change_request_group_id=', p_change_request_group_id);
5527 po_debug.debug_var(l_log_head, l_progress,'l_chn_req_id =', l_chn_req_id );
5528 po_debug.debug_stmt(l_log_head, l_progress,'INITIATOR =REQUESTER' );
5529 po_debug.debug_stmt(l_log_head, l_progress, 'ACTION_TYPE=CANCELLATION' );
5530 po_debug.debug_var(l_log_head, l_progress,'p_cancel_table.change_reason(i) =', p_cancel_table.change_reason(i) );
5531 po_debug.debug_stmt(l_log_head, l_progress, 'REQUEST_LEVEL=LINE' );
5532 po_debug.debug_stmt(l_log_head, l_progress, 'REQUEST_STATUS=SYSTEMSAVE' );
5533 po_debug.debug_stmt(l_log_head, l_progress, 'DOCUMENT_TYPE=REQ' );
5534 po_debug.debug_var(l_log_head, l_progress,'p_req_hdr_id =', p_req_hdr_id );
5535 po_debug.debug_var(l_log_head, l_progress,'l_req_num =', l_req_num );
5536 po_debug.debug_var(l_log_head, l_progress,'l_req_user_id =', l_req_user_id );
5537 po_debug.debug_var(l_log_head, l_progress,'p_cancel_table.req_line_id(i) =', p_cancel_table.req_line_id(i) );
5538 po_debug.debug_var(l_log_head, l_progress,'l_req_line_num =', l_req_line_num );
5539 po_debug.debug_var(l_log_head, l_progress,'l_req_user_id =', l_req_user_id );
5540 po_debug.debug_var(l_log_head, l_progress,'l_req_user_id =', l_req_user_id );
5541 po_debug.debug_var(l_log_head, l_progress,'l_preparer_id =', l_preparer_id );
5542 po_debug.debug_stmt(l_log_head, l_progress, 'CHANGE_ACTIVE_FLAG=Y' );
5543 po_debug.debug_var(l_log_head, l_progress,'l_req_price =', l_req_price );
5544 po_debug.debug_var(l_log_head, l_progress,'l_req_quantity =', l_req_quantity );
5545 po_debug.debug_var(l_log_head, l_progress, 'l_req_date=', l_req_date);
5546 END IF;
5547
5548 END LOOP;
5549
5550
5551 x_return_status := fnd_api.g_ret_sts_success;
5552 EXCEPTION WHEN OTHERS THEN
5553 x_return_status := fnd_api.g_ret_sts_unexp_error;
5554 IF g_fnd_debug = 'Y' THEN
5555 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
5556 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
5557 l_api_name || '.others_exception', l_progress || ':' || SQLERRM);
5558 END IF;
5559 END IF;
5560 END save_ireqcancel;
5561
5562 /*-------------------------------------------------------------------------------------------------
5563 *This API is called directly from the UI. It will have PLSQL tables as input, which contain change/cancel requests
5564 *1. Validate the requests
5565 *2. If ALL valid, same them into PO_CHANGE_REQUESTS table
5566 *x_return_status = FND_API.G_RET_STS_SUCCESS => Everything is Valid, and records are saved into change table
5567 * FND_API.G_RET_STS_ERROR => Caught Errors, thus no records are saved into change table
5568 * FND_API.G_RET_STS_UNEXP_ERROR => Unexpected Errors Occur in the API
5569 *x_retMsg will indicate details/location of errors.
5570 ---------------------------------------------------------------------------------------------------*/
5571 PROCEDURE save_ireqchange(p_api_version IN NUMBER,
5572 x_return_status OUT NOCOPY VARCHAR2,
5573 p_req_hdr_id IN NUMBER,
5574 p_change_table IN po_req_change_table,
5575 p_cancel_table IN po_req_cancel_table,
5576 p_change_request_group_id OUT NOCOPY NUMBER,
5577 x_retmsg OUT NOCOPY VARCHAR2,
5578 x_errtable OUT NOCOPY po_req_change_err_table)
5579 IS
5580 l_api_name VARCHAR2(50) := 'Save_IReqChange';
5581 l_req_change_table change_tbl_type;
5582 l_dummy NUMBER;
5583 y NUMBER := 1;
5584 l_change_result VARCHAR2(1) := fnd_api.g_ret_sts_success;
5585 l_cancel_result VARCHAR2(1);
5586 l_err_line_id_tbl po_tbl_number;
5587 l_err_line_num_tbl po_tbl_number;
5588 l_err_dist_id_tbl po_tbl_number;
5589 l_err_dist_num_tbl po_tbl_number;
5590 l_err_error_attr_tbl po_tbl_varchar30;
5591 l_err_msg_count_tbl po_tbl_number;
5592 l_err_msg_data_tbl po_tbl_varchar2000;
5593 l_irc_status VARCHAR2(1);
5594 l_irc_err_msg VARCHAR2(2000);
5595 l_catch_exception EXCEPTION;
5596 l_req_dist_id NUMBER;
5597 l_lineqty_status VARCHAR2(1);
5598 l_lineqty_msg VARCHAR2(2000);
5599 l_req_num NUMBER;
5600 l_req_dist_number NUMBER;
5601 l_old_req_date DATE;
5602 l_old_req_quantity NUMBER;
5603 l_old_amount NUMBER;
5604 l_preparer_id NUMBER;
5605 l_log_head CONSTANT VARCHAR2(100) := c_log_head || l_api_name;
5606 l_progress VARCHAR2(3) := '000';
5607
5608
5609 BEGIN
5610
5611 IF g_debug_stmt THEN
5612 po_debug.debug_begin(l_log_head);
5613 po_debug.debug_var(l_log_head, l_progress, 'p_api_version', p_api_version);
5614 po_debug.debug_var(l_log_head, l_progress, 'p_req_hdr_id', p_req_hdr_id);
5615 END IF;
5616
5617
5618 DELETE FROM po_change_requests
5619 WHERE document_header_id = p_req_hdr_id
5620 AND request_status = 'SYSTEMSAVE'
5621 AND initiator = 'REQUESTER';
5622
5623 IF g_debug_stmt THEN
5624 po_debug.debug_var(l_log_head, l_progress,'NO of rows deleted from PO_CHANGE_REQUESTS', SQL%rowcount);
5625 END IF;
5626
5627
5628
5629 x_retmsg := 'SRCH000';
5630
5631 IF(p_change_table IS NOT NULL) THEN
5632 --Input Change Table is p_change_table, which is a table of objects. The following "for" loop
5633 --Copy the data from p_change_table to l_req_change_table, which is a table of record
5634 IF g_debug_stmt THEN
5635 po_debug.debug_var(l_log_head, l_progress,'p_change_table is not null and count=', p_change_table.req_line_id.count);
5636 END IF;
5637
5638
5639
5640 FOR x IN 1..p_change_table.req_line_id.count
5641 LOOP
5642 IF(p_change_table.need_by(x) IS NOT NULL
5643 -- OR p_change_table.amount(x) is not null
5644 OR p_change_table.quantity(x) IS NOT NULL) THEN
5645
5646 IF g_debug_stmt THEN
5647 po_debug.debug_stmt(l_log_head, l_progress,'In p_change_table need by date or quantity is changed');
5648 END IF;
5649
5650
5651 BEGIN
5652 SELECT
5653 prha.segment1,
5654 prda.distribution_id,
5655 prla.need_by_date,
5656 prla.quantity,
5657 prla.amount,
5658 prha.preparer_id
5659 INTO
5660 l_req_num,
5661 l_req_dist_number,
5662 l_old_req_date,
5663 l_old_req_quantity,
5664 l_old_amount,
5665 l_preparer_id
5666 FROM
5667 po_requisition_lines_all prla,
5668 po_requisition_headers_all prha,
5669 po_req_distributions_all prda
5670 WHERE
5671 prha.requisition_header_id = p_req_hdr_id
5672 AND prha.requisition_header_id = prla.requisition_header_id
5673 AND prla.requisition_line_id = p_change_table.req_line_id(x)
5674 AND prda.requisition_line_id = prla.requisition_line_id;
5675 EXCEPTION
5676 WHEN OTHERS THEN
5677 NULL;
5678 END;
5679
5680
5681
5682 l_req_change_table(y).action_type := 'MODIFICATION';
5683 l_req_change_table(y).request_level := 'LINE';
5684 l_req_change_table(y).request_status := 'SYSTEMSAVE';
5685 l_req_change_table(y).initiator := 'REQUESTER';
5686 l_req_change_table(y).document_header_id := p_req_hdr_id;
5687 l_req_change_table(y).document_num := l_req_num;
5688 l_req_change_table(y).document_line_id := p_change_table.req_line_id(x);
5689 l_req_change_table(y).document_distribution_id := l_req_dist_number;
5690 l_req_change_table(y).old_quantity := l_old_req_quantity;
5691 l_req_change_table(y).old_date := l_old_req_date;
5692 l_req_change_table(y).requester_id := l_preparer_id;
5693 l_req_change_table(y).old_budget_amount := l_old_amount;
5694
5695 IF g_debug_stmt THEN
5696 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).ACTION_TYPE', l_req_change_table(y).action_type);
5697 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).REQUEST_LEVEL', l_req_change_table(y).request_level);
5698 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).request_status', l_req_change_table(y).request_status);
5699 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).INITIATOR', l_req_change_table(y).initiator);
5700 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).DOCUMENT_HEADER_ID', l_req_change_table(y).document_header_id);
5701 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).DOCUMENT_NUM', l_req_change_table(y).document_num);
5702 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).DOCUMENT_LINE_ID', l_req_change_table(y).document_line_id);
5703 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).DOCUMENT_DISTRIBUTION_ID', l_req_change_table(y).document_distribution_id);
5704 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).OLD_QUANTITY', l_req_change_table(y).old_quantity);
5705 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).old_date', l_req_change_table(y).old_date);
5706 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).REQUESTER_ID', l_req_change_table(y).requester_id);
5707 po_debug.debug_var(l_log_head, l_progress, 'l_req_change_table(y).OLD_BUDGET_AMOUNT', l_req_change_table(y).old_budget_amount);
5708
5709 END IF;
5710
5711 /*
5712 if(p_change_table.amount(x) is not null) then
5713
5714 l_req_change_table(y).NEW_BUDGET_AMOUNT := p_change_table.amount(x);
5715 l_req_change_table(y).REQUEST_REASON := p_change_table.change_reason(x);
5716 y:=y+1;
5717 END IF; */
5718
5719 IF (p_change_table.need_by(x) IS NOT NULL) THEN
5720
5721 l_req_change_table(y).new_date := p_change_table.need_by(x);
5722 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
5723 -- y:=y+1;
5724 END IF;
5725 IF(p_change_table.quantity(x) IS NOT NULL) THEN
5726
5727 l_req_change_table(y).new_quantity := p_change_table.quantity(x);
5728 l_req_change_table(y).request_reason := p_change_table.change_reason(x);
5729 -- y:=y+1;
5730 END IF;
5731 y := y + 1;
5732 END IF;
5733
5734 END LOOP;
5735
5736
5737
5738 --Validate the Change Requests, by passing in l_req_change_table, a table of records
5739 --Initialize the Error Table
5740 l_err_line_id_tbl := po_tbl_number();
5741 l_err_line_num_tbl := po_tbl_number();
5742 l_err_dist_id_tbl := po_tbl_number();
5743 l_err_dist_num_tbl := po_tbl_number();
5744 l_err_error_attr_tbl := po_tbl_varchar30();
5745 l_err_msg_count_tbl := po_tbl_number();
5746 l_err_msg_data_tbl := po_tbl_varchar2000();
5747 x_errtable := po_req_change_err_table(
5748 l_err_line_id_tbl,
5749 l_err_line_num_tbl,
5750 l_err_dist_id_tbl,
5751 l_err_dist_num_tbl,
5752 l_err_error_attr_tbl,
5753 l_err_msg_count_tbl,
5754 l_err_msg_data_tbl);
5755
5756 -- Validate_Changes(p_req_hdr_id,l_req_change_table,l_change_result,x_retMsg,x_errTable);
5757 -- these validations are done online
5758 END IF;
5759
5760 --If ALL changes are valid, we will insert change records, and insert cancel records(if any)
5761 --if(l_change_result = FND_API.G_RET_STS_SUCCESS) then
5762 x_retmsg := 'SRCH004';
5763 SELECT po_chg_request_seq.nextval INTO p_change_request_group_id FROM dual;
5764
5765
5766
5767 IF g_debug_stmt THEN
5768 po_debug.debug_var(l_log_head, l_progress, 'p_change_request_group_id=', p_change_request_group_id);
5769 END IF;
5770
5771 insert_reqchange(l_req_change_table, p_change_request_group_id);
5772 x_retmsg := 'SRCH005';
5773
5774 update_internalrecordswithtax(p_change_request_group_id);
5775 x_retmsg := 'SRCH006';
5776
5777
5778
5779 ---Insert_LineQuantityOrAmount(p_change_request_group_id); not inserting derived record in po_change_request
5780 l_change_result := fnd_api.g_ret_sts_success;
5781 x_retmsg := 'SRCH0061';
5782
5783 -- Insert_PriceBreakRows(p_change_request_group_id);
5784
5785 x_retmsg := 'SRCH0062';
5786
5787 --Process Cancellation Requests
5788 l_cancel_result := fnd_api.g_ret_sts_success;
5789
5790 IF(p_cancel_table IS NOT NULL) THEN
5791 save_ireqcancel(1.0, l_cancel_result, p_req_hdr_id, p_cancel_table, l_dummy, x_retmsg, p_change_request_group_id);
5792 END IF;
5793
5794 --x_return_status := l_cancel_result;
5795 x_return_status := fnd_api.g_ret_sts_success;
5796
5797 IF(l_change_result = fnd_api.g_ret_sts_error) THEN
5798 x_return_status := fnd_api.g_ret_sts_error;
5799 x_retmsg := 'SRCH007';
5800 ELSE
5801 x_return_status := fnd_api.g_ret_sts_success;
5802
5803 END IF;
5804
5805 EXCEPTION
5806 WHEN OTHERS THEN
5807 x_retmsg := 'SRCHUNEXP:' || x_retmsg || ':' || SQLERRM;
5808 x_return_status := fnd_api.g_ret_sts_unexp_error;
5809
5810
5811
5812 IF g_fnd_debug = 'Y' THEN
5813 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
5814 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
5815 l_api_name || '.others_exception', x_retmsg);
5816 END IF;
5817 END IF;
5818 END save_ireqchange;
5819
5820
5821
5822 /*
5823 **Submit_IReqCancel: Final procedure call for transaction which involves requester
5824 **cancelling a req line.
5825 **This API could be called from the Cancel Flow UI directly, or from Submit_ReqChange API.
5826 */
5827 PROCEDURE submit_ireqcancel (
5828 p_api_version IN NUMBER,
5829 x_return_status OUT NOCOPY VARCHAR2,
5830 p_group_id IN NUMBER,
5831 x_retmsg OUT NOCOPY VARCHAR2,
5832 p_errtable OUT NOCOPY po_req_change_err_table,
5833 p_origin IN VARCHAR2)
5834 IS
5835 l_api_name VARCHAR2(50) := 'Submit_IReqCancel';
5836 l_log_head CONSTANT VARCHAR2(100) := c_log_head || l_api_name;
5837 l_line_id NUMBER;
5838 l_result VARCHAR2(1);
5839 l_progress VARCHAR2(3):='000';
5840 i NUMBER := 1;
5841 l_canerr_line_id_tbl po_tbl_number;
5842 l_canerr_line_num_tbl po_tbl_number;
5843 l_canerr_dist_id_tbl po_tbl_number;
5844 l_canerr_dist_num_tbl po_tbl_number;
5845 l_canerr_error_attr_tbl po_tbl_varchar30;
5846 l_canerr_msg_count_tbl po_tbl_number;
5847 l_canerr_msg_data_tbl po_tbl_varchar2000;
5848 l_line_location_id NUMBER;
5849 l_chn_req_id NUMBER;
5850 l_req_hdr_id NUMBER;
5851 l_wf_status VARCHAR2(1);
5852 l_workflow_needed VARCHAR2(1) := 'Y';
5853 CURSOR l_cancels_csr(grp_id NUMBER) IS
5854 SELECT
5855 pcr.document_header_id,
5856 pcr.document_line_id,
5857 prla.line_location_id,
5858 pcr.change_request_id
5859 FROM
5860 po_change_requests pcr,
5861 po_requisition_lines_all prla
5862 WHERE pcr.action_type = 'CANCELLATION'
5863 AND pcr.change_request_group_id = grp_id
5864 AND pcr.document_line_id = prla.requisition_line_id;
5865 BEGIN
5866 IF g_debug_stmt THEN
5867 po_debug.debug_var(l_log_head, l_progress, 'p_group_id', p_group_id);
5868 END IF;
5869
5870
5871 l_canerr_line_id_tbl := po_tbl_number();
5872 l_canerr_line_num_tbl := po_tbl_number();
5873 l_canerr_dist_id_tbl := po_tbl_number();
5874 l_canerr_dist_num_tbl := po_tbl_number();
5875 l_canerr_error_attr_tbl := po_tbl_varchar30();
5876 l_canerr_msg_count_tbl := po_tbl_number();
5877 l_canerr_msg_data_tbl := po_tbl_varchar2000();
5878
5879 p_errtable := po_req_change_err_table(
5880 l_canerr_line_id_tbl ,
5881 l_canerr_line_num_tbl,
5882 l_canerr_dist_id_tbl ,
5883 l_canerr_dist_num_tbl,
5884 l_canerr_error_attr_tbl,
5885 l_canerr_msg_count_tbl ,
5886 l_canerr_msg_data_tbl );
5887
5888 --Calling PO Cancel API to check if the corresponding PO Shipment Can be cancelled.
5889 OPEN l_cancels_csr(p_group_id);
5890 LOOP
5891 FETCH l_cancels_csr INTO
5892 l_req_hdr_id, l_line_id, l_line_location_id, l_chn_req_id;
5893 EXIT WHEN l_cancels_csr%notfound;
5894 /* if(l_line_location_id is null) then
5895 update po_change_requests
5896 set request_status = 'ACCEPTED'
5897 where change_request_id = l_chn_req_id;
5898 else */--since only lines on so is cancellable so wf is always needed
5899 l_workflow_needed := 'Y';
5900
5901 -- end if;
5902 END LOOP;
5903
5904 CLOSE l_cancels_csr;
5905
5906 x_return_status := fnd_api.g_ret_sts_success;
5907
5908 --If all requests are valid, update status to "NEW", and kick off Workflow
5909
5910 IF(p_errtable.req_line_id.count = 0) THEN
5911
5912
5913
5914
5915 UPDATE po_change_requests
5916 SET request_status = 'NEW'
5917 WHERE change_request_group_id = p_group_id
5918 AND request_status = 'SYSTEMSAVE';
5919
5920
5921
5922
5923 IF (p_origin IS NULL AND l_workflow_needed = 'Y') THEN
5924
5925 po_reqchangerequestwf_pvt.submit_internal_req_change(
5926 p_api_version => 1.0,
5927 p_commit => fnd_api.g_false,
5928 x_return_status => l_wf_status,
5929 p_req_header_id => l_req_hdr_id,
5930 p_note_to_approver => NULL,
5931 p_initiator => 'REQUESTER');
5932 END IF;
5933
5934
5935
5936
5937 ELSE
5938 x_return_status := fnd_api.g_ret_sts_error;
5939 END IF;
5940
5941 EXCEPTION WHEN OTHERS THEN
5942 x_return_status := fnd_api.g_ret_sts_unexp_error ;
5943 IF g_fnd_debug = 'Y' THEN
5944 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
5945 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
5946 l_api_name || '.others_exception', SQLERRM);
5947 END IF;
5948 END IF;
5949 END submit_ireqcancel;
5950
5951
5952 PROCEDURE get_preparer_name(
5953 p_req_hdr_id IN NUMBER
5954 , x_preparer_name OUT NOCOPY VARCHAR2
5955 , x_return_status OUT NOCOPY VARCHAR2
5956 )
5957 IS
5958 l_preparer_id NUMBER;
5959 x_preparer_display_name varchar2(360);
5960 BEGIN
5961
5962 SELECT preparer_id into l_preparer_id
5963 FROM po_requisition_headers_all
5964 WHERE requisition_header_id = p_req_hdr_id;
5965
5966 WF_DIRECTORY.GetUserName( 'PER',
5967 l_preparer_id,
5968 x_preparer_name,
5969 x_preparer_display_name);
5970
5971
5972 x_return_status := fnd_api.g_ret_sts_success;
5973 END get_preparer_name;
5974
5975
5976
5977
5978
5979 PROCEDURE update_reqcancel_from_so( p_req_line_id IN NUMBER
5980 , p_req_cancel_qty IN NUMBER
5981 , p_req_cancel_all IN BOOLEAN
5982 ,x_return_status OUT NOCOPY VARCHAR2 )
5983 IS
5984
5985 l_req_line_id NUMBER;
5986 l_bool_ret_sts BOOLEAN;
5987 l_return_status VARCHAR2(10);
5988 l_open_quantity number;
5989 l_quantity_delivered NUMBER;
5990 l_quantity NUMBER;
5991 l_delta_quantity number;
5992 l_log_head CONSTANT VARCHAR2(100) := c_log_head || 'update_reqcancel_from_so';
5993 l_progress varchar2(3):='000';
5994 l_count number:=0;
5995 BEGIN
5996
5997 -- Bug 8235698: Check whether there is a pending change on this
5998 -- requisition line , if there exists one then
5999 -- return Error to the SO (OM) API.
6000
6001 BEGIN
6002
6003 SELECT COUNT(*) INTO l_count FROM po_change_requests
6004 WHERE request_status in ( 'NEW' , 'MGR_PRE_APP' , 'MGR_APP')
6005 AND DOCUMENT_TYPE= 'REQ'
6006 AND REQUEST_LEVEL= 'LINE'
6007 AND DOCUMENT_LINE_ID=p_req_line_id;
6008
6009 EXCEPTION
6010 WHEN no_data_found THEN
6011 l_count:=0;
6012 END;
6013
6014 IF (l_count <> 0 ) THEN
6015
6016 x_return_status := FND_API.G_RET_STS_ERROR;
6017 IF g_debug_stmt THEN
6018 po_debug.debug_begin(l_log_head);
6019
6020 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
6021 po_debug.debug_var(l_log_head, l_progress, 'No of po_change_requests on req line', l_count);
6022 END IF;
6023
6024 return;
6025 END IF;
6026 -- have save point
6027 SAVEPOINT update_reqcancel_from_so_sp;
6028 /*
6029 * ALGORITHM : For each req line or perticular line
6030 Step 1: Retrive the open receiving quantity INTO l_open_quantity
6031 Step 2 : Retrive the REQ LINE quantity INTO l_quantity
6032 */
6033
6034 l_return_status := fnd_api.g_ret_sts_success;
6035 l_progress:='001';
6036
6037 IF g_debug_stmt THEN
6038 po_debug.debug_begin(l_log_head);
6039 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
6040 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_qty', p_req_cancel_qty);
6041 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_all', p_req_cancel_all);
6042 END IF;
6043
6044 IF (p_req_line_id IS NOT NULL ) THEN
6045
6046 IF p_req_cancel_all THEN
6047
6048 po_reqchangerequestwf_pvt.req_line_CANCEL(
6049 p_req_line_id => p_req_line_id,
6050 x_return_status =>l_return_status);
6051 ELSE
6052
6053 BEGIN
6054 SELECT QUANTITY, nvl(QUANTITY_DELIVERED,0)
6055 INTO l_quantity, l_quantity_delivered
6056 FROM po_requisition_lines_all
6057 WHERE REQUISITION_LINE_ID=p_req_line_id;
6058 EXCEPTION
6059 WHEN OTHERS THEN
6060 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6061 END;
6062
6063 IF g_debug_stmt THEN
6064 po_debug.debug_var(l_log_head, l_progress, 'l_quantity', l_quantity);
6065 po_debug.debug_var(l_log_head, l_progress, 'l_quantity_delivered', l_quantity_delivered);
6066 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_qty', p_req_cancel_qty);
6067 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_all', p_req_cancel_all);
6068 END IF;
6069
6070 IF (p_req_cancel_qty IS NOT NULL AND l_quantity IS NOT NULL ) THEN
6071 IF (l_quantity - p_req_cancel_qty > 0) THEN
6072 -- UPDATE THE REQ LINE WITH DELTA QUANTITY AS
6073 l_delta_quantity := (-1) * p_req_cancel_qty ;
6074
6075 IF g_debug_stmt THEN
6076 po_debug.debug_var(l_log_head, l_progress, 'l_delta_quantity', l_delta_quantity);
6077 END IF;
6078
6079 po_reqchangerequestwf_pvt.update_reqline_quan_changes(
6080 p_req_line_id => p_req_line_id,
6081 p_delta_quantity=> l_delta_quantity,
6082 x_return_status =>l_return_status);
6083
6084 ELSE
6085 po_reqchangerequestwf_pvt.req_line_CANCEL(
6086 p_req_line_id => p_req_line_id,
6087 x_return_status =>l_return_status);
6088 END IF;
6089 END IF;
6090 END IF;
6091 END IF;
6092
6093
6094
6095 IF g_debug_stmt THEN
6096 po_debug.debug_var(l_log_head, l_progress, 'l_return_status', l_return_status);
6097 END IF;
6098
6099 x_return_status := fnd_api.g_ret_sts_success;
6100
6101 EXCEPTION
6102 WHEN OTHERS THEN
6103 x_return_status:= FND_API.G_RET_STS_ERROR;
6104 ROLLBACK TO update_reqcancel_from_so_sp;
6105 END update_reqcancel_from_so;
6106
6107
6108
6109
6110 PROCEDURE update_reqchange_from_so(
6111 p_req_line_id IN NUMBER
6112 , p_delta_quantity IN NUMBER
6113 , p_new_need_by_date IN DATE
6114 , x_return_status OUT NOCOPY VARCHAR2
6115 )
6116 IS
6117
6118 l_bool_ret_sts BOOLEAN;
6119 l_mtl_supply_quantity NUMBER;
6120 l_return_status varchar2(10);
6121 l_sync_need_by varchar2(3);
6122 l_count number:=0;
6123
6124 BEGIN
6125 -- Check whether there is a pending change on this
6126 -- requisition line , if there exists one then
6127 -- return Error to the SO (OM) API.
6128
6129 BEGIN
6130 SELECT count(*) INTO l_count
6131 FROM PO_change_requests
6132 WHERE request_status in ( 'NEW' , 'MGR_PRE_APP' , 'MGR_APP')
6133 AND DOCUMENT_TYPE= 'REQ'
6134 AND REQUEST_LEVEL= 'LINE'
6135 AND DOCUMENT_LINE_ID=p_req_line_id;
6136
6137 EXCEPTION
6138 WHEN no_data_found THEN
6139 l_count :=0;
6140 END;
6141
6142 IF (l_count <> 0 ) THEN
6143 x_return_status := FND_API.G_RET_STS_ERROR;
6144 return;
6145 END IF;
6146
6147 -- have save point
6148 SAVEPOINT update_reqchange_from_so_s;
6149 l_return_status := fnd_api.g_ret_sts_success;
6150
6151 --algo
6152 -- for the given req line the given attribute needs to be chnaged
6153 -- for quantity .. input is the delta qunatity = new qunatity-old quantity
6154 -- hence the new line quantity shall be existing qunatity+delta quantity
6155 -- this is applicable to both mtl_supply and po_requisition_lines_all
6156
6157 -- for need by date.. input is new need by date so update this value to
6158 -- both the tables
6159 IF p_req_line_id IS NOT NULL AND p_delta_quantity IS NOT NULL THEN
6160
6161 BEGIN
6162 po_reqchangerequestwf_pvt.update_reqline_quan_changes(
6163 p_req_line_id => p_req_line_id,
6164 p_delta_quantity=> p_delta_quantity,
6165 x_return_status =>l_return_status);
6166
6167 EXCEPTION
6168 WHEN OTHERS THEN
6169 ROLLBACK TO update_reqchange_from_so_s;
6170 END;
6171
6172
6173 END IF;
6174
6175 IF (p_req_line_id IS NOT NULL AND p_new_need_by_date IS NOT NULL ) THEN
6176 BEGIN
6177 -- read the profile POR: Sync up Need by date on IR with OM
6178 -- if yes then update the req table
6179 -- else by pass this and return success
6180 l_sync_need_by := nvl(fnd_profile.value('POR_SYNC_NEEDBYDATE_OM'), 'NO');
6181
6182 IF ( l_sync_need_by = 'YES' ) THEN
6183
6184 po_reqchangerequestwf_pvt.update_req_line_date_changes(p_req_line_id=>p_req_line_id,
6185 p_need_by_date=> p_new_need_by_date,
6186 x_return_status =>l_return_status);
6187
6188 END IF;
6189 EXCEPTION
6190 WHEN OTHERS THEN
6191 ROLLBACK TO update_reqchange_from_so_s;
6192 END;
6193
6194 END IF;
6195 x_return_status := fnd_api.g_ret_sts_success;
6196
6197 END update_reqchange_from_so;
6198
6199
6200 /*-----------------------------------------------------------------------------------------------------
6201 * At the Final Stage of Requester Creating Change request, SUBMIT_IREQCHANGE will be executed to complete
6202 * the transaction. This API takes care of funds Check, and does a final round of validation against
6203 * all change/cancel requests before kicking off the Workflow.
6204 ----------------------------------------------------------------------------------------------------*/
6205 PROCEDURE submit_ireqchange (
6206 p_api_version IN NUMBER,
6207 x_return_status OUT NOCOPY VARCHAR2,
6208 p_group_id IN NUMBER,
6209 p_fundscheck_flag IN VARCHAR2,
6210 p_note_to_approver IN VARCHAR2,
6211 p_initiator IN VARCHAR2,
6212 x_retmsg OUT NOCOPY VARCHAR2,
6213 x_errcode OUT NOCOPY VARCHAR2,
6214 x_errtable OUT NOCOPY po_req_change_err_table)
6215 IS
6216 l_api_name VARCHAR2(50) := 'Submit_IReqChange';
6217 l_log_head CONSTANT VARCHAR2(100) := c_log_head || l_api_name;
6218
6219 i NUMBER := 1;
6220 l_cancelerrorsize NUMBER;
6221 l_flag_one VARCHAR2(1);
6222 l_flag_two VARCHAR2(1);
6223
6224 l_req_dist_id NUMBER;
6225 l_req_line_id NUMBER;
6226 l_req_hdr_id NUMBER;
6227 l_req_num po_requisition_headers_all.segment1%TYPE;
6228 l_budget_account_id NUMBER;
6229 l_gl_date DATE;
6230 l_old_quantity NUMBER;
6231 l_old_tax NUMBER;
6232 l_qty_changed_flag VARCHAR2(1) := fnd_api.g_false;
6233 l_change_exist VARCHAR2(1);
6234 l_cancel_exist VARCHAR2(1);
6235 l_new_quantity NUMBER;
6236 l_new_so_quantity NUMBER;
6237 l_rec_tax NUMBER;
6238 l_nonrec_tax NUMBER;
6239 l_new_tax NUMBER;
6240 l_entered_dr NUMBER;
6241 l_entered_cr NUMBER;
6242 l_org_id NUMBER;
6243 l_fc_out_tbl po_fcout_type;
6244 l_fc_result_code VARCHAR2(1);
6245 l_fc_result_status VARCHAR2(1);
6246 l_fc_msg_count NUMBER;
6247 l_fc_msg_data VARCHAR2(2000);
6248 l_fc_req_line_id NUMBER;
6249 l_fc_req_line_num NUMBER;
6250 l_fc_req_distr_id NUMBER;
6251 l_fc_req_distr_num NUMBER;
6252 l_req_change_table change_tbl_type;
6253 l_new_date DATE;
6254 l_new_need_by_date DATE;
6255 l_old_need_by_date DATE;
6256 l_old_amount NUMBER;
6257 l_new_amount NUMBER;
6258 l_new_price NUMBER;
6259 l_distribution_id NUMBER;
6260 l_request_reason po_change_requests.request_reason%TYPE;
6261 l_cancel_errtable po_req_change_err_table;
6262 l_cal_disttax_status VARCHAR2(1);
6263 l_item_id NUMBER;
6264 l_req_uom po_requisition_lines_all.unit_meas_lookup_code%TYPE;
6265 l_po_uom po_line_locations_all.unit_meas_lookup_code%TYPE;
6266 l_po_to_req_rate NUMBER;
6267
6268 l_po_return_code VARCHAR2(100) := '';
6269 l_err_line_id_tbl po_tbl_number;
6270 l_err_line_num_tbl po_tbl_number;
6271 l_err_dist_id_tbl po_tbl_number;
6272 l_err_dist_num_tbl po_tbl_number;
6273 l_err_error_attr_tbl po_tbl_varchar30;
6274 l_err_msg_count_tbl po_tbl_number;
6275 l_err_msg_data_tbl po_tbl_varchar2000;
6276 l_wf_status VARCHAR2(1);
6277 l_distribution_id_tbl po_tbl_number;
6278
6279 CURSOR l_changes_csr(grp_id NUMBER) IS
6280 SELECT
6281 document_header_id,
6282 document_line_id,
6283 document_distribution_id,
6284 new_quantity,
6285 new_need_by_date,
6286 request_reason
6287 FROM po_change_requests
6288 WHERE change_request_group_id = grp_id
6289 AND action_type = 'MODIFICATION';
6290
6291 CURSOR l_cancel_csr(grp_id NUMBER) IS
6292 SELECT
6293 document_header_id,
6294 document_line_id,
6295 request_reason
6296 FROM po_change_requests
6297 WHERE change_request_group_id = grp_id
6298 AND action_type = 'CANCELLATION';
6299
6300
6301 CURSOR l_dist_qty_price_chn_csr(grp_id NUMBER) IS
6302 SELECT
6303 document_line_id line_id,
6304 document_distribution_id dist_id,
6305 document_header_id hdr_id,
6306 document_num req_num
6307 FROM
6308 po_change_requests
6309 WHERE
6310 change_request_group_id = grp_id AND
6311 new_quantity IS NOT NULL AND
6312 action_type = 'MODIFICATION'
6313 ;/* UNION
6314 SELECT
6315 prda.requisition_line_id line_id,
6316 prda.distribution_id dist_id,
6317 prla.requisition_header_id hdr_id,
6318 prha.segment1 req_num
6319 FROM
6320 po_req_distributions_all prda,
6321 po_requisition_lines_all prla,
6322 po_change_requests pcr,
6323 po_requisition_headers_all prha
6324 WHERE
6325 prha.requisition_header_id = prla.requisition_header_id AND
6326 prla.requisition_line_id = prda.requisition_line_id AND
6327 pcr.document_line_id = prla.requisition_line_id AND
6328 pcr.change_request_group_id = grp_id AND
6329 pcr.action_type = 'MODIFICATION' AND
6330 pcr.new_need_by_date IS NOT NULL;*/
6331
6332 -- list of req distributions effected with the req changes
6333 CURSOR l_changed_req_dists_csr(grp_id NUMBER) IS
6334 SELECT -- any quantity change
6335 pcr.document_distribution_id
6336 FROM
6337 po_change_requests pcr
6338 WHERE
6339 pcr.change_request_group_id = grp_id AND
6340 pcr.new_quantity IS NOT NULL AND
6341 pcr.action_type = 'MODIFICATION';
6342
6343 /* AND
6344 pcr.document_distribution_id = prda.distribution_id*/
6345 /* CURSOR l_changed_req_dists_csr(grp_id NUMBER) IS
6346 SELECT -- any quantity or amount change
6347 prda.distribution_id
6348 FROM
6349 po_change_requests pcr,
6350 po_req_distributions_all prda
6351 WHERE
6352 pcr.change_request_group_id = grp_id AND
6353 pcr.new_quantity IS NOT NULL AND
6354 pcr.action_type = 'MODIFICATION' AND
6355 pcr.document_distribution_id = prda.distribution_id
6356 ; UNION
6357 SELECT -- select distributions that are effected with any line change
6358 prda.distribution_id
6359 FROM
6360 po_change_requests pcr,
6361 po_requisition_lines_all prla,
6362 po_req_distributions_all prda
6363 WHERE
6364 pcr.change_request_group_id = grp_id AND
6365 pcr.action_type = 'MODIFICATION' AND
6366 pcr.new_need_by_date IS NOT NULL AND
6367 pcr.document_line_id = prla.requisition_line_id AND
6368 prla.requisition_line_id = prda.requisition_line_id ;*/
6369
6370 -- list of release distributions effected with the req changes
6371 CURSOR l_dist_tax_csr(grp_id NUMBER) IS
6372 SELECT -- any quantity change
6373 prla.requisition_line_id,
6374 prda.distribution_id,
6375 prla.requisition_header_id,
6376 prla.unit_price,
6377 nvl(pcr.new_quantity, pcr.old_quantity)
6378 FROM
6379 po_change_requests pcr,
6380 po_req_distributions_all prda,
6381 po_requisition_lines_all prla
6382 WHERE
6383 pcr.change_request_group_id = grp_id AND
6384 pcr.new_quantity IS NOT NULL AND
6385 -- (pcr.new_quantity IS NOT NULL OR pcr.new_need_by_date IS NOT NULL) AND
6386 pcr.action_type = 'MODIFICATION' AND
6387 pcr.document_distribution_id = prda.distribution_id AND
6388 prla.requisition_line_id = prda.requisition_line_id AND
6389 pcr.document_line_id = prla.requisition_line_id ;
6390
6391 BEGIN
6392 x_return_status := fnd_api.g_ret_sts_error;
6393 x_retmsg := 'SMRCH000';
6394 x_return_status := fnd_api.g_ret_sts_success;
6395
6396 --Check if Funds Check is needed
6397 SELECT
6398 nvl(fsp.req_encumbrance_flag, 'N')
6399 INTO
6400 l_flag_one
6401 FROM financials_system_parameters fsp;
6402
6403 --Check if change request exist
6404 l_change_exist := 'N';
6405 OPEN l_changes_csr(p_group_id);
6406
6407 FETCH l_changes_csr
6408 INTO l_req_hdr_id, l_req_line_id, l_req_dist_id, l_new_quantity,
6409 l_new_date, l_request_reason;
6410 IF(l_req_hdr_id IS NOT NULL) THEN
6411 l_change_exist := 'Y';
6412 END IF;
6413 CLOSE l_changes_csr;
6414
6415 IF g_debug_stmt THEN
6416 po_debug.debug_var(l_log_head, x_retmsg, 'l_flag_one=', l_flag_one);
6417 po_debug.debug_var(l_log_head, x_retmsg, 'l_change_exist=', l_change_exist);
6418 po_debug.debug_var(l_log_head, x_retmsg, 'p_group_ID=', p_group_id);
6419 po_debug.debug_var(l_log_head, x_retmsg, 'l_cancel_exist=', l_cancel_exist);
6420 po_debug.debug_var(l_log_head, x_retmsg, 'l_req_hdr_id=', l_req_hdr_id);
6421 po_debug.debug_var(l_log_head, x_retmsg, 'l_req_line_id=', l_req_line_id);
6422 po_debug.debug_var(l_log_head, x_retmsg, 'l_request_reason=', l_request_reason);
6423 END IF;
6424
6425 --Check if cancel request exist
6426 l_cancel_exist := 'N';
6427 l_req_hdr_id := NULL;l_req_line_id := NULL;l_request_reason := NULL;
6428
6429 OPEN l_cancel_csr(p_group_id);
6430 FETCH l_cancel_csr
6431 INTO l_req_hdr_id, l_req_line_id, l_request_reason;
6432
6433 IF(l_req_hdr_id IS NOT NULL) THEN
6434 l_cancel_exist := 'Y';
6435 END IF;
6436
6437 CLOSE l_cancel_csr;
6438
6439 x_retmsg := 'SMRCH001';
6440
6441 IF g_debug_stmt THEN
6442 po_debug.debug_var(l_log_head, x_retmsg, 'l_flag_one=', l_flag_one);
6443 po_debug.debug_var(l_log_head, x_retmsg, 'l_change_exist=', l_change_exist);
6444 po_debug.debug_var(l_log_head, x_retmsg, 'p_group_ID=', p_group_id);
6445 po_debug.debug_var(l_log_head, x_retmsg, 'l_cancel_exist=', l_cancel_exist);
6446 po_debug.debug_var(l_log_head, x_retmsg, 'l_req_hdr_id=', l_req_hdr_id);
6447 po_debug.debug_var(l_log_head, x_retmsg, 'l_req_line_id=', l_req_line_id);
6448 po_debug.debug_var(l_log_head, x_retmsg, 'l_request_reason=', l_request_reason);
6449 END IF ;
6450
6451 --Funds Check Starts
6452 IF (l_change_exist = 'Y' AND p_fundscheck_flag = 'Y' AND l_flag_one <> 'N' ) THEN
6453
6454 x_retmsg := 'SMRCH002';
6455 IF g_debug_stmt THEN
6456 po_debug.debug_stmt(l_log_head, x_retmsg,'change exists with funds check');
6457 END IF;
6458
6459 --Check if any records require funds check.
6460 OPEN l_dist_qty_price_chn_csr(p_group_id);
6461 FETCH l_dist_qty_price_chn_csr INTO
6462 l_req_line_id,
6463 l_req_dist_id,
6464 l_req_hdr_id,
6465 l_req_num;
6466 CLOSE l_dist_qty_price_chn_csr;
6467
6468 IF (l_req_num IS NOT NULL) THEN
6469
6470 -- initialize distributions list table
6471 l_distribution_id_tbl := po_tbl_number();
6472
6473 -- insert NEW/OLD records of standard po distributions into PO_ENCUMBRANCE_GT
6474 OPEN l_changed_req_dists_csr(p_group_id);
6475
6476 FETCH l_changed_req_dists_csr BULK COLLECT
6477 INTO l_distribution_id_tbl;
6478
6479 CLOSE l_changed_req_dists_csr;
6480
6481 po_document_funds_grp.populate_encumbrance_gt(
6482 p_api_version => 1.0,
6483 x_return_status => x_return_status,
6484 p_doc_type => po_document_funds_grp.g_doc_type_requisition, --call with req type at dist level
6485 p_doc_level => po_document_funds_grp.g_doc_level_distribution,
6486 p_doc_level_id_tbl => l_distribution_id_tbl,
6487 p_make_old_copies_flag => po_document_funds_grp.g_parameter_yes,
6488 p_make_new_copies_flag => po_document_funds_grp.g_parameter_yes,
6489 p_check_only_flag => po_document_funds_grp.g_parameter_yes);
6490
6491 -- error handling after calling populate_encumbrance_gt
6492 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
6493 x_retmsg := 'After calling populate_encumbrance_gt';
6494 x_errcode := 'FC_FAIL';
6495 IF g_debug_stmt THEN
6496 po_debug.debug_stmt(l_log_head, x_retmsg,'error exists with funds check');
6497 END IF;
6498
6499 RETURN;
6500 END IF;
6501
6502 -- re-initialize distributions list table
6503 l_distribution_id_tbl.delete;
6504
6505 -- Update NEW record in PO_ENCUMBRANCE_GT with the new
6506 -- values
6507 x_retmsg := 'SMRCH003';
6508
6509 /*
6510 *Looping through the distribution records which requires fundscheck, and populating the fundscheck
6511 *input table with the appropriate data.
6512 */
6513
6514 /**/
6515 --need to get newest price quantity and amount
6516
6517
6518
6519 OPEN l_dist_tax_csr(p_group_id);
6520
6521 LOOP
6522 FETCH l_dist_tax_csr INTO
6523 l_req_line_id,
6524 l_req_dist_id,
6525 l_req_hdr_id,
6526 l_new_price,
6527 l_new_quantity;
6528 EXIT WHEN l_dist_tax_csr%notfound;
6529 x_retmsg := 'SMRCH0031:' || l_req_line_id || '*' || l_req_dist_id || '*' || l_req_hdr_id || '*' || l_req_num;
6530
6531 IF g_debug_stmt THEN
6532 po_debug.debug_var(l_log_head, x_retmsg,'l_req_line_id ', l_req_line_id );
6533 po_debug.debug_var(l_log_head, x_retmsg,'l_req_dist_id ', l_req_dist_id );
6534 po_debug.debug_var(l_log_head, x_retmsg,'l_req_hdr_id ', l_req_hdr_id );
6535 po_debug.debug_var(l_log_head, x_retmsg,'l_new_price ', l_new_price );
6536 po_debug.debug_var(l_log_head, x_retmsg, 'l_new_quantity', l_new_quantity);
6537 END IF;
6538
6539 calculate_disttax(1.0, l_cal_disttax_status, l_req_dist_id, l_new_price, l_new_quantity, NULL,
6540 l_rec_tax, l_nonrec_tax);
6541 l_new_tax := l_nonrec_tax;
6542 l_new_amount := l_new_price*l_new_quantity;
6543 IF g_debug_stmt THEN
6544 po_debug.debug_var(l_log_head, x_retmsg, 'l_rec_tax=', l_rec_tax);
6545 po_debug.debug_var(l_log_head, x_retmsg, 'l_nonrec_tax=', l_nonrec_tax);
6546 END IF;
6547
6548 -- update new values in PO_ENCUMBRANCE_GT
6549 UPDATE po_encumbrance_gt
6550 SET
6551 amount_ordered = l_new_amount,
6552 quantity_ordered = l_new_quantity,
6553 price = l_new_price,
6554 nonrecoverable_tax = l_new_tax
6555 WHERE
6556 distribution_id = l_distribution_id AND
6557 adjustment_status = po_document_funds_grp.g_adjustment_status_new;
6558
6559 END LOOP;
6560 CLOSE l_dist_tax_csr;
6561
6562
6563 x_retmsg := 'SMRCH0032';
6564 --Execute PO Funds Check API
6565
6566 po_document_funds_grp.check_adjust(
6567 p_api_version => 1.0,
6568 x_return_status => l_fc_result_status,
6569 p_doc_type => po_document_funds_grp.g_doc_type_REQUISITION,
6570 p_doc_subtype => NULL,
6571 p_override_funds => po_document_funds_grp.g_parameter_USE_PROFILE,
6572 p_use_gl_date => po_document_funds_grp.g_parameter_YES,
6573 p_override_date => sysdate,
6574 p_report_successes => po_document_funds_grp.g_parameter_NO,
6575 x_po_return_code => l_po_return_code,
6576 x_detailed_results => l_fc_out_tbl);
6577
6578 x_retMsg := 'SMRCH004';
6579
6580 IF (g_fnd_debug = 'Y') THEN
6581 IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
6582 FND_LOG.string(FND_LOG.level_statement,
6583 g_module_prefix || l_api_name,
6584 'FUNDS CHECK:' || l_fc_result_status ||' PO RETURN CODE:' || l_po_return_code);
6585 END IF;
6586 END IF;
6587
6588 IF (l_fc_result_status = fnd_api.g_ret_sts_unexp_error) THEN
6589 x_errcode := 'FC_ERROR';
6590 x_return_status := fnd_api.g_ret_sts_error;
6591 RETURN;
6592
6593 ELSE
6594 IF g_debug_stmt THEN
6595 po_debug.debug_STmt(l_log_head, x_retmsg, 'after check adjust of funds check');
6596 END IF;
6597
6598
6599 IF (l_po_return_code = po_document_funds_grp.g_return_success) THEN
6600 x_return_status := fnd_api.g_ret_sts_success;
6601
6602 ELSE -- there can be warning/error message for other cases
6603
6604 x_errcode := 'FC_FAIL';
6605 x_return_status := fnd_api.g_ret_sts_error;
6606
6607 -- populate x_errTable (output PLSQL table) with the corresponding
6608 -- funds check error messages.
6609
6610 l_err_line_id_tbl := po_tbl_number();
6611 l_err_line_num_tbl := po_tbl_number();
6612 l_err_dist_id_tbl := po_tbl_number();
6613 l_err_dist_num_tbl := po_tbl_number();
6614 l_err_error_attr_tbl := po_tbl_varchar30();
6615 l_err_msg_count_tbl := po_tbl_number();
6616 l_err_msg_data_tbl := po_tbl_varchar2000();
6617
6618 x_errtable := po_req_change_err_table(
6619 l_err_line_id_tbl,
6620 l_err_line_num_tbl,
6621 l_err_dist_id_tbl,
6622 l_err_dist_num_tbl,
6623 l_err_error_attr_tbl,
6624 l_err_msg_count_tbl,
6625 l_err_msg_data_tbl);
6626
6627
6628 x_errtable.req_line_id.extend(l_fc_out_tbl.row_index.count);
6629 x_errtable.req_line_num.extend(l_fc_out_tbl.row_index.count);
6630 x_errtable.req_dist_id.extend(l_fc_out_tbl.row_index.count);
6631 x_errtable.req_dist_num.extend(l_fc_out_tbl.row_index.count);
6632 x_errtable.msg_count.extend(l_fc_out_tbl.row_index.count);
6633 x_errtable.msg_data.extend(l_fc_out_tbl.row_index.count);
6634 FOR x IN 1..l_fc_out_tbl.row_index.count LOOP
6635
6636 SELECT
6637 prda.distribution_id,
6638 prda.distribution_num,
6639 prda.requisition_line_id,
6640 prla.line_num
6641 INTO
6642 l_fc_req_distr_id,
6643 l_fc_req_distr_num,
6644 l_fc_req_line_id,
6645 l_fc_req_line_num
6646 FROM
6647 po_requisition_lines_all prla,
6648 po_req_distributions_all prda,
6649 po_distributions_all pda
6650 WHERE
6651 pda.po_distribution_id = l_fc_out_tbl.distribution_id(x)
6652 AND pda.req_distribution_id = prda.distribution_id
6653 AND prla.requisition_line_id = prda.requisition_line_id;
6654
6655 x_errtable.req_line_id(x) := l_fc_req_line_id;
6656 x_errtable.req_line_num(x) := l_fc_req_line_num;
6657 x_errtable.req_dist_id(x) := l_fc_req_distr_id;
6658 x_errtable.req_dist_num(x) := l_fc_req_distr_num;
6659 x_errtable.msg_data(x) := l_fc_out_tbl.error_msg(x);
6660
6661 END LOOP;
6662 RETURN;
6663 END IF;
6664 END IF;
6665 END IF;
6666
6667 END IF;
6668 --Funds Check Ends
6669
6670
6671 i := 1;
6672 OPEN l_changes_csr(p_group_id);
6673 LOOP
6674 FETCH l_changes_csr
6675 INTO
6676 l_req_hdr_id,
6677 l_req_line_id,
6678 l_req_dist_id,
6679 l_new_quantity,
6680 --l_new_price,
6681 l_new_date,
6682 l_request_reason;
6683 EXIT WHEN l_changes_csr%notfound;
6684 l_req_change_table(i).document_line_id := l_req_line_id;
6685 l_req_change_table(i).document_distribution_id := l_req_dist_id;
6686 l_req_change_table(i).new_price := l_new_price;
6687 l_req_change_table(i).new_quantity := l_new_quantity;
6688 l_req_change_table(i).new_date := l_new_date;
6689 l_req_change_table(i).request_reason := l_request_reason;
6690
6691 i := i + 1;
6692 END LOOP;
6693 CLOSE l_changes_csr;
6694 x_retmsg := 'SMRCH006';
6695 l_err_line_id_tbl := po_tbl_number();
6696 l_err_line_num_tbl := po_tbl_number();
6697 l_err_dist_id_tbl := po_tbl_number();
6698 l_err_dist_num_tbl := po_tbl_number();
6699 l_err_error_attr_tbl := po_tbl_varchar30();
6700 l_err_msg_count_tbl := po_tbl_number();
6701 l_err_msg_data_tbl := po_tbl_varchar2000();
6702
6703 x_errTable := po_req_change_err_table(
6704 l_err_line_id_tbl,
6705 l_err_line_num_tbl,
6706 l_err_dist_id_tbl,
6707 l_err_dist_num_tbl,
6708 l_err_error_attr_tbl,
6709 l_err_msg_count_tbl,
6710 l_err_msg_data_tbl);
6711
6712 --Final Round of Validations Against Changes
6713 -- if(l_change_exist = 'Y') then
6714 -- Validate_Changes(l_req_hdr_id,l_req_change_table,x_return_status,x_retMsg,x_errTable);
6715 --call OM API for this validation this is not needed
6716 -- end if;
6717 x_retmsg := 'SMRCH007';
6718 --Submit Cancel Requests
6719 IF g_debug_stmt THEN
6720 po_debug.debug_stmt(l_log_head, x_retmsg, 'submitting changes...');
6721 END IF;
6722
6723 IF(l_cancel_exist = 'Y') THEN
6724 submit_ireqcancel(1.0, x_return_status, p_group_id, x_retmsg, x_errTable, 'Y');
6725 END IF;
6726
6727 x_retmsg := 'SMRCH008';
6728 /* i:=x_errTable.req_line_id.count+1;
6729 l_CancelErrorSize:=l_cancel_ErrTable.req_line_id.count;
6730
6731 if(l_CancelErrorSize > 0) then
6732 x_errTable.req_line_id.extend(l_CancelErrorSize);
6733 x_errTable.msg_count.extend(l_CancelErrorSize);
6734 x_errTable.msg_data.extend(l_CancelErrorSize);
6735
6736 for k in 1..l_CancelErrorSize
6737 loop
6738 x_errTable.req_line_id(i):=l_cancel_ErrTable.req_line_id(k);
6739 x_errTable.msg_count(i):=1;
6740 x_errTable.msg_data(i):='CANNOT CANCEL';
6741 i:=i+1;
6742 end loop;
6743 end if;
6744 /*
6745 * If all requests are valid, update status to "NEW" and kick off workflow
6746 */
6747
6748
6749
6750 IF(x_errtable.req_line_id.count = 0) THEN
6751
6752 IF g_debug_stmt THEN
6753 po_debug.debug_stmt(l_log_head, x_retmsg, 'all change requests are valid, updating status to "NEW" and kick off workflow');
6754 END IF;
6755
6756
6757 UPDATE po_change_requests
6758 SET request_status = 'NEW'
6759 WHERE change_request_group_id = p_group_id
6760 AND request_status = 'SYSTEMSAVE';
6761
6762
6763 --Kick Off Workflow
6764 x_retmsg := 'SMRCH009';
6765
6766 po_reqchangerequestwf_pvt.submit_internal_req_change(
6767 p_api_version => 1.0,
6768 p_commit => fnd_api.g_false,
6769 p_req_header_id => l_req_hdr_id,
6770 p_note_to_approver => p_note_to_approver,
6771 p_initiator => p_initiator,
6772 x_return_status => l_wf_status);
6773 ELSE
6774 x_errcode := 'VC_FAIL';
6775 x_return_status := fnd_api.g_ret_sts_error;
6776 END IF;
6777 EXCEPTION WHEN OTHERS THEN
6778 x_return_status := fnd_api.g_ret_sts_unexp_error;
6779 x_retmsg := x_retmsg || ':' || SQLERRM;
6780 IF g_fnd_debug = 'Y' THEN
6781 IF (fnd_log.g_current_runtime_level <= fnd_log.level_unexpected) THEN
6782 fnd_log.string(fnd_log.level_unexpected, g_module_prefix ||
6783 l_api_name || '.others_exception', x_retmsg );
6784
6785 END IF;
6786 END IF;
6787 END SUBMIT_IREQCHANGE;
6788
6789 /* This is called from the UI to check whether the new values are valid
6790 */
6791 procedure validate_internal_req_changes(
6792 p_req_line_id IN NUMBER
6793 , p_req_header_id IN NUMBER
6794 , p_need_by_date IN DATE DEFAULT NULL
6795 , p_old_quantity IN NUMBER DEFAULT 0
6796 , p_new_quantity IN NUMBER DEFAULT 0
6797 , X_return_status OUT NOCOPY VARCHAR2
6798 )
6799 IS
6800
6801 L_msg_data VARCHAR2(2000);
6802 L_msg_count NUMBER;
6803 l_delta_quantity number;
6804 l_log_head CONSTANT VARCHAR2(100) := c_log_head ||'validate_internal_req_changes';
6805 l_progress varchar2(3) := '000';
6806
6807 /*Procedure Call_Process_Order_for_IReq -- Specification definition
6808 ( P_API_Version IN NUMBER
6809 , P_internal_req_line_id IN PO_Requisition_Lines_All.Requisition_Line_id%TYPE
6810 , P_internal_req_header_id IN PO_Requisition_Headers_All.Requisition_Header_id%TYPE
6811 , P_Mode IN VARCHAR2
6812 , P_Cancel_ISO IN BOOLEAN DEFAULT FALSE
6813 , P_Cancel_ISO_lines IN BOOLEAN DEFAULT FALSE
6814 , P_New_Request_Date IN DATE DEFAULT NULL
6815 , P_Delta_Ordered_Qty IN NUMBER DEFAULT 0
6816 , X_msg_count OUT NOCOPY NUMBER
6817 , X_msg_data OUT NOCOPY VARCHAR2
6818 , X_return_status OUT NOCOPY VARCHAR2
6819 );*/
6820
6821 l_orgid number;
6822 l_open_quantity number;
6823 BEGIN
6824
6825 /* Only for the qunatity changes check for the the new ordered quantity is less
6826 than received+open receiving
6827 quantity then the throw error */
6828
6829 IF( p_new_quantity <> 0 ) THEN
6830
6831 BEGIN
6832 SELECT nvl(sum(w.shipped_quantity),0)
6833 INTO l_open_quantity
6834 FROM oe_order_lines_all oel
6835 ,oe_order_headers_all oeh
6836 ,wsh_delivery_details w
6837 ,po_requisition_lines_all pol
6838 ,po_requisition_headers_all poh --Bug 14280643
6839 WHERE
6840 oel.header_id = oeh.header_id
6841 AND oel.line_id = w.source_line_id
6842 AND w.source_code = 'OE'
6843 AND w.released_status = 'C'
6844 AND oel.source_document_line_id=pol.requisition_line_id
6845 AND oel.source_document_id=pol.requisition_header_id
6846 AND oeh.source_document_id = pol.requisition_header_id --Bug 14280643
6847 AND poh.requisition_header_id = pol.requisition_header_id --Bug 14280643
6848 AND poh.segment1 = oeh.orig_sys_document_ref --Bug 14280643
6849 AND oeh.source_document_type_id =10
6850 AND pol.REQUISITION_LINE_ID=p_req_line_id;
6851 EXCEPTION
6852 WHEN NO_DATA_FOUND THEN
6853 l_open_quantity := 0;
6854 WHEN OTHERS THEN
6855 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6856 END;
6857
6858 IF ( p_new_quantity < l_open_quantity ) THEN
6859 RAISE FND_API.G_EXC_ERROR;
6860 END IF;
6861 END IF;
6862 l_delta_quantity := p_new_quantity-p_old_quantity;
6863
6864 IF g_debug_stmt THEN
6865 po_debug.debug_begin(l_log_head);
6866 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
6867 po_debug.debug_var(l_log_head, l_progress, 'p_req_header_id', p_req_header_id);
6868 po_debug.debug_var(l_log_head, l_progress, 'p_need_by_date', p_need_by_date);
6869 po_debug.debug_var(l_log_head, l_progress, 'p_old_quantity', p_old_quantity);
6870 po_debug.debug_var(l_log_head, l_progress, 'p_new_quantity', p_new_quantity);
6871 po_debug.debug_var(l_log_head, l_progress, 'l_delta_quantity', l_delta_quantity);
6872 END IF;
6873
6874 l_progress :='001';
6875
6876
6877 l_orgid := PO_ReqChangeRequestWF_PVT.get_sales_order_org(p_req_line_id =>p_req_line_id);
6878
6879 IF g_debug_stmt THEN
6880 po_debug.debug_var(l_log_head, l_progress, 'Sales order l_orgid', l_orgid);
6881 END IF;
6882
6883 IF l_orgid is NOT NULL THEN
6884 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
6885 END IF;
6886
6887 IF g_debug_stmt THEN
6888 po_debug.debug_stmt(l_log_head, l_progress, 'Calling OM API Validating the changes');
6889 END IF;
6890
6891 OE_Internal_Requisition_Pvt.Call_Process_Order_for_IReq
6892 ( P_API_Version => 1.0
6893 , P_internal_req_line_id => p_req_line_id
6894 , P_internal_req_header_id => p_req_header_id
6895 , P_Mode => 'V' --SIMPLY VALIDATING
6896 , P_New_Request_Date => p_need_by_date
6897 , P_Delta_Ordered_Qty => l_delta_quantity
6898 , X_msg_count => L_msg_count
6899 , X_msg_data => L_msg_data
6900 , X_return_status => X_return_status
6901 );
6902
6903 IF g_debug_stmt THEN
6904 po_debug.debug_stmt(l_log_head, l_progress, 'returning from OM API Validating the changes');
6905 END IF;
6906
6907 l_orgid := PO_ReqChangeRequestWF_PVT.get_requisition_org( p_req_hdr_id => p_req_header_id,
6908 p_req_line_id =>p_req_line_id);
6909
6910 IF g_debug_stmt THEN
6911 po_debug.debug_var(l_log_head, l_progress, 'Requisition l_orgid', l_orgid);
6912 END IF;
6913
6914 IF l_orgid is NOT NULL THEN
6915 PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ; -- <R12 MOAC>
6916 END IF;
6917
6918
6919 IF g_debug_stmt THEN
6920 po_debug.debug_stmt(l_log_head, l_progress, 'returning from OM API Validating the changes');
6921 po_debug.debug_var(l_log_head, l_progress, 'l_orgid', l_orgid);
6922 po_debug.debug_var(l_log_head, l_progress, 'L_msg_data', L_msg_data);
6923 po_debug.debug_var(l_log_head, l_progress, 'L_msg_count', L_msg_count);
6924 po_debug.debug_var(l_log_head, l_progress, 'X_return_status', X_return_status);
6925 po_debug.debug_end(l_log_head);
6926
6927 END IF;
6928 exception
6929 when others then
6930 X_return_status:=FND_API.G_RET_STS_ERROR;
6931 IF g_debug_stmt THEN
6932 po_debug.debug_stmt(l_log_head, l_progress, ' Validating the changes in exception'|| sqlerrm);
6933 po_debug.debug_var(l_log_head, l_progress, 'l_orgid', l_orgid);
6934 po_debug.debug_var(l_log_head, l_progress, 'L_msg_data', L_msg_data);
6935 po_debug.debug_var(l_log_head, l_progress, 'L_msg_count', L_msg_count);
6936 po_debug.debug_var(l_log_head, l_progress, 'X_return_status', X_return_status);
6937 po_debug.debug_end(l_log_head);
6938 END IF;
6939 END validate_internal_req_changes;
6940
6941
6942
6943
6944 -- 14227140 changes starts
6945 /**
6946 * Procedure to update the cancel qty in req line from SO
6947 * This method is called when a SO initiated partial
6948 * cancellation of Qty (Primary or Secondary) or cancellation of line.
6949 *
6950
6951 * @param p_req_line_id number canceled req line
6952 * @param p_req_can_prim_qty number canceled Prim Qty of req line
6953 * @param p_req_can_sec_qty number canceled Secondary Qty of req line
6954 * @param p_req_can_all boolean to hole weather req line cancelation flag
6955 * @param x_return_status returns the tstatus of the api.
6956 */
6957 PROCEDURE update_reqcancel_from_so( p_req_line_id IN NUMBER
6958 , p_req_cancel_prim_qty IN NUMBER
6959 , p_req_cancel_sec_qty IN NUMBER
6960 , p_req_cancel_all IN BOOLEAN
6961 ,x_return_status OUT NOCOPY VARCHAR2 )
6962 IS
6963
6964 l_req_line_id NUMBER;
6965 l_bool_ret_sts BOOLEAN;
6966 l_return_status VARCHAR2(10);
6967 l_open_quantity number;
6968 l_prim_quantity NUMBER;
6969 l_sec_quantity NUMBER;
6970 l_delta_prim_quantity number :=0;
6971 l_delta_sec_quantity number :=0;
6972 l_log_head CONSTANT VARCHAR2(100) := c_log_head || 'update_reqcancel_from_so';
6973 l_progress varchar2(3):='000';
6974 l_count number:=0;
6975 BEGIN
6976
6977 -- Bug 8235698: Check whether there is a pending change on this
6978 -- requisition line , if there exists one then
6979 -- return Error to the SO (OM) API.
6980
6981 BEGIN
6982
6983 SELECT COUNT(*) INTO l_count FROM po_change_requests
6984 WHERE request_status in ( 'NEW' , 'MGR_PRE_APP' , 'MGR_APP')
6985 AND DOCUMENT_TYPE= 'REQ'
6986 AND REQUEST_LEVEL= 'LINE'
6987 AND DOCUMENT_LINE_ID=p_req_line_id;
6988
6989 EXCEPTION
6990 WHEN no_data_found THEN
6991 l_count:=0;
6992 END;
6993
6994 IF (l_count <> 0 ) THEN
6995
6996 x_return_status := FND_API.G_RET_STS_ERROR;
6997 IF g_debug_stmt THEN
6998 po_debug.debug_begin(l_log_head);
6999
7000 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
7001 po_debug.debug_var(l_log_head, l_progress, 'No of po_change_requests on req line', l_count);
7002 END IF;
7003
7004 return;
7005 END IF;
7006 -- have save point
7007 SAVEPOINT update_reqcancel_from_so_sp;
7008 /*
7009 * ALGORITHM : For each req line or perticular line
7010 Step 1: Retrive the open receiving quantity INTO l_open_quantity
7011 Step 2 : Retrive the REQ LINE quantity INTO l_quantity
7012 */
7013
7014 l_return_status := fnd_api.g_ret_sts_success;
7015 l_progress:='001';
7016
7017 IF g_debug_stmt THEN
7018 po_debug.debug_begin(l_log_head);
7019 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
7020 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_prim_qty', p_req_cancel_prim_qty);
7021 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_sec_qty', p_req_cancel_sec_qty);
7022 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_all', p_req_cancel_all);
7023 END IF;
7024
7025 IF (p_req_line_id IS NOT NULL ) THEN
7026
7027 IF p_req_cancel_all THEN
7028
7029 po_reqchangerequestwf_pvt.req_line_CANCEL(
7030 p_req_line_id => p_req_line_id,
7031 x_return_status =>l_return_status);
7032 ELSE
7033
7034 BEGIN
7035 SELECT QUANTITY, SECONDARY_QUANTITY
7036 INTO l_prim_quantity, l_sec_quantity
7037 FROM po_requisition_lines_all
7038 WHERE REQUISITION_LINE_ID=p_req_line_id;
7039 EXCEPTION
7040 WHEN OTHERS THEN
7041 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7042 END;
7043
7044 IF g_debug_stmt THEN
7045 po_debug.debug_var(l_log_head, l_progress, 'l_prim_quantity', l_prim_quantity);
7046 po_debug.debug_var(l_log_head, l_progress, 'l_sec_quantity', l_sec_quantity);
7047 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_prim_qty', p_req_cancel_prim_qty);
7048 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_sec_qty', p_req_cancel_sec_qty);
7049 po_debug.debug_var(l_log_head, l_progress, 'p_req_cancel_all', p_req_cancel_all);
7050 END IF;
7051 IF ((p_req_cancel_prim_qty IS NOT NULL AND l_prim_quantity IS NOT NULL)
7052 OR (p_req_cancel_sec_qty IS NOT NULL AND l_sec_quantity IS NOT NULL) ) THEN
7053 IF ((l_prim_quantity - p_req_cancel_prim_qty > 0) OR
7054 (l_sec_quantity - p_req_cancel_sec_qty > 0)) THEN
7055
7056 IF(l_prim_quantity - p_req_cancel_prim_qty > 0) THEN
7057 -- update the req line primary quantity with delta quantity as
7058 l_delta_prim_quantity := (-1) * p_req_cancel_prim_qty ;
7059 END IF;
7060 IF(l_sec_quantity - p_req_cancel_sec_qty > 0) THEN
7061 -- update the req line secondary quantity with delta quantity as
7062 l_delta_sec_quantity := (-1) * p_req_cancel_sec_qty ;
7063 END IF;
7064
7065 IF g_debug_stmt THEN
7066 po_debug.debug_var(l_log_head, l_progress, 'l_delta_prim_quantity', l_delta_prim_quantity);
7067 po_debug.debug_var(l_log_head, l_progress, 'l_delta_sec_quantity', l_delta_sec_quantity);
7068 END IF;
7069
7070 po_reqchangerequestwf_pvt.update_reqline_quan_changes(
7071 p_req_line_id => p_req_line_id,
7072 p_delta_prim_quantity=> l_delta_prim_quantity,
7073 p_delta_sec_quantity=> l_delta_sec_quantity,
7074 x_return_status =>l_return_status);
7075
7076 ELSE
7077 po_reqchangerequestwf_pvt.req_line_CANCEL(
7078 p_req_line_id => p_req_line_id,
7079 x_return_status =>l_return_status);
7080 END IF;
7081 END IF;
7082 END IF;
7083 END IF;
7084
7085 IF g_debug_stmt THEN
7086 po_debug.debug_var(l_log_head, l_progress, 'l_return_status', l_return_status);
7087 END IF;
7088
7089 x_return_status := fnd_api.g_ret_sts_success;
7090
7091 EXCEPTION
7092 WHEN OTHERS THEN
7093 x_return_status:= FND_API.G_RET_STS_ERROR;
7094 ROLLBACK TO update_reqcancel_from_so_sp;
7095 END update_reqcancel_from_so;
7096
7097
7098 /**
7099 * Procedure to update the Qty changes on req line from SO changes
7100 * This method is called when a SO initiated change in Qty (Primary or Secondary).
7101 *
7102 * @param p_req_line_id number holds the req line number
7103 * @param p_delta_quantity_prim number changed Prim Qty of SO
7104 * @param p_delta_quantity_sec number changed Secondary Qty of SO
7105 * @param p_new_need_by_date date need by date of SO.
7106 * @param x_return_status returns the tstatus of the api
7107 */
7108 PROCEDURE update_reqchange_from_so(
7109 p_req_line_id IN NUMBER
7110 , p_delta_quantity_prim IN NUMBER
7111 , p_delta_quantity_sec IN NUMBER
7112 , p_new_need_by_date IN DATE
7113 , x_return_status OUT NOCOPY VARCHAR2
7114 )
7115 IS
7116
7117 l_bool_ret_sts BOOLEAN;
7118 l_mtl_supply_quantity NUMBER;
7119 l_return_status varchar2(10);
7120 l_sync_need_by varchar2(3);
7121 l_count number:=0;
7122
7123 BEGIN
7124 -- Check whether there is a pending change on this
7125 -- requisition line , if there exists one then
7126 -- return Error to the SO (OM) API.
7127
7128 BEGIN
7129 SELECT count(*) INTO l_count
7130 FROM PO_change_requests
7131 WHERE request_status in ( 'NEW' , 'MGR_PRE_APP' , 'MGR_APP')
7132 AND DOCUMENT_TYPE= 'REQ'
7133 AND REQUEST_LEVEL= 'LINE'
7134 AND DOCUMENT_LINE_ID=p_req_line_id;
7135
7136 EXCEPTION
7137 WHEN no_data_found THEN
7138 l_count :=0;
7139 END;
7140
7141 IF (l_count <> 0 ) THEN
7142 x_return_status := FND_API.G_RET_STS_ERROR;
7143 return;
7144 END IF;
7145
7146 -- have save point
7147 SAVEPOINT update_reqchange_from_so_s;
7148 l_return_status := fnd_api.g_ret_sts_success;
7149
7150 --algo
7151 -- for the given req line the given attribute needs to be chnaged
7152 -- for quantity .. input is the delta qunatity = new qunatity-old quantity
7153 -- hence the new line quantity shall be existing qunatity+delta quantity
7154 -- this is applicable to both mtl_supply and po_requisition_lines_all
7155
7156 -- for need by date.. input is new need by date so update this value to
7157 -- both the tables
7158 IF p_req_line_id IS NOT NULL AND (p_delta_quantity_prim IS NOT NULL OR p_delta_quantity_sec IS NOT NULL )THEN
7159
7160 BEGIN
7161 po_reqchangerequestwf_pvt.update_reqline_quan_changes(
7162 p_req_line_id => p_req_line_id,
7163 p_delta_prim_quantity=> p_delta_quantity_prim,
7164 p_delta_sec_quantity=> p_delta_quantity_sec,
7165 x_return_status =>l_return_status);
7166
7167 EXCEPTION
7168 WHEN OTHERS THEN
7169 ROLLBACK TO update_reqchange_from_so_s;
7170 END;
7171
7172
7173 END IF;
7174
7175 IF (p_req_line_id IS NOT NULL AND p_new_need_by_date IS NOT NULL ) THEN
7176 BEGIN
7177 -- read the profile POR: Sync up Need by date on IR with OM
7178 -- if yes then update the req table
7179 -- else by pass this and return success
7180 l_sync_need_by := nvl(fnd_profile.value('POR_SYNC_NEEDBYDATE_OM'), 'NO');
7181
7182 IF ( l_sync_need_by = 'YES' ) THEN
7183
7184 po_reqchangerequestwf_pvt.update_req_line_date_changes(p_req_line_id=>p_req_line_id,
7185 p_need_by_date=> p_new_need_by_date,
7186 x_return_status =>l_return_status);
7187
7188 END IF;
7189 EXCEPTION
7190 WHEN OTHERS THEN
7191 ROLLBACK TO update_reqchange_from_so_s;
7192 END;
7193
7194 END IF;
7195 x_return_status := fnd_api.g_ret_sts_success;
7196
7197 END update_reqchange_from_so;
7198
7199 -- 14227140 changes ends
7200
7201 -- 15875594 changes starts
7202 /**
7203 * Procedure to clear the change request attachments added at line level
7204 * before inistiating the change request
7205 * (To clear the attachments that are left unprocessed in change request flow).
7206 *
7207 * @param p_req_hdr_id number holds the req header id
7208 * @param x_return_status returns the tstatus of the api
7209 */
7210 PROCEDURE del_req_line_chng_attachments(p_req_hdr_id IN NUMBER,
7211 x_return_status OUT NOCOPY VARCHAR2)
7212 IS
7213 CURSOR l_req_lines_csr(req_hdr_id NUMBER) IS
7214 SELECT REQUISITION_LINE_ID FROM po_requisition_lines_all where REQUISITION_HEADER_ID = req_hdr_id;
7215 l_req_line_id NUMBER;
7216 BEGIN
7217 OPEN l_req_lines_csr(p_req_hdr_id);
7218 LOOP
7219 FETCH l_req_lines_csr INTO
7220 l_req_line_id;
7221 EXIT WHEN l_req_lines_csr%notfound;
7222 IF(l_req_line_id IS NOT NULL) THEN
7223 -- delete the attachmnets of change request
7224 FND_ATTACHED_DOCUMENTS2_PKG.delete_attachments ( 'REQ_LINE_CHANGES',l_req_line_id, NULL,NULL,NULL, NULL,'Y');
7225 --there is no commit in above call
7226 COMMIT;
7227 END IF;
7228 END LOOP;
7229 CLOSE l_req_lines_csr;
7230 x_return_status := fnd_api.g_ret_sts_success;
7231 EXCEPTION
7232 WHEN OTHERS THEN
7233 x_return_status:= fnd_api.g_ret_sts_error;
7234 END del_req_line_chng_attachments;
7235 -- 15875594 changes ends
7236
7237 -- 16839471 changes starts
7238 /**
7239 * Procedure to clear the change request attachments added at line level
7240 *
7241 * @param p_req_line_id number holds the req line id
7242 * @param x_return_status returns the tstatus of the api
7243 */
7244 PROCEDURE del_chng_req_line_attachments(p_req_line_id IN NUMBER,
7245 x_return_status OUT NOCOPY VARCHAR2)
7246 IS
7247 l_progress varchar2(3):='000';
7248 l_log_head CONSTANT VARCHAR2(100) := c_log_head || 'del_chng_req_line_attachments';
7249
7250 BEGIN
7251 IF(p_req_line_id IS NOT NULL) THEN
7252 IF g_debug_stmt THEN
7253 l_progress :='001';
7254 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
7255 END IF;
7256 -- delete the attachmnets of change request
7257 FND_ATTACHED_DOCUMENTS2_PKG.delete_attachments ( 'REQ_LINE_CHANGES',p_req_line_id, NULL,NULL,NULL, NULL,'Y');
7258 --there is no commit in above call
7259 IF g_debug_stmt THEN
7260 l_progress :='002';
7261 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
7262 END IF;
7263 COMMIT;
7264 END IF;
7265 x_return_status := fnd_api.g_ret_sts_success;
7266 EXCEPTION
7267 WHEN OTHERS THEN
7268 x_return_status:= fnd_api.g_ret_sts_error;
7269 IF g_debug_stmt THEN
7270 l_progress :='003';
7271 po_debug.debug_var(l_log_head, l_progress, 'p_req_line_id', p_req_line_id);
7272 po_debug.debug_var(l_log_head, l_progress, 'x_return_status', x_return_status);
7273 END IF;
7274
7275 END del_chng_req_line_attachments;
7276 -- 16839471 changes ends
7277
7278
7279 END po_rco_validation_pvt;