DBA Data[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;