DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_OM_INTEGRATION_GRP

Source


1 PACKAGE BODY PO_OM_INTEGRATION_GRP AS
2 /* $Header: POXGOMIB.pls 120.6 2011/01/28 09:38:15 mmaramga ship $*/
3 
4 --CONSTANTS
5 
6 G_PKG_NAME CONSTANT varchar2(30) := 'PO_OM_INTEGRATION_GRP';
7 
8 c_log_head    CONSTANT VARCHAR2(50) := 'po.plsql.'|| G_PKG_NAME || '.';
9 
10 -- Read the profile option that enables/disables the debug log
11 g_fnd_debug VARCHAR2(1) := NVL(FND_PROFILE.VALUE('AFLOG_ENABLED'),'N');
12 
13 g_debug_stmt  CONSTANT BOOLEAN := PO_DEBUG.is_debug_stmt_on;
14 g_debug_unexp CONSTANT BOOLEAN := PO_DEBUG.is_debug_unexp_on;
15 
16 -- START Forward declarations for package private procedures:
17 PROCEDURE call_po_change_api (
18   p_chg           IN OUT NOCOPY PO_CHANGES_REC_TYPE,
19   x_return_status OUT NOCOPY VARCHAR2
20 );
21 -- END Forward declarations for package private procedures
22 
23 -------------------------------------------------------------------------------
24 --Start of Comments
25 --Name: update_req_po
26 --Pre-reqs:
27 --  None.
28 --Modifies:
29 --  None.
30 --Locks:
31 --  None.
32 --Function:
33 --  Validate and Update Requisition and Purchase Order/Release. This procedure
34 --  is called by OM to synchroize key attribute values on Sales Order with the
35 --  corresponding Drop Ship Purchasing Documents.
36 --Parameters:
37 --IN:
38 --p_api_version
39 --  Specifies API version.
40 --p_req_header_id
41 --  Specifies Requisition Header ID.
42 --  The Req HeaderId/LineId identify the drop ship requisition line of
43 --  the backing sales order line
44 --p_req_line_id
45 --  Specifies Requisition Line ID.
46 --  The Req HeaderId/LineId identify the drop ship requisition line of
47 --  the backing sales order line
48 --p_po_header_id := NULL
49 --  Specifies Purchase Order Header ID.
50 --  The PO HeaderId/LineId/LineLocationId identify the drop ship PO Shipment of
51 --  the backing sales order line
52 --p_po_release_id := NULL
53 --  Specifies Purchase Order Release ID.
54 --  The PO ReleaseId/LineId/LineLocationId identify the drop ship
55 --  Release Shipment of the backing sales order line
56 --p_po_line_id := NULL
57 --  Specifies Purchase Order Line ID.
58 --  The PO LineId/LineLocationId together with a PO HeaderId or ReleaseId
59 --  identify the drop ship PO/Release Shipment of the backing sales order line
60 --p_po_line_location_id := NULL
61 --  Specifies Purchase Order Shipment ID.
62 --  The PO LineId/LineLocationId together with a PO HeaderId or ReleaseId
63 --  identify the drop ship PO/Release Shipment of the backing sales order line
64 --p_quantity := NULL
65 --  The new quantity value to update on Requisition Line and PO/Release Shipment
66 --  When quantity changes on SO Line, both p_quantity and p_secondary_quantity
67 --  should be passed in with latest values on SO line.
68 --p_secondary_quantity := NULL
69 --  The new secondary quantity value to update on Requisition Line
70 --  and PO/Release Shipment. This should be passed only when quantity changes
71 --  on SO. This should NOT be passed if sec qty changes but no change to qty
72 --p_need_by_date := NULL
73 --  The new need by date value to update on Requisition Line and
74 --  PO/Release Shipment. This field is called Schedule Date on SO Line.
75 --p_ship_to_location_id := NULL
76 --  The new Ship To Location to update on Requisition Line and PO/Release Shipment
77 --p_sales_order_update_date := NULL
78 --  The new sales order update date to update on PO/Release Shipment.
79 --  When any of the referenced data elements on SO change, this pararameter is
80 --  sent in with value of SYSDATE.
81 --OUT:
82 --x_return_status
83 --  Indicates API return status as 'S', 'E' or 'U'.
84 --x_msg_count
85 --  Number of Error messages
86 --x_msg_data
87 --  Error messages body
88 --Notes:
89 --  Requisition and/or PO can be in a different Operating Unit from the current one
90 --Testing:
91 --  Call the API when only Requisition Exist, PO/Release Exist
92 --    and for all the combinations of attributes.
93 --End of Comments
94 -------------------------------------------------------------------------------
95 
96 PROCEDURE update_req_po
97 (
98     p_api_version           IN NUMBER,
99     p_req_header_id         IN PO_TBL_NUMBER,
100     p_req_line_id           IN PO_TBL_NUMBER,
101     p_po_header_id          IN PO_TBL_NUMBER := NULL,
102     p_po_release_id         IN PO_TBL_NUMBER := NULL,
103     p_po_line_id            IN PO_TBL_NUMBER := NULL,
104     p_po_line_location_id   IN PO_TBL_NUMBER := NULL,
105     p_quantity              IN PO_TBL_NUMBER := NULL,
106     p_secondary_quantity    IN PO_TBL_NUMBER := NULL,
107     p_need_by_date          IN PO_TBL_DATE := NULL,
108     p_ship_to_location_id   IN PO_TBL_NUMBER := NULL,
109     p_sales_order_update_date IN PO_TBL_DATE := NULL,
110     p_preferred_grade	    IN PO_TBL_VARCHAR240 := NULL, --<INVCONV R12>
111     x_return_status         OUT NOCOPY  VARCHAR2,
112     x_msg_count             OUT NOCOPY  NUMBER,
113     x_msg_data              OUT NOCOPY  VARCHAR2
114 )
115 IS
116 l_api_name    CONSTANT VARCHAR(30) := 'UPDATE_REQ_PO';
117 l_api_version CONSTANT NUMBER := 1.0;
118 l_progress    VARCHAR2(3) := '000';
119 l_log_head CONSTANT VARCHAR2(100) := c_log_head || '.' || l_api_name;
120 
121 -- Bug 3292895 START
122 TYPE indexed_tbl_number IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
123 
124 l_processed_pos         INDEXED_TBL_NUMBER;
125 l_processed_releases    INDEXED_TBL_NUMBER;
126 l_processed_reqs        INDEXED_TBL_NUMBER;
127 
128 l_cur_po_header_id      PO_HEADERS_ALL.po_header_id%TYPE;
129 l_cur_po_release_id     PO_RELEASES_ALL.po_release_id%TYPE;
130 l_cur_req_header_id     PO_REQUISITION_HEADERS_ALL.requisition_header_id%TYPE;
131 l_start_index           NUMBER;
132 
133 l_po_changes            PO_CHANGES_REC_TYPE;
134 l_errors                PO_API_ERRORS_REC_TYPE;
135 l_req_changes           PO_REQ_CHANGES_REC_TYPE;
136 -- Bug 3292895 END
137 
138 l_quantity_ordered      PO_TBL_NUMBER := p_quantity;
139 
140 l_original_org_id     NUMBER  := PO_MOAC_UTILS_PVT.get_current_org_id ;  -- <R12 MOAC> added
141 l_document_org_id       PO_HEADERS.ORG_ID%TYPE;
142 l_count                 NUMBER;
143 
144 -- Bug# 8970502 : Added the following variables
145 
146 l_request_unit_of_measure PO_REQUISITION_LINES_ALL.UNIT_MEAS_LOOKUP_CODE%TYPE;
147 l_request_secondary_uom PO_REQUISITION_LINES_ALL.SECONDARY_UNIT_OF_MEASURE%TYPE;
148 
149 --Bug# 4640038 Start, Added the following variable
150 
151 l_po_request_unit_of_measure PO_LINES_ALL.UNIT_MEAS_LOOKUP_CODE%TYPE;
152 l_po_request_secondary_uom   PO_LINES_ALL.SECONDARY_UOM%TYPE;
153 l_so_request_unit_of_measure mtl_units_of_measure.UNIT_OF_MEASURE_TL%TYPE;
154 l_so_request_secondary_uom   mtl_units_of_measure.UNIT_OF_MEASURE_TL%TYPE;
155 l_uom_conversion_rate NUMBER := 1;
156 l_suom_conversion_rate NUMBER := 1;
157 l_secondary_quantity_ordered  PO_TBL_NUMBER := p_secondary_quantity;
158 l_item_id po_lines.item_id%TYPE;
159 
160 --Bug# 4640038 End
161 
162 -- Bug 3639067
163 l_drop_ship_flag        PO_LINE_LOCATIONS_ALL.drop_ship_flag%TYPE;
164 
165 BEGIN
166 
167 IF g_fnd_debug = 'Y' THEN
168     IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
169       FND_LOG.string(FND_LOG.LEVEL_STATEMENT, c_log_head || '.'||l_api_name||'.'
170           || l_progress, 'Entering Procedure '||l_api_name);
171     END IF;
172 END IF;
173 
174 -- Standard call to check for call compatibility
175 l_progress := '010';
176 IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name, G_PKG_NAME) THEN
177     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
178 END IF;
179 
180 SAVEPOINT PO_OM_GRP_UPDATE_REQ_PO_SP;
181 
182 -- Bug 3292895 START
183 -- Rewrote the grouping logic for PO shipments / requistion lines so that
184 -- it does not use nested tables, which are not supported in Oracle 8i.
185 
186 -- Group the changes to various PO Shipments by po_header_id/po_release_id
187 -- and call the PO Change API for each PO/release.
188 l_progress := '020';
189 
190 LOOP
191   l_cur_po_header_id := NULL;
192   l_cur_po_release_id := NULL;
193 
194   -- Find the next PO or release to process.
195   l_progress := '030';
196   FOR i IN 1..p_po_header_id.count LOOP
197 
198     IF (p_po_release_id(i) IS NOT NULL)
199        AND (NOT l_processed_releases.EXISTS(p_po_release_id(i))) THEN
200       -- We found a release that has not been processed yet.
201       l_cur_po_release_id := p_po_release_id(i);
202       l_processed_releases(l_cur_po_release_id) := 1; -- Mark it as processed.
203       -- Bug 3691067. For a release, mark its BPA also as processed because
204       --    changes to the Sales Order should only be reflected in the Release
205       --    not its corresponding Blanket
206       l_processed_pos(p_po_header_id(i)) := 1;
207       l_start_index := i;
208       EXIT;
209     END IF;
210 
211     IF (p_po_header_id(i) IS NOT NULL)
212        AND (NOT l_processed_pos.EXISTS(p_po_header_id(i))) THEN
213       -- We found a PO that has not been processed yet.
214       l_cur_po_header_id := p_po_header_id(i);
215       l_processed_pos(l_cur_po_header_id) := 1; -- Mark it as processed.
216       l_start_index := i;
217       EXIT;
218     END IF;
219 
220   END LOOP; -- 1..p_po_header_id.count
221 
222   -- Exit the loop once all POs/releases have been processed.
223   EXIT WHEN ((l_cur_po_header_id IS NULL) AND (l_cur_po_release_id IS NULL));
224 
225   -- Create a change object for the PO/release.
226   l_progress := '040';
227   l_po_changes := PO_CHANGES_REC_TYPE.create_object (
228                     p_po_header_id => l_cur_po_header_id,
229                     p_po_release_id => l_cur_po_release_id );
230 
231   -- Add the shipment changes for this PO/release to the change object.
232   l_progress := '050';
233   FOR i IN l_start_index..p_po_header_id.count LOOP
234     IF ((l_cur_po_header_id IS NOT NULL)
235         AND (l_cur_po_header_id = p_po_header_id(i))) OR
236        ((l_cur_po_release_id IS NOT NULL)
237         AND (l_cur_po_release_id = p_po_release_id(i))) THEN
238 
239       -- Bug 3639067 START
240       -- Only synchronize if the shipment is flagged as drop ship.
241       -- (Pre-11.5.10 drop shipments may still have drop_ship_flag of NULL
242       -- if the upgrade script poxupgds.sql found discrepancies between the
243       -- sales order, requisition, and PO. In this case, we should not
244       -- automatically synchronize SO changes to the req/PO.)
245       SELECT drop_ship_flag
246       INTO l_drop_ship_flag
247       FROM po_line_locations_all
248       WHERE line_location_id = p_po_line_location_id(i);
249 
250       IF (l_drop_ship_flag = 'Y') THEN
251 
252         --Bug 3256289: Pass ReqLine's UOM, SecondaryUOM to Change PO API as request UOMs
253         -- Bug# 4640038, Now getting the uom from
254         -- Drop ship sales order line and convering the quantity
255         -- to the PO UOM.
256 
257       Begin
258 
259        l_progress := '052';
260 
261         -- Bug# 4640038, Get the uom and secondary uom of sales order line
262         --bug5606683 changed the following sql select clause to get the UOM instead of
263         -- their translated value.
264        SELECT puom.unit_of_measure,
265               suom.unit_of_measure
266          INTO l_so_request_unit_of_measure,
267               l_so_request_secondary_uom
268          FROM oe_order_lines_all ol,
269               oe_drop_ship_sources ds,
270               mtl_units_of_measure puom,
271               mtl_units_of_measure suom
272         WHERE ol.line_id=ds.line_id
273           AND ds.line_location_id= p_po_line_location_id(i)
274         and ol.order_quantity_uom= puom.uom_code
275         and ol.ordered_quantity_uom2=suom.uom_code(+);
276 
277       Exception
278 
279         When OTHERS then
280 
281           IF (g_debug_stmt) THEN
282               PO_DEBUG.debug_stmt (
283               p_log_head => l_log_head,
284               p_token    => l_progress,
285               p_message  => 'Exception while retrieving drop ship row :' || p_po_line_location_id(i) );
286           END IF;
287 
288       End;
289 
290 
291       IF (g_debug_stmt) THEN
292           PO_DEBUG.debug_stmt (
293           p_log_head => l_log_head,
294           p_token    => l_progress,
295           p_message  => 'Sales Order uom :' ||l_so_request_unit_of_measure||', Secondary UOM :'||l_so_request_secondary_uom);
296       END IF;
297 
298        l_progress := '054';
299 
300         -- Bug# 4640038, Get the uom and secondary uom of PO line
301 
302        Select item_id ,
303               unit_meas_lookup_code ,
304               secondary_uom
305         INTO l_item_id,
306              l_po_request_unit_of_measure,
307              l_po_request_secondary_uom
308         from po_lines_all
309        WHERE po_line_id = p_po_line_id(i);
310 
311       IF (g_debug_stmt) THEN
312           PO_DEBUG.debug_stmt (
313           p_log_head => l_log_head,
314           p_token    => l_progress,
315           p_message  => 'PO uom :' ||l_po_request_unit_of_measure||', Secondary UOM :'||l_po_request_secondary_uom);
316 
317       END IF;
318 
319       -- Bug# 4640038, Get the conversion rate of uom from SO to PO
320       l_progress := '056';
321       IF l_po_request_unit_of_measure IS NOT NULL AND
322          l_so_request_unit_of_measure IS NOT NULL THEN
323          IF  l_po_request_unit_of_measure <> l_so_request_unit_of_measure then
324             l_uom_conversion_rate := nvl(po_uom_s.po_uom_convert(
325                                l_so_request_unit_of_measure,
326                                l_po_request_unit_of_measure,
327                                l_item_id),1);
328             IF (g_debug_stmt) THEN
329                PO_DEBUG.debug_stmt (
330                 p_log_head => l_log_head,
331                 p_token    => l_progress,
332                 p_message  => 'PO UOM conversion rate :' ||to_char(l_uom_conversion_rate));
333             END IF;
334          END IF;
335       END IF;
336 
337       -- Bug# 4640038, Get the conversion rate of secondary uom from SO to PO
338       l_progress := '058';
339       IF l_po_request_secondary_uom is not NULL AND
340          l_so_request_secondary_uom is not NULL THEN
341          IF l_po_request_secondary_uom <> l_so_request_secondary_uom THEN
342             l_suom_conversion_rate := nvl(po_uom_s.po_uom_convert(
343                                l_so_request_secondary_uom,
344                                l_po_request_secondary_uom,
345                                l_item_id),1);
346             IF (g_debug_stmt) THEN
347                PO_DEBUG.debug_stmt (
348                 p_log_head => l_log_head,
349                 p_token    => l_progress,
350                 p_message  => 'PO Secondary UOM conversion rate :' ||to_char(l_suom_conversion_rate));
351             END IF;
352          END IF;
353       END IF;
354 
355         /*
356 
357         Bug# 4640038, Commented out this code
358         The Requisition could be in a different uom that the sales order
359         When changing the quantity iof the SO we need to pass the quantity
360         converted to the PO UOM as the PO ans SO can be in different UOM.
361         We will convert the SO quantity to the PO Quantity and pass it
362         to the change order api.
363 
364 
365         SELECT unit_meas_lookup_code, secondary_unit_of_measure
366         INTO l_request_unit_of_measure, l_request_secondary_uom
367         FROM po_requisition_lines_all
368         WHERE requisition_line_id = p_req_line_id(i);
369 
370        */
371 
372 	--Bug 3239540: OM passes p_quantity as the new open, undelivered
373         --quantity. We need to add the quantity delivered:
374         --  new quantity ordered = new undelivered quantity + quantity delivered
375         -- Bug# 4640038 Added the conversion rate calculation below
376 
377         IF (p_quantity(i) IS NULL) THEN
378           l_quantity_ordered(i) := NULL;
379 
380         ELSE
381 
382 	  SELECT round((p_quantity(i) * l_uom_conversion_rate),5) + nvl(sum(nvl(quantity_delivered, 0)), 0)
383           INTO l_quantity_ordered(i)
384           FROM po_distributions_all
385           WHERE line_location_id = p_po_line_location_id(i);
386 
387         END IF;
388 
389         -- Bug# 4640038 Added the conversion rate calculation below
390 
391         IF (p_secondary_quantity(i) IS NULL) THEN
392           l_secondary_quantity_ordered(i) := NULL;
393         ELSE
394 
395          SELECT round((p_secondary_quantity(i) * l_suom_conversion_rate),5) + NVL(SUM(NVL(secondary_quantity_received,0)),0)
396                  INTO l_secondary_quantity_ordered(i)
397           FROM   po_line_locations_all
398           WHERE  line_location_id = p_po_line_location_id(i);
399         END IF;
400 
401 
402         -- Add this shipment change to the PO change object.
403         l_po_changes.shipment_changes.add_change (
404             p_po_line_location_id     => p_po_line_location_id(i),
405             p_quantity                => l_quantity_ordered(i),
406             p_request_unit_of_measure => l_po_request_unit_of_measure,
407             p_secondary_quantity      => p_secondary_quantity(i),
408             p_request_secondary_uom   => l_po_request_secondary_uom,
409             p_need_by_date            => p_need_by_date(i),
410             p_ship_to_location_id     => p_ship_to_location_id(i),
411             p_preferred_grade	      => p_preferred_grade(i),   --<INVCONV R12>
412             p_sales_order_update_date => p_sales_order_update_date(i) );
413 
414       -- Bug 3639067 START
415       ELSE -- l_drop_ship_flag is not Y
416         IF (g_debug_stmt) THEN
417           PO_DEBUG.debug_stmt (
418             p_log_head => l_log_head,
419             p_token    => l_progress,
420             p_message  => 'Skip this PO shipment - drop_ship_flag is not Y: '
421                           || p_po_line_location_id(i) );
422         END IF;
423       END IF; -- l_drop_ship_flag
424       -- Bug 3639067 END
425 
426     END IF;
427   END LOOP; -- l_start_index..p_po_header_id.count
428 
429   -- Update the PO/Release by calling the PO Change API.
430   -- Bug 3248723 START
431   l_progress := '060';
432   IF (l_po_changes.shipment_changes.get_count > 0) THEN -- Bug 3639067
433     call_po_change_api ( p_chg => l_po_changes,
434                          x_return_status => x_return_status );
435   END IF; -- Bug 3639067
436   -- Bug 3248723 END
437 
438   IF (x_return_status = FND_API.G_RET_STS_ERROR) THEN
439       RAISE FND_API.g_exc_error;
440   ELSIF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
441       RAISE FND_API.g_exc_unexpected_error;
442   END IF;
443 
444 END LOOP;
445 
446 -- Group the changes to various requisition lines by requisition_header_id
447 -- and call the Req Change API for each requisition.
448 l_progress := '200';
449 
450 LOOP
451   l_cur_req_header_id := NULL;
452 
453   -- Find the next requisition to process.
454   l_progress := '210';
455   FOR i IN 1..p_req_header_id.count LOOP
456 
457     IF (p_req_header_id(i) IS NOT NULL)
458        AND (NOT l_processed_reqs.EXISTS(p_req_header_id(i))) THEN
459       -- We found a requisition that has not been processed yet.
460       l_cur_req_header_id := p_req_header_id(i);
461       l_processed_reqs(l_cur_req_header_id) := 1; -- Mark it as processed.
462       l_start_index := i;
463       EXIT;
464     END IF;
465 
466   END LOOP; -- 1..p_req_header_id.count
467 
468   -- Exit the loop once all requisitions have been processed.
469   EXIT WHEN (l_cur_req_header_id IS NULL);
470 
471   -- Create a change object for the requisition.
472   l_progress := '220';
473   -- Bug 3331194 Set unit_price, etc. to PO_TBL_NUMBER() instead of NULL.
474   l_req_changes := PO_REQ_CHANGES_REC_TYPE (
475                      req_header_id => l_cur_req_header_id,
476                      line_changes =>
477                        PO_REQ_LINES_REC_TYPE (
478                          req_line_id => PO_TBL_NUMBER(),
479                          unit_price => PO_TBL_NUMBER(),
480                          currency_unit_price => PO_TBL_NUMBER(),
481                          quantity => PO_TBL_NUMBER(),
482                          secondary_quantity => PO_TBL_NUMBER(),
483                          -- preferred_grade    => PO_TBL_VARCHAR240(), --<INVCONV R12>
484                          need_by_date => PO_TBL_DATE(),
485                          deliver_to_location_id => PO_TBL_NUMBER(),
486                          assignment_start_date => PO_TBL_DATE(),
487                          assignment_end_date => PO_TBL_DATE(),
488                          amount => PO_TBL_NUMBER() ),
489                      distribution_changes => null );
490 
491   -- Add the line changes for this requisition to the change object.
492   l_progress := '230';
493   FOR i IN l_start_index..p_req_header_id.count LOOP
494     IF (l_cur_req_header_id = p_req_header_id(i)) THEN
495 
496       -- Bug 3639067 START
497       -- Only synchronize if the line is flagged as drop ship.
498       SELECT drop_ship_flag
499       INTO l_drop_ship_flag
500       FROM po_requisition_lines_all
501       WHERE requisition_line_id = p_req_line_id(i);
502 
503       IF (l_drop_ship_flag = 'Y') THEN
504       -- Bug 3639067 END
505 
506         -- Bug8970502 Start
507 
508  	-- Bug#8970502, Now getting the uom from
509  	-- Drop ship sales order line and convering the quantity
510  	-- to the Req UOM.
511  	Begin
512  	  l_progress := '052';
513 
514  	  -- Bug#8970502, Get the uom and secondary uom of sales order line
515  	  SELECT puom.unit_of_measure,
516  	  suom.unit_of_measure
517  	  INTO l_so_request_unit_of_measure,
518  	  l_so_request_secondary_uom
519  	  FROM oe_order_lines_all ol,
520  	  oe_drop_ship_sources ds,
521  	  mtl_units_of_measure puom,
522  	  mtl_units_of_measure suom
523  	  WHERE ol.line_id=ds.line_id
524  	  AND ds.requisition_line_id= p_req_line_id(i)
525  	  and ol.order_quantity_uom= puom.uom_code
526  	  and ol.ordered_quantity_uom2=suom.uom_code(+);
527  	Exception
528  	When OTHERS then
529  	  IF (g_debug_stmt) THEN
530  	    PO_DEBUG.debug_stmt (
531  	    p_log_head => l_log_head,
532  	    p_token => l_progress,
533  	    p_message => 'Exception while retrieving drop ship row :' || p_req_line_id(i));
534  	  END IF;
535  	End;
536 
537  	IF (g_debug_stmt) THEN
538  	  PO_DEBUG.debug_stmt (
539  	  p_log_head => l_log_head,
540  	  p_token => l_progress,
541  	  p_message => 'Sales Order uom :' ||l_so_request_unit_of_measure||', Secondary UOM :'||l_so_request_secondary_uom);
542  	END IF;
543 
544  	l_progress := '054';
545  	-- Bug#8970502, Get the uom and secondary uom of Req.
546  	Select item_id ,
547  	 unit_meas_lookup_code ,
548  	 secondary_unit_of_measure
549  	INTO l_item_id,
550  	 l_request_unit_of_measure,
551  	 l_request_secondary_uom
552  	from po_requisition_lines_all
553  	WHERE requisition_line_id = p_req_line_id(i);
554 
555  	IF (g_debug_stmt) THEN
556  	  PO_DEBUG.debug_stmt (
557  	  p_log_head => l_log_head,
558  	  p_token => l_progress,
559  	  p_message => 'Req uom :' ||l_request_unit_of_measure||', Secondary UOM :'||
560  	  l_request_secondary_uom);
561  	END IF;
562 
563 
564  	-- Bug#8970502 , Get the conversion rate of uom from SO to Req
565  	l_progress := '056';
566  	IF l_request_unit_of_measure IS NOT NULL AND
567  	   l_request_unit_of_measure IS NOT NULL THEN
568  	  IF l_request_unit_of_measure <> l_so_request_unit_of_measure then
569  	    l_uom_conversion_rate := nvl(po_uom_s.po_uom_convert(
570  	    l_so_request_unit_of_measure,
571  	    l_request_unit_of_measure,
572  	    l_item_id),1);
573  	    IF (g_debug_stmt) THEN
574  	      PO_DEBUG.debug_stmt (
575  	      p_log_head => l_log_head,
576  	      p_token => l_progress,
577  	      p_message => ' Primary UOM conversion rate From Sales Order to req :' ||to_char(
578  	      l_uom_conversion_rate));
579  	    END IF;
580  	  END IF;
581  	END IF;
582 
583  	-- Bug#8970502, Get the conversion rate of secondary uom from SO to Req
584  	l_progress := '058';
585  	IF l_request_secondary_uom is not NULL AND
586  	   l_so_request_secondary_uom is not NULL THEN
587  	  IF l_request_secondary_uom <> l_so_request_secondary_uom THEN
588  	    l_suom_conversion_rate := nvl(po_uom_s.po_uom_convert(
589  	    l_so_request_secondary_uom,
590  	    l_request_secondary_uom,
591  	    l_item_id),1);
592  	    IF (g_debug_stmt) THEN
593  	      PO_DEBUG.debug_stmt (
594  	      p_log_head => l_log_head,
595  	      p_token => l_progress,
596  	      p_message => 'Secondary UOM conversion rate From Sales Order to req :' ||
597  	      to_char(l_suom_conversion_rate));
598  	    END IF;
599  	  END IF;
600  	END IF;
601 
602  	-- Bug#8970502 Added the conversion rate calculation below
603  	IF (p_quantity(i) IS NULL) THEN
604  	  l_quantity_ordered(i) := NULL;
605  	ELSE
606  	  SELECT round((p_quantity(i) * l_uom_conversion_rate),5) + nvl(sum(nvl(
607  	  quantity_delivered, 0)), 0)
608  	  INTO l_quantity_ordered(i)
609  	  FROM po_requisition_lines_all
610  	  WHERE requisition_line_id = p_req_line_id(i);
611  	END IF;
612 
613  	-- Bug#8970502 Added the conversion rate calculation below
614  	IF (p_secondary_quantity(i) IS NULL) THEN
615  	  l_secondary_quantity_ordered(i) := NULL;
616  	ELSE
617  	  SELECT round((p_secondary_quantity(i) * l_suom_conversion_rate),5) + NVL(SUM(NVL(
618  	  secondary_quantity_received,0)),0)
619  	  INTO l_secondary_quantity_ordered(i)
620  	  FROM po_requisition_lines_all
621  	  WHERE requisition_line_id = p_req_line_id(i);
622  	END IF;
623 
624  	-- Bug8970502 End
625 
626 
627         l_req_changes.line_changes.req_line_id.extend(1);
628         l_count := l_req_changes.line_changes.req_line_id.count;
629         l_req_changes.line_changes.req_line_id(l_count) := p_req_line_id(i);
630 
631         l_req_changes.line_changes.unit_price.extend(1);
632         l_req_changes.line_changes.currency_unit_price.extend(1);
633 
634         l_req_changes.line_changes.quantity.extend(1);
635         l_req_changes.line_changes.quantity(l_count) := l_quantity_ordered(i);
636 
637         l_req_changes.line_changes.secondary_quantity.extend(1);
638         l_req_changes.line_changes.secondary_quantity(l_count)
639           := p_secondary_quantity(i);
640 
641         l_req_changes.line_changes.need_by_date.extend(1);
642         l_req_changes.line_changes.need_by_date(l_count)
643           := p_need_by_date(i);
644 
645         l_req_changes.line_changes.deliver_to_location_id.extend(1);
646         l_req_changes.line_changes.deliver_to_location_id(l_count)
647           := p_ship_to_location_id(i);
648 
649         l_req_changes.line_changes.assignment_start_date.extend(1);
650         l_req_changes.line_changes.assignment_end_date.extend(1);
651         l_req_changes.line_changes.amount.extend(1);
652 
653       -- Bug 3639067 START
654       ELSE -- l_drop_ship_flag is not Y
655         IF (g_debug_stmt) THEN
656           PO_DEBUG.debug_stmt (
657             p_log_head => l_log_head,
658             p_token    => l_progress,
659             p_message  => 'Skip this req line - drop_ship_flag is not Y: '
660                           || p_req_line_id(i) );
661         END IF;
662       END IF; -- l_drop_ship_flag
663       -- Bug 3639067 END
664 
665     END IF;
666   END LOOP; -- l_start_index..p_req_header_id.count
667 
668   -- Update the Requisition by calling the Update Requisition API.
669   l_progress := '240';
670 
671   IF (l_req_changes.line_changes.req_line_id.count > 0) THEN -- Bug 3639067
672 
673     -- Retrieve the document's operating unit.
674     SELECT org_id
675     INTO l_document_org_id
676     FROM po_requisition_headers_all
677     WHERE requisition_header_id = l_cur_req_header_id;
678 
679     -- Set Org Context to that of Document
680     PO_MOAC_UTILS_PVT.set_org_context(l_document_org_id) ;         -- <R12 MOAC>
681 
682     l_progress := '250';
683     PO_REQ_DOCUMENT_UPDATE_GRP.update_requisition (
684       p_api_version => 1.0,
685       p_req_changes => l_req_changes,
686       p_update_source => 'OM',
687       x_return_status => x_return_status,
688       x_msg_count  => x_msg_count,
689       x_msg_data  => x_msg_data );
690 
691     IF (x_return_status = FND_API.g_ret_sts_error) THEN
692         RAISE FND_API.g_exc_error;
693     ELSIF (x_return_status = FND_API.g_ret_sts_unexp_error) THEN
694         RAISE FND_API.g_exc_unexpected_error;
695     END IF;
696 
697   END IF; -- l_req_changes... - Bug 3639067
698 
699 END LOOP;
700 -- Bug 3292895 END
701 
702 l_progress := '900';
703 -- Set the org context back to the original operating unit.
704 PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;       -- <R12 MOAC>
705 
706 x_return_status := FND_API.G_RET_STS_SUCCESS;
707 
708 EXCEPTION
709     WHEN FND_API.G_EXC_ERROR THEN
710         ROLLBACK TO PO_OM_GRP_UPDATE_REQ_PO_SP;
711         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
712         x_return_status := FND_API.G_RET_STS_ERROR;
713         -- Set the org context back to the original operating unit.
714         PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;     -- <R12 MOAC>
715     WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
716         ROLLBACK TO PO_OM_GRP_UPDATE_REQ_PO_SP;
717         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
718         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
719         -- Set the org context back to the original operating unit.
720         PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;   -- <R12 MOAC>
721     WHEN OTHERS THEN
722         ROLLBACK TO PO_OM_GRP_UPDATE_REQ_PO_SP;
723         PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
724                                       p_proc_name => l_api_name,
725                                       p_progress => l_progress );
726         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
727         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
728         -- Set the org context back to the original operating unit.
729         PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;   -- <R12 MOAC>
730 
731 END update_req_po;
732 
733 -------------------------------------------------------------------------------
734 --Start of Comments
735 --Name: cancel_req_po
736 --Pre-reqs:
737 --  None.
738 --Modifies:
739 --  None.
740 --Locks:
741 --  None.
742 --Function:
743 --  Validate and Cancel Requisition and Purchase Order/Release. This procedure
744 --  is called by OM when a Drop Ship SO Line is cancelled or deleted.
745 --Parameters:
746 --IN:
747 --p_api_version
748 --  Specifies API version.
749 --p_req_header_id
750 --  Specifies Requisition Header ID.
751 --  The Req HeaderId/LineId identify the drop ship requisition line of
752 --  the backing sales order line
753 --p_req_line_id
754 --  Specifies Requisition Line ID.
755 --  The Req HeaderId/LineId identify the drop ship requisition line of
756 --  the backing sales order line
757 --p_po_header_id := NULL
758 --  Specifies Purchase Order Header ID.
759 --  The PO HeaderId/LineId/LineLocationId identify the drop ship PO Shipment of
760 --  the backing sales order line
761 --p_po_release_id := NULL
762 --  Specifies Purchase Order Header ID.
763 --  The PO ReleaseId/LineId/LineLocationId identify the drop ship
764 --  Release Shipment of the backing sales order line
765 --p_po_line_id := NULL
766 --  Specifies Purchase Order Line ID.
767 --  The PO LineId/LineLocationId together with a PO HeaderId or ReleaseId
768 --  identify the drop ship PO/Release Shipment of the backing sales order line
769 --p_po_line_location_id := NULL
770 --  Specifies Purchase Order Shipment ID.
771 --  The PO LineId/LineLocationId together with a PO HeaderId or ReleaseId
772 --  identify the drop ship PO/Release Shipment of the backing sales order line
773 --OUT:
774 --x_return_status
775 --  Indicates API return status as 'S', 'E' or 'U'.
776 --x_msg_count
777 --  Number of Error messages
778 --x_msg_data
779 --  Error messages body
780 --Notes:
781 --  Requisition and/or PO can be in a different Operating Unit from the current one
782 --Testing:
783 --  Call the API when only Requisition Exist, and when PO/Release also Exist
784 --End of Comments
785 -------------------------------------------------------------------------------
786 
787 PROCEDURE cancel_req_po
788 (
789     p_api_version           IN NUMBER,
790     p_req_header_id         IN PO_TBL_NUMBER,
791     p_req_line_id           IN PO_TBL_NUMBER,
792     p_po_header_id          IN PO_TBL_NUMBER := NULL,
793     p_po_release_id         IN PO_TBL_NUMBER := NULL,
794     p_po_line_id            IN PO_TBL_NUMBER := NULL,
795     p_po_line_location_id   IN PO_TBL_NUMBER := NULL,
796     x_return_status         OUT NOCOPY  VARCHAR2,
797     x_msg_count             OUT NOCOPY  NUMBER,
798     x_msg_data              OUT NOCOPY  VARCHAR2
799 )
800 IS
801 l_api_name    CONSTANT VARCHAR(30) := 'CANCEL_REQ_PO';
802 l_api_version CONSTANT NUMBER := 1.0;
803 l_progress    VARCHAR2(3) := '000';
804 l_log_head CONSTANT VARCHAR2(100) := c_log_head || '.' || l_api_name;
805 
806 l_doc_type PO_DOCUMENT_TYPES.DOCUMENT_TYPE_CODE%TYPE;
807 l_doc_subtype PO_DOCUMENT_TYPES.DOCUMENT_SUBTYPE%TYPE;
808 
809 -- Bug 3248723 START
810 l_original_org_id     NUMBER  := PO_MOAC_UTILS_PVT.get_current_org_id ;     -- <R12 MOAC>
811 l_approved_date         PO_LINE_LOCATIONS_ALL.approved_date%TYPE;
812 l_chg                   PO_CHANGES_REC_TYPE;
813 -- Bug 3248723 END
814 l_document_org_id       PO_HEADERS.ORG_ID%TYPE; -- Bug 3362534
815 
816 -- Bug 3639067 START
817 l_drop_ship_flag        PO_LINE_LOCATIONS_ALL.drop_ship_flag%TYPE;
818 l_session_gt_key        PO_SESSION_GT.key%TYPE;
819 l_req_header_id         PO_TBL_NUMBER;
820 l_req_line_id           PO_TBL_NUMBER;
821 -- Bug 3639067 END
822 
823 BEGIN
824 
825 IF g_fnd_debug = 'Y' THEN
826     IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
827       FND_LOG.string(FND_LOG.LEVEL_STATEMENT, c_log_head || '.'||l_api_name||'.'
828           || l_progress, 'Entering Procedure '||l_api_name);
829     END IF;
830 END IF;
831 
832 -- Standard call to check for call compatibility
833 l_progress := '010';
834 IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name, G_PKG_NAME) THEN
835     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
836 END IF;
837 
838 -- Cancel PO/Release Shipments
839 l_progress := '020';
840 FOR i IN 1..p_po_header_id.count LOOP
841 
842   IF p_po_header_id(i) IS NOT NULL OR p_po_release_id(i) IS NOT NULL THEN
843   --If PO is NOT null, that means PO is created, not just req
844 
845     IF p_po_release_id(i) IS NOT NULL THEN
846         SELECT RELEASE_TYPE,
847                org_id -- Bug 3362534
848         INTO l_doc_subtype,
849              l_document_org_id
850         from  PO_RELEASES_ALL
851         WHERE po_release_id = p_po_release_id(i);
852         l_doc_type := 'RELEASE';
853     ELSE
854         SELECT TYPE_LOOKUP_CODE,
855                org_id -- Bug 3362534
856         INTO l_doc_subtype,
857              l_document_org_id
858         from  PO_HEADERS_ALL
859         WHERE po_header_id = p_po_header_id(i);
860         l_doc_type := 'PO';
861     END IF;
862 
863     -- Bug 3248723 START
864     -- If the shipment has not been approved before, call the PO Change API
865     -- to delete it. Otherwise, call the PO Control API to cancel it.
866 
867     l_progress := '025';
868     SELECT approved_date,
869            drop_ship_flag -- Bug 3639067
870     INTO l_approved_date,
871          l_drop_ship_flag
872     FROM po_line_locations_all
873     WHERE line_location_id = p_po_line_location_id(i);
874 
875     -- Bug 3639067 START
876     -- Only synchronize if the shipment is flagged as drop ship.
877     IF (l_drop_ship_flag = 'Y') THEN
878     -- Bug 3639067 END
879 
880       IF (l_approved_date IS NULL) THEN -- Delete the shipment.
881         l_progress := '030';
882         -- Create a change object with a request to delete the shipment.
883         l_chg := PO_CHANGES_REC_TYPE.create_object (
884                    p_po_header_id => p_po_header_id(i),
885                    p_po_release_id => p_po_release_id(i) );
886         l_chg.shipment_changes.add_change (
887           p_po_line_location_id => p_po_line_location_id(i),
888           p_delete_record => PO_DOCUMENT_UPDATE_GRP.G_PARAMETER_YES );
889 
890         -- Call the PO Change API to delete the shipment.
891         call_po_change_api ( p_chg => l_chg,
892                              x_return_status => x_return_status );
893       ELSE -- Cancel the shipment.
894       -- Bug 3248723 END
895         l_progress := '035';
896 
897         -- Bug 3362534 Set the org context to the operating unit of the document.
898         PO_MOAC_UTILS_PVT.set_org_context(l_document_org_id) ;          -- <R12 MOAC>
899 
900         PO_Document_Control_GRP.control_document
901                (p_api_version      => 1.0,
902                 p_init_msg_list    => FND_API.G_FALSE,
903                 p_commit           => FND_API.G_FALSE,
904                 x_return_status    => x_return_status,
905                 p_doc_type         => l_doc_type,
906                 p_doc_subtype      => l_doc_subtype,
907                 p_doc_id           => p_po_header_id(i),
908                 p_doc_num          => null,
909                 p_release_id       => p_po_release_id(i),
910                 p_release_num      => null,
911                 p_doc_line_id      => p_po_line_id(i),
912                 p_doc_line_num     => null,
913                 p_doc_line_loc_id  => p_po_line_location_id(i),
914                 p_doc_shipment_num => null,
915                 p_source           => 'OM',
916                 p_action           => 'CANCEL',
917                 p_action_date      => SYSDATE,
918                 p_cancel_reason    => 'Order Management',
919                 p_cancel_reqs_flag => 'N',
920                 p_print_flag       => 'N',
921                 p_note_to_vendor   => null);
922       END IF; -- l_approved_date
923 
924       IF (x_return_status = FND_API.g_ret_sts_error) THEN
925           RAISE FND_API.g_exc_error;
926       ELSIF (x_return_status = FND_API.g_ret_sts_unexp_error) THEN
927           RAISE FND_API.g_exc_unexpected_error;
928       END IF;
929 
930     -- Bug 3639067 START
931     ELSE -- l_drop_ship_flag is not Y
932       IF (g_debug_stmt) THEN
933         PO_DEBUG.debug_stmt (
934           p_log_head => l_log_head,
935           p_token    => l_progress,
936           p_message  => 'Skip this PO shipment - drop_ship_flag is not Y: '
937                         || p_po_line_location_id(i) );
938       END IF;
939     END IF; -- l_drop_ship_flag
940     -- Bug 3639067 END
941 
942   END IF; --End of IF p_po_header_id(i) IS NOT NULL ...
943 
944 END LOOP;
945 
946 -- Cancel Req Lines
947 l_progress := '040';
948 
949 -- Bug 3639067 START
950 -- Only synchronize the lines that are flagged as drop ship.
951 -- To do this, we filter p_req_line_id, p_req_header_id to construct
952 -- new tables l_req_line_id, l_req_header_id that contain only the req lines
953 -- with drop_ship_flag = 'Y'.
954 
955 -- SQL What: Retrieve a key to identify our records in PO_SESSION_GT.
956 SELECT PO_SESSION_GT_S.nextval
957 INTO l_session_gt_key
958 FROM dual;
959 
960 ----------------------------------------------------------------
961 -- PO_SESSION_GT column mapping
962 --
963 -- num1   requisition_line_id
964 -- num2   requisition_header_id
965 ----------------------------------------------------------------
966 
967 -- SQL What: Insert into PO_SESSION_GT the IDs of the req lines that have
968 -- drop_ship_flag = 'Y'
969 FORALL i IN 1..p_req_line_id.COUNT
970   INSERT INTO po_session_gt
971   (key, num1, num2)
972   SELECT l_session_gt_key, PRL.requisition_line_id, PRL.requisition_header_id
973   FROM po_requisition_lines_all PRL
974   WHERE PRL.requisition_line_id = p_req_line_id(i)
975   AND PRL.drop_ship_flag = 'Y';
976 
977 -- SQL What: Select the req line and header IDs from PO_SESSION_GT into
978 -- the PL/SQL tables l_req_line_id and l_req_header_id.
979 SELECT GT.num1, GT.num2
980 BULK COLLECT INTO l_req_line_id, l_req_header_id
981 FROM po_session_gt GT
982 WHERE key = l_session_gt_key;
983 
984 IF (g_debug_stmt) THEN
985   PO_DEBUG.debug_var (
986     p_log_head => l_log_head,
987     p_progress => l_progress,
988     p_name => 'l_req_header_id',
989     p_value => l_req_header_id
990   );
991 
992   PO_DEBUG.debug_var (
993     p_log_head => l_log_head,
994     p_progress => l_progress,
995     p_name => 'l_req_line_id',
996     p_value => l_req_line_id
997   );
998 
999   IF (p_req_line_id.COUNT > l_req_line_id.COUNT) THEN
1000     PO_DEBUG.debug_stmt (
1001       p_log_head => l_log_head,
1002       p_token    => l_progress,
1003       p_message  => 'Skipped '||(p_req_line_id.COUNT - l_req_line_id.COUNT)
1004                     ||' req lines whose drop_ship_flag is not Y' );
1005   END IF;
1006 END IF;
1007 
1008 IF (l_req_header_id.COUNT > 0) THEN
1009 -- Bug 3639067 END
1010 
1011   PO_REQ_DOCUMENT_CANCEL_GRP.cancel_requisition
1012       (p_api_version      => 1.0,
1013       p_req_header_id    => l_req_header_id, -- Bug 3639067
1014       p_req_line_id      => l_req_line_id, -- Bug 3639067
1015       p_cancel_date => SYSDATE,
1016       p_cancel_reason => 'Order Management',
1017       p_source => 'OM',
1018       x_return_status  => x_return_status,
1019       x_msg_count  => x_msg_count,
1020       x_msg_data  => x_msg_data);
1021 
1022   IF (x_return_status = FND_API.g_ret_sts_error) THEN
1023       RAISE FND_API.g_exc_error;
1024   ELSIF (x_return_status = FND_API.g_ret_sts_unexp_error) THEN
1025       RAISE FND_API.g_exc_unexpected_error;
1026   END IF;
1027 
1028 END IF; -- l_req_header_id - Bug 3639067
1029 
1030 l_progress := '050';
1031 
1032 x_return_status := FND_API.G_RET_STS_SUCCESS;
1033 
1034 -- Set the org context back to the original operating unit.
1035 PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;   -- <R12 MOAC>
1036 
1037 EXCEPTION
1038     WHEN FND_API.G_EXC_ERROR THEN
1039         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
1040         x_return_status := FND_API.G_RET_STS_ERROR;
1041         -- Set the org context back to the original operating unit.
1042         PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;       -- <R12 MOAC>
1043     WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1044         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
1045         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1046         -- Set the org context back to the original operating unit.
1047         PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;        -- <R12 MOAC>
1048     WHEN OTHERS THEN
1049         PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
1050                                       p_proc_name => l_api_name,
1051                                       p_progress => l_progress );
1052         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
1053         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1054         -- Set the org context back to the original operating unit.
1055         PO_MOAC_UTILS_PVT.set_org_context(l_original_org_id) ;       -- <R12 MOAC>
1056 
1057 END cancel_req_po;
1058 
1059 -- Bug 3248723 START
1060 -------------------------------------------------------------------------------
1061 --Start of Comments
1062 --Name: call_po_change_api
1063 --Pre-reqs:
1064 --  None.
1065 --Modifies:
1066 --  the org context
1067 --Locks:
1068 --  None.
1069 --Function:
1070 --  Switches the org context to the document's operating unit and calls the
1071 --  PO Change API to apply the requested changes.
1072 --Parameters:
1073 --IN:
1074 --p_chg
1075 --  Object with the requested changes
1076 --OUT:
1077 --x_return_status
1078 --  Indicates procedure return status.
1079 --End of Comments
1080 -------------------------------------------------------------------------------
1081 PROCEDURE call_po_change_api (
1082   p_chg           IN OUT NOCOPY PO_CHANGES_REC_TYPE,
1083   x_return_status OUT NOCOPY VARCHAR2
1084 ) IS
1085   l_proc_name CONSTANT VARCHAR2(30) := 'call_po_change_api';
1086 
1087   l_progress              VARCHAR2(3) := '000';
1088   l_authorization_status  PO_HEADERS.AUTHORIZATION_STATUS%TYPE;
1089   l_document_org_id       PO_HEADERS.ORG_ID%TYPE;
1090   l_run_submission_checks VARCHAR2(1);
1091   l_launch_approvals_flag VARCHAR2(1);
1092   l_errors                PO_API_ERRORS_REC_TYPE;
1093 BEGIN
1094   -- Retrieve the document's operating unit.
1095   IF p_chg.po_release_id IS NOT NULL THEN
1096     SELECT org_id, authorization_status
1097     INTO l_document_org_id, l_authorization_status
1098     FROM po_releases_all
1099     WHERE po_release_id = p_chg.po_release_id;
1100   ELSE -- PO
1101     SELECT org_id, authorization_status
1102     INTO l_document_org_id, l_authorization_status
1103     FROM po_headers_all
1104     WHERE po_header_id = p_chg.po_header_id;
1105   END IF;
1106 
1107   l_progress := '010';
1108 
1109   -- Set Org Context to that of Document
1110   PO_MOAC_UTILS_PVT.set_org_context(l_document_org_id) ;     -- <R12 MOAC>
1111 
1112   -- If the PO was in Approved status before the change, then perform
1113   -- submission checks and launch the PO Approval workflow to re-approve
1114   -- the PO after making the changes.
1115   IF l_authorization_status = 'APPROVED' THEN
1116     l_run_submission_checks := FND_API.G_TRUE;
1117     l_launch_approvals_flag := FND_API.G_TRUE;
1118   ELSE
1119     l_run_submission_checks := FND_API.G_FALSE;
1120     l_launch_approvals_flag := FND_API.G_FALSE;
1121   END IF;
1122 
1123   l_progress := '020';
1124   PO_DOCUMENT_UPDATE_GRP.update_document (
1125     p_api_version              => 1.0,
1126     p_init_msg_list            => FND_API.G_FALSE,
1127     x_return_status            => x_return_status,
1128     p_changes                  => p_chg,
1129     p_run_submission_checks    => l_run_submission_checks,
1130     p_launch_approvals_flag    => l_launch_approvals_flag,
1131     p_buyer_id                 => null,
1132     p_update_source            => PO_DOCUMENT_UPDATE_GRP.G_UPDATE_SOURCE_OM,
1133     p_override_date            => null,
1134     x_api_errors               => l_errors,
1135     p_approval_background_flag => PO_DOCUMENT_UPDATE_GRP.G_PARAMETER_NO
1136   );
1137 
1138   l_progress := '030';
1139   IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1140       -- If non success status, transfer l_errors to FND Message Stack
1141       FOR j IN 1..l_errors.message_text.count LOOP
1142         FND_MESSAGE.set_name('PO', 'PO_WRAPPER_MESSAGE');
1143         FND_MESSAGE.set_token('MESSAGE', l_errors.message_text(j));
1144         FND_MSG_PUB.Add;
1145       END LOOP;
1146   END IF;
1147 
1148 EXCEPTION
1149   WHEN OTHERS THEN
1150     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
1151                                   p_proc_name => l_proc_name,
1152                                   p_progress => l_progress );
1153     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1154 END call_po_change_api;
1155 -- Bug 3248723 END
1156 
1157 -- <DOC PURGE FPJ START>
1158 
1159 -------------------------------------------------------------------------------
1160 --Start of Comments
1161 --Name: purge
1162 --Pre-reqs:
1163 --  None.
1164 --Modifies:
1165 --  drop_ship_flag
1166 --Locks:
1167 --  None.
1168 --Function:
1169 --  Perform necessary action on PO side when a Sales Order is purged.
1170 --  If the purged SO is a drop ship SO, the drop ship flag at PO shipment
1171 --  needs to be updated to NULL.
1172 --Parameters:
1173 --IN:
1174 --p_api_version
1175 --  Specifies API version.
1176 --p_init_msg_list
1177 --  Determines whether the message stacked can be initialized within the API
1178 --p_commit
1179 --  Determines whether the API will commit
1180 --p_entity
1181 --  Types of ids that are passing in. For now it has to be 'PO_LINE_LOCATIONS'
1182 --p_entity_id_tbl
1183 --  A table containing ids of the records to be updated. For now they must
1184 --  be drop shipments on a PO.
1185 --OUT:
1186 --IN OUT:
1187 --x_return_status
1188 --  Indicates API return status as 'S', 'E' or 'U'.
1189 --x_msg_count
1190 --  Number of Error messages
1191 --x_msg_data
1192 --  Error messages body
1193 --Notes:
1194 --Testing:
1195 --End of Comments
1196 -------------------------------------------------------------------------------
1197 
1198 PROCEDURE Purge
1199 ( p_api_version          IN            NUMBER
1200  ,p_init_msg_list        IN            VARCHAR2
1201  ,p_commit               IN            VARCHAR2
1202  ,x_return_status        OUT NOCOPY    VARCHAR2
1203  ,x_msg_count            OUT NOCOPY    NUMBER
1204  ,x_msg_data             OUT NOCOPY    VARCHAR2
1205  ,p_entity               IN            VARCHAR2
1206  ,p_entity_id_tbl        IN            PO_TBL_NUMBER
1207 )
1208 IS
1209   l_api_name VARCHAR2(50) := 'Purge';
1210   l_api_version NUMBER := 1.0;
1211   l_progress VARCHAR2(3);
1212   l_log_head CONSTANT VARCHAR2(100) := c_log_head || '.' || l_api_name;
1213 
1214 BEGIN
1215 
1216     l_progress := '000';
1217 
1218     x_return_status := FND_API.G_RET_STS_SUCCESS;
1219 
1220     IF (g_fnd_debug = 'Y') THEN
1221         PO_DEBUG.debug_begin
1222         ( p_log_head => l_log_head
1223         );
1224     END IF;
1225 
1226     IF (FND_API.to_boolean(p_init_msg_list)) THEN
1227         FND_MSG_PUB.initialize;
1228     END IF;
1229 
1230     IF (NOT FND_API.Compatible_API_Call
1231             ( p_current_version_number => l_api_version,
1232               p_caller_version_number  => p_api_version,
1233               p_api_name               => l_api_name,
1234               p_pkg_name               => g_pkg_name
1235             )
1236        ) THEN
1237 
1238        l_progress := '010';
1239        RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1240     END IF;
1241 
1242     IF (p_entity_id_tbl IS NULL) THEN
1243         l_progress := '020';
1244 
1245         IF (g_fnd_debug = 'Y') THEN
1246             PO_DEBUG.debug_stmt
1247             ( p_log_head => l_log_head,
1248               p_token    => l_progress,
1249               p_message  => 'entity_id_tbl is empty. quitting'
1250             );
1251         END IF;
1252 
1253         RETURN;
1254     END IF;
1255 
1256     IF (p_entity = 'PO_LINE_LOCATIONS') THEN
1257         l_progress := '030';
1258 
1259         IF (g_fnd_debug = 'Y') THEN
1260             PO_DEBUG.debug_stmt
1261             ( p_log_head => l_log_head,
1262               p_token    => l_progress,
1263               p_message  => 'p_entity_id_tbl.COUNT=' ||
1264                             p_entity_id_tbl.COUNT
1265             );
1266         END IF;
1267 
1268         --SQL What: Set drop ship flag on the PO shipment to NULL when
1269         --          the assocaited SO is purged
1270         --SQL Why:  The association between SO and PO will be removed once
1271         --          the SO is purged.
1272 
1273         FORALL i IN 1..p_entity_id_tbl.COUNT
1274             UPDATE po_line_locations_all PLL
1275             SET    drop_ship_flag = ''
1276             WHERE  PLL.line_location_id = p_entity_id_tbl(i);
1277 
1278         IF (g_fnd_debug = 'Y') THEN
1279             PO_DEBUG.debug_stmt
1280             ( p_log_head => l_log_head,
1281               p_token    => l_progress,
1282               p_message  => '# of updated rows: ' || SQL%ROWCOUNT
1283             );
1284         END IF;
1285 
1286     ELSE
1287         l_progress := '050';
1288 
1289         IF (g_fnd_debug = 'Y') THEN
1290             PO_DEBUG.debug_stmt
1291             ( p_log_head => l_log_head,
1292               p_token    => l_progress,
1293               p_message  => 'Unknown entity: ' || p_entity
1294             );
1295         END IF;
1296 
1297         FND_MSG_PUB.add_exc_msg
1298         ( p_pkg_name        => g_pkg_name,
1299           p_procedure_name  => l_api_name || '.' || l_progress,
1300           p_error_text      => 'Unknown entity: ' || p_entity
1301         );
1302 
1303         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1304 
1305     END IF;
1306 
1307     l_progress := '060';
1308 
1309     IF (FND_API.to_boolean(p_commit)) THEN
1310 
1311         l_progress := '070';
1312         COMMIT;
1313 
1314     END IF;
1315 
1316     IF (g_fnd_debug = 'Y') THEN
1317         PO_DEBUG.debug_end
1318         ( p_log_head => l_log_head
1319         );
1320     END IF;
1321 
1322 EXCEPTION
1323 WHEN OTHERS THEN
1324     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1325     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
1326                                   p_proc_name => l_api_name,
1327                                   p_progress => l_progress );
1328     FND_MSG_PUB.count_and_get
1329     ( p_encoded => 'F',
1330       p_count   => x_msg_count,
1331       p_data    => x_msg_data
1332     );
1333 
1334 END Purge;
1335 
1336 
1337 -------------------------------------------------------------------------------
1338 --Start of Comments
1339 --Name: validate_purge
1340 --Pre-reqs:
1341 --  None.
1342 --Modifies:
1343 --  None
1344 --Locks:
1345 --  None.
1346 --Function:
1347 --  Given the drop shipment id of a PO, this procedure determines whether the
1348 --  corresponing SO is purgable. This is called before a Sales Order is about
1349 --  to be purged
1350 --Parameters:
1351 --IN:
1352 --p_api_version
1353 --  Specifies API version.
1354 --p_init_msg_list
1355 --  Determines whether the message stacked can be initialized within the API
1356 --p_commit
1357 --  Determines whether the API will commit
1358 --p_entity
1359 --  Types of ids that are passing in. For now it has to be 'PO_LINE_LOCATIONS'
1360 --p_entity_id_tbl
1361 --  A table containing ids of the records to checked. For now they must
1362 --  be the PO shipments, with the corrsponding SO line that are about to be
1363 --  purged
1364 --IN OUT:
1365 --OUT:
1366 --x_return_status
1367 --  Indicates API return status as 'S', 'E' or 'U'.
1368 --x_msg_count
1369 --  Number of Error messages
1370 --x_msg_data
1371 --  Error messages body
1372 --x_purge_allowed_tbl
1373 --  Returns 'Y' if the corresponding shipment in p_entity_id_tbl is in a state
1374 --  where the corresponding SO is allowed to be purged. (and 'N' otherwise)
1375 --  The number of entries returned in this structure should be the same as
1376 --  that in p_entity_id_tbl. This API will always re-initialize this parameter
1377 --Notes:
1378 --Testing:
1379 --End of Comments
1380 -------------------------------------------------------------------------------
1381 
1382 PROCEDURE Validate_Purge
1383 ( p_api_version          IN            NUMBER
1384  ,p_init_msg_list        IN            VARCHAR2
1385  ,p_commit               IN            VARCHAR2
1386  ,x_return_status        OUT NOCOPY    VARCHAR2
1387  ,x_msg_count            OUT NOCOPY    NUMBER
1388  ,x_msg_data             OUT NOCOPY    VARCHAR2
1389  ,p_entity               IN            VARCHAR2
1390  ,p_entity_id_tbl        IN            PO_TBL_NUMBER
1391  ,x_purge_allowed_tbl    OUT NOCOPY    PO_TBL_VARCHAR1
1392 )
1393 IS
1394   l_api_name VARCHAR2(50) := 'Validate_Purge';
1395   l_api_version NUMBER := 1.0;
1396   l_progress VARCHAR2(3);
1397   l_log_head CONSTANT VARCHAR2(100) := c_log_head || '.' || l_api_name;
1398 
1399   l_seq_id   NUMBER;
1400 
1401   l_order_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
1402 BEGIN
1403     l_progress := '000';
1404 
1405     x_return_status := FND_API.G_RET_STS_SUCCESS;
1406 
1407     IF (g_fnd_debug = 'Y') THEN
1408         PO_DEBUG.debug_begin
1409         ( p_log_head => l_log_head
1410         );
1411     END IF;
1412 
1413     IF (FND_API.to_boolean(p_init_msg_list)) THEN
1414         FND_MSG_PUB.initialize;
1415     END IF;
1416 
1417     IF (NOT FND_API.Compatible_API_Call
1418             ( p_current_version_number => l_api_version,
1419               p_caller_version_number  => p_api_version,
1420               p_api_name               => l_api_name,
1421               p_pkg_name               => g_pkg_name
1422             )
1423        ) THEN
1424 
1425        l_progress := '010';
1426        RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1427     END IF;
1428 
1429     IF (p_entity_id_tbl IS NULL) THEN
1430         l_progress := '020';
1431 
1432         IF (g_fnd_debug = 'Y') THEN
1433             PO_DEBUG.debug_stmt
1434             ( p_log_head => l_log_head,
1435               p_token    => l_progress,
1436               p_message  => 'entity_id_tbl is empty. quitting'
1437             );
1438         END IF;
1439 
1440         RETURN;
1441     END IF;
1442 
1443     l_order_tbl.extend(p_entity_id_tbl.COUNT);
1444 
1445     FOR i IN 1..l_order_tbl.COUNT LOOP
1446         l_order_tbl(i) := i;
1447     END LOOP;
1448 
1449     IF (g_fnd_debug = 'Y') THEN
1450         PO_DEBUG.debug_stmt
1451         ( p_log_head => l_log_head,
1452           p_token    => l_progress,
1453           p_message  => 'l_order_tbl.count= ' || l_order_tbl.COUNT
1454         );
1455     END IF;
1456 
1457     l_progress := '030';
1458 
1459     SELECT PO_SESSION_GT_S.nextval
1460     INTO   l_seq_id
1461     FROM   DUAL;
1462 
1463     IF (g_fnd_debug = 'Y') THEN
1464         PO_DEBUG.debug_stmt
1465         ( p_log_head => l_log_head,
1466           p_token    => l_progress,
1467           p_message  => 'seq_id = ' || l_seq_id
1468         );
1469     END IF;
1470 
1471     FORALL i IN 1..p_entity_id_tbl.COUNT
1472        INSERT INTO po_session_gt
1473        ( key,
1474          num1,
1475          num2 )
1476        VALUES
1477        ( l_seq_id,
1478          p_entity_id_tbl(i),
1479          l_order_tbl(i) );
1480 
1481     l_progress := '040';
1482 
1483     IF (p_entity = 'PO_LINE_LOCATIONS') THEN
1484         l_progress := '050';
1485 
1486         --SQL WHAT: Determine whether a SO can be purged or not by
1487         --          Checking the following things on the associated PO:
1488         --          Does PO still exist? - If No, then allow purge
1489         --          IS PO finally closed? - If Yes, then allow purge
1490         --          Is PO Cancelled? - If Yes, then allow purge
1491         --          Otherwise, disallow purge
1492         --SQL WHY:  SO should not be purged if the associated PO is not
1493         --          in an unmodifiable stage
1494 
1495         SELECT DECODE (PH.po_header_id,
1496                        NULL, 'Y',                      -- po is deleted
1497                        DECODE (PH.closed_code,
1498                                'FINALLY CLOSED', 'Y',  -- po is finally closed
1499                                DECODE (PH.cancel_flag,
1500                                        'Y', 'Y',       -- po is cancelled
1501                                        'N')))
1502         BULK COLLECT INTO x_purge_allowed_tbl
1503         FROM   po_session_gt PSG,
1504                po_headers_all PH,
1505                po_line_locations_all PLL
1506         WHERE  PSG.key = l_seq_id
1507         AND    PSG.num1 = PLL.line_location_id (+)
1508         AND    PLL.po_header_id = PH.po_header_id (+)
1509         ORDER BY PSG.num2 asc;
1510 
1511         IF (g_fnd_debug = 'Y') THEN
1512             PO_DEBUG.debug_stmt
1513             ( p_log_head => l_log_head,
1514               p_token    => l_progress,
1515               p_message  => 'x_purge_allowed.COUNT = ' ||
1516                             x_purge_allowed_tbl.COUNT
1517             );
1518         END IF;
1519 
1520     ELSE
1521         l_progress := '060';
1522 
1523         IF (g_fnd_debug = 'Y') THEN
1524             PO_DEBUG.debug_stmt
1525             ( p_log_head => l_log_head,
1526               p_token    => l_progress,
1527               p_message  => 'Unknown entity: ' || p_entity
1528             );
1529         END IF;
1530 
1531         FND_MSG_PUB.add_exc_msg
1532         ( p_pkg_name        => g_pkg_name,
1533           p_procedure_name  => l_api_name || '.' || l_progress,
1534           p_error_text      => 'Unknown entity: ' || p_entity
1535         );
1536 
1537         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1538 
1539     END IF;
1540 
1541     l_progress := '070';
1542     DELETE FROM po_session_gt WHERE key = l_seq_id;
1543 
1544     IF (FND_API.to_boolean(p_commit)) THEN
1545 
1546         l_progress := '080';
1547         COMMIT;
1548 
1549     END IF;
1550 
1551     IF (g_fnd_debug = 'Y') THEN
1552         PO_DEBUG.debug_end
1553         ( p_log_head => l_log_head
1554         );
1555     END IF;
1556 
1557 
1558 EXCEPTION
1559 WHEN OTHERS THEN
1560     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1561     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
1562                                   p_proc_name => l_api_name,
1563                                   p_progress => l_progress );
1564     FND_MSG_PUB.count_and_get
1565     ( p_encoded => 'F',
1566       p_count   => x_msg_count,
1567       p_data    => x_msg_data
1568     );
1569 
1570 END Validate_Purge;
1571 
1572 -- <DOC PURGE FPJ END>
1573 
1574 -------------------------------------------------------------------------------
1575 --Start of Comments
1576 --Name: get_drop_ship_details
1577 --Pre-reqs:
1578 --  none
1579 --Modifies:
1580 --  None.
1581 --Locks:
1582 --  None.
1583 --Procedure:
1584 --  Returns drop ship info for a given shipment
1585 --Parameters:
1586 --IN:
1587 --p_api_version
1588 --  Initial API version : Expected value is 1.0
1589 --p_line_location_id
1590 -- shipment identifier
1591 --OUT:
1592 --x_order_line_info_rec
1593 --  Record containing the order line info
1594 --x_msg_data
1595 -- Message returned by the API
1596 --x_msg_count
1597 -- Number of error messages
1598 --x_ret_status
1599 --  (a) FND_API.G_RET_STS_SUCCESS - 'S' if successful
1600 --  (b) FND_API.G_RET_STS_ERROR - 'E' if known error occurs
1601 --  (c) FND_API.G_RET_STS_UNEXP_ERROR - 'U' if unexpected error occurs
1602 --Testing:
1603 --  None.
1604 --End of Comments
1605 -------------------------------------------------------------------------------
1606 PROCEDURE get_drop_ship_details(p_api_version   IN NUMBER,
1607                          p_line_location_id     IN NUMBER,
1608                          x_customer_name        OUT NOCOPY VARCHAR2,
1609                          x_customer_contact OUT NOCOPY VARCHAR2,
1610                          x_shipping_method OUT NOCOPY VARCHAR2,
1611                          x_shipping_instructions OUT NOCOPY VARCHAR2,
1612                          x_packing_instructions OUT NOCOPY VARCHAR2,
1613                          x_so_num OUT NOCOPY VARCHAR2,
1614                          x_so_line_num OUT NOCOPY VARCHAR2,
1615                          x_so_status OUT NOCOPY VARCHAR2,
1616                          x_ordered_qty OUT NOCOPY NUMBER,
1617                          x_shipped_qty OUT NOCOPY NUMBER,
1618                          x_customer_po_number OUT NOCOPY VARCHAR2,
1619                          x_customer_po_line_num OUT NOCOPY VARCHAR2,
1620                          x_customer_po_shipment_num OUT NOCOPY VARCHAR2,
1621                          x_customer_item_desc   OUT NOCOPY VARCHAR2,
1622                          x_msg_data             OUT NOCOPY VARCHAR2,
1623                          x_msg_count            OUT NOCOPY NUMBER,
1624                          x_return_status        OUT NOCOPY VARCHAR2 ) IS
1625 
1626 l_api_name              CONSTANT VARCHAR2(30) := 'get_drop_ship_details';
1627 l_api_version           CONSTANT NUMBER := 1.0;
1628 l_order_line_info_rec   OE_DROP_SHIP_GRP.Order_Line_Info_Rec_Type;
1629 
1630 BEGIN
1631  -- Initialise the return status
1632  x_return_status := FND_API.G_RET_STS_SUCCESS;
1633 
1634  -- check for API version
1635  IF ( NOT FND_API.compatible_api_call(l_api_version,p_api_version,l_api_name,G_PKG_NAME) )
1636  THEN
1637    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1638    return;
1639  END IF;
1640 
1641  -- Call the OM API to get the drop ship info
1642  OE_DROP_SHIP_GRP.get_order_line_info(
1643                            P_API_VERSION    => 1.0,
1644                            P_PO_HEADER_ID   => null,
1645                            P_PO_LINE_ID     => null,
1646                            P_PO_LINE_LOCATION_ID  => p_line_location_id,
1647                            P_PO_RELEASE_ID  => null,
1648                            P_MODE           => 2 ,
1649                            X_ORDER_LINE_INFO_REC  => l_order_line_info_rec,
1650                            X_MSG_DATA       => x_msg_data,
1651                            X_MSG_COUNT      => x_msg_count,
1652                            X_RETURN_STATUS  => x_return_status );
1653 
1654  IF  X_RETURN_STATUS = FND_API.G_RET_STS_SUCCESS THEN
1655    x_customer_name         := l_order_line_info_rec.SHIP_TO_CUSTOMER_NAME;
1656    x_customer_contact      := l_order_line_info_rec.SHIP_TO_CONTACT_NAME;
1657    x_shipping_method       := l_order_line_info_rec.SHIPPING_METHOD;
1658    x_shipping_instructions := l_order_line_info_rec.SHIPPING_INSTRUCTIONS;
1659    x_packing_instructions  := l_order_line_info_rec.PACKING_INSTRUCTIONS;
1660    x_so_num                := l_order_line_info_rec.SALES_ORDER_NUMBER;
1661    x_so_line_num           := l_order_line_info_rec.SALES_ORDER_LINE_NUMBER;
1662    x_so_status             := l_order_line_info_rec.SALES_ORDER_LINE_STATUS;
1663    x_ordered_qty           := l_order_line_info_rec.SALES_ORDER_LINE_ORDERED_QTY;
1664    x_shipped_qty           := l_order_line_info_rec.SALES_ORDER_LINE_SHIPPED_QTY;
1665    x_customer_item_desc    := l_order_line_info_rec.CUSTOMER_PRODUCT_DESCRIPTION;
1666    x_customer_po_number    := l_order_line_info_rec.CUSTOMER_PO_NUMBER;
1667    x_customer_po_line_num  := l_order_line_info_rec.CUSTOMER_PO_LINE_NUMBER;
1668    x_customer_po_shipment_num := l_order_line_info_rec.CUSTOMER_PO_SHIPMENT_NUMBER;
1669  END IF;
1670 
1671 EXCEPTION
1672 When Others then
1673      x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1674 END;
1675 
1676 END PO_OM_INTEGRATION_GRP;