DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_DOCUMENT_UPDATE_GRP

Source


1 PACKAGE BODY PO_DOCUMENT_UPDATE_GRP AS
2 /* $Header: POXGCPOB.pls 120.5 2005/10/26 12:21:45 joswong noship $*/
3 
4 -- Read the profile option that enables/disables the debug log
5 g_fnd_debug VARCHAR2(1) := NVL(FND_PROFILE.VALUE('AFLOG_ENABLED'),'N');
6 
7 g_pkg_name CONSTANT VARCHAR2(30) := 'PO_DOCUMENT_UPDATE_GRP';
8 g_module_prefix  CONSTANT VARCHAR2(40) := 'po.plsql.' || g_pkg_name || '.';
9 
10 -- <PO_CHANGE_API FPJ START>
11 -- In file version 115.3, added an overloaded update_document procedure that
12 -- takes in changes as a PO_CHANGES_REC_TYPE object. This allows the caller to
13 -- request changes to multiple lines, shipments, and distributions at once.
14 
15 -------------------------------------------------------------------------------
16 --Start of Comments
17 --Name: update_document
18 --Function:
19 --  Validates and applies the requested changes and any derived
20 --  changes to the Purchase Order, Purchase Agreement, or Release.
21 --Notes:
22 --  For details, see the comments in the package body for
23 --  PO_DOCUMENT_UPDATE_PVT.update_document.
24 --End of Comments
25 -------------------------------------------------------------------------------
26 PROCEDURE update_document (
27   p_api_version            IN NUMBER,
28   p_init_msg_list          IN VARCHAR2,
29   x_return_status          OUT NOCOPY VARCHAR2,
30   p_changes                IN OUT NOCOPY PO_CHANGES_REC_TYPE,
31   p_run_submission_checks  IN VARCHAR2,
32   p_launch_approvals_flag  IN VARCHAR2,
33   p_buyer_id               IN NUMBER,
34   p_update_source          IN VARCHAR2,
35   p_override_date          IN DATE,
36   x_api_errors             OUT NOCOPY PO_API_ERRORS_REC_TYPE,
37   p_approval_background_flag IN VARCHAR2,
38   p_mass_update_releases   IN VARCHAR2 -- Bug 3373453
39 ) IS
40   l_api_name     CONSTANT VARCHAR(30) := 'UPDATE_DOCUMENT';
41   l_api_version  CONSTANT NUMBER := 1.0;
42 BEGIN
43   -- Standard API initialization:
44   IF NOT FND_API.Compatible_API_Call ( l_api_version, p_api_version,
45                                        l_api_name, g_pkg_name ) THEN
46     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
47   END IF;
48 
49   IF (FND_API.to_boolean(p_init_msg_list)) THEN
50     FND_MSG_PUB.initialize;
51   END IF;
52 
53   PO_DOCUMENT_UPDATE_PVT.update_document(
54     p_api_version => 1.0,
55     p_init_msg_list => p_init_msg_list,
56     x_return_status => x_return_status,
57     p_changes => p_changes,
58     p_run_submission_checks => p_run_submission_checks,
59     p_launch_approvals_flag => p_launch_approvals_flag,
60     p_buyer_id => p_buyer_id,
61     p_update_source => p_update_source,
62     p_override_date => p_override_date,
63     x_api_errors => x_api_errors,
64     p_approval_background_flag => p_approval_background_flag,
65     p_mass_update_releases => p_mass_update_releases
66   );
67 
68 EXCEPTION
69   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
70     -- Add the errors on the API message list to x_api_errors.
71     PO_DOCUMENT_UPDATE_PVT.add_message_list_errors (
72       p_api_errors => x_api_errors,
73       x_return_status => x_return_status
74     );
75     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
76   WHEN OTHERS THEN
77     -- Add the unexpected error to the API message list.
78     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
79                                   p_proc_name => l_api_name );
80     -- Add the errors on the API message list to x_api_errors.
81     PO_DOCUMENT_UPDATE_PVT.add_message_list_errors (
82       p_api_errors => x_api_errors,
83       x_return_status => x_return_status
84     );
85     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
86 END update_document;
87 -- <PO_CHANGE_API FPJ END>
88 
89 -- START Forward declarations for package private procedures:
90 FUNCTION check_mandatory_params (
91   p_api_errors                  IN OUT NOCOPY PO_API_ERRORS_REC_TYPE,
92   p_po_number                   VARCHAR2,
93   p_revision_number             NUMBER,
94   p_line_number                 NUMBER,
95   p_new_quantity                NUMBER,
96   p_new_price                   NUMBER,
97   p_new_promised_date           DATE,
98   p_new_need_by_date            DATE,
99   p_launch_approvals_flag       VARCHAR2,
100   p_secondary_qty               NUMBER,
101   p_preferred_grade             VARCHAR2
102 ) RETURN NUMBER;
103 -- END Forward declarations for package private procedures
104 
105 
106 
107 -- <PO_CHANGE_API FPJ>
108 -- In file version 115.3, removed the P_INTERFACE_TYPE and P_TRANSACTION_ID
109 -- parameters from UPDATE_DOCUMENT and added an X_API_ERRORS parameter, because
110 -- the PO Change API will no longer write error messages to the
111 -- PO_INTERFACE_ERRORS table. Instead, it will return all of the errors
112 -- in the x_api_errors object.
113 
114 -------------------------------------------------------------------------------
115 --Start of Comments
116 --Name: update_document
117 --Function:
118 --  Validates and applies the requested changes and any derived
119 --  changes to the Purchase Order or Release.
120 --Pre-reqs:
121 --  The Applications context must be set before calling this API - i.e.:
122 --    FND_GLOBAL.apps_initialize ( user_id => <user ID>,
123 --                                 resp_id => <responsibility ID>,
124 --                                 resp_appl_id => 201 );
125 --Notes:
126 --  This procedure is for backward compatibility only. New callers should use
127 --  the overloaded UPDATE_DOCUMENT procedure above, which takes in changes
128 --  as a PO_CHANGES_REC_TYPE object.
129 --End of Comments
130 -------------------------------------------------------------------------------
131 PROCEDURE update_document (
132   p_PO_NUMBER                   IN      VARCHAR2,
133   p_RELEASE_NUMBER              IN      NUMBER,
134   p_REVISION_NUMBER             IN      NUMBER,
135   p_LINE_NUMBER                 IN      NUMBER,
136   p_SHIPMENT_NUMBER             IN      NUMBER,
137   p_NEW_QUANTITY                IN      NUMBER,
138   p_NEW_PRICE                   IN      NUMBER,
139   p_NEW_PROMISED_DATE           IN      DATE,
140   p_NEW_NEED_BY_DATE            IN      DATE,
141   p_LAUNCH_APPROVALS_FLAG       IN      VARCHAR2,
142   p_UPDATE_SOURCE               IN      VARCHAR2,
143   p_OVERRIDE_DATE               IN      DATE,
144   p_VERSION                     IN      NUMBER,
145   x_result                      IN OUT NOCOPY   NUMBER,
146   x_api_errors                  OUT NOCOPY PO_API_ERRORS_REC_TYPE,
147   p_BUYER_NAME                  IN VARCHAR2  default NULL, /* Bug:2986718 */
148  -- <INVCONV R12 START>
149   p_secondary_qty               IN NUMBER ,
150   p_preferred_grade             IN VARCHAR2
151   -- <INVCONV R12 END>
152 ) IS
153 
154   l_api_version CONSTANT NUMBER := 2.0;
155   l_api_name    CONSTANT VARCHAR2(50) := 'UPDATE_DOCUMENT';
156 
157   -- <PO_CHANGE_API FPJ START>
158   CURSOR l_po_header_csr (p_po_number VARCHAR2) IS
159     select  po_header_id, revision_num,
160             NVL(authorization_status, 'INCOMPLETE'), type_lookup_code
161     from    po_headers
162     where   segment1 = p_PO_NUMBER
163     and     type_lookup_code IN ('STANDARD', 'BLANKET', 'PLANNED');
164 
165   CURSOR l_po_release_csr (p_po_header_id NUMBER, p_release_number NUMBER) IS
166     select  po_release_id, revision_num,
167             NVL(authorization_status, 'INCOMPLETE'), release_type
168     from    po_releases
169     where   po_header_id = p_po_header_id
170     and     release_num = p_RELEASE_NUMBER;
171 
172   CURSOR l_po_line_csr (p_po_header_id NUMBER, p_line_number NUMBER) IS
173     select  po_line_id
174     from    po_lines
175     where   po_header_id = p_po_header_id
176     and     line_num = p_LINE_NUMBER;
177 
178   CURSOR l_po_shipment_csr (p_po_line_id NUMBER, p_shipment_number NUMBER) IS
179     select  line_location_id
180     from    po_line_locations
181     where   po_line_id = p_po_line_id
182     and     shipment_num = p_SHIPMENT_NUMBER;
183 
184   CURSOR l_release_shipment_csr (p_po_release_id NUMBER, p_po_line_id NUMBER,
185                                  p_shipment_number NUMBER) IS
186     select  line_location_id
187     from    po_line_locations
188     where   po_line_id = p_po_line_id
189     and     po_release_id = p_po_release_id
190     and     shipment_num = p_SHIPMENT_NUMBER;
191 
192   l_header_table_name    VARCHAR2(30);
193   l_changes              PO_CHANGES_REC_TYPE;
194   l_new_shipment_price   PO_LINE_LOCATIONS.price_override%TYPE;
195   l_po_header_id         PO_HEADERS.po_header_id%TYPE;
196   l_po_release_id        PO_RELEASES.po_release_id%TYPE;
197   l_po_line_id           PO_LINES.po_line_id%TYPE;
198   l_line_location_id     PO_LINE_LOCATIONS.line_location_id%TYPE;
199   l_revision_num         PO_HEADERS.revision_num%TYPE;
200   l_authorization_status PO_HEADERS.authorization_status%TYPE;
201   l_document_subtype     PO_HEADERS.type_lookup_code%TYPE;
202   l_launch_approvals_flag VARCHAR2(1);
203   l_shipment_count       NUMBER;
204   l_buyer_id             PO_HEADERS.agent_id%TYPE;
205 
206   l_return_status        VARCHAR2(1);
207   l_secondary_quantity   PO_LINES.SECONDARY_QUANTITY%TYPE := p_secondary_qty;  -- <INVCONV R12>
208   l_preferred_grade      MTL_GRADES.grade_Code%TYPE := p_preferred_grade;      -- <INVCONV R12>
209 
210   l_progress             VARCHAR2(3) := '000';
211   -- <PO_CHANGE_API FPJ END>
212   l_message_name        fnd_new_messages.message_name%TYPE;   -- <INVCONV R12>
213 
214 BEGIN
215 
216   IF (g_fnd_debug = 'Y') THEN
217     IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) THEN
218       FND_LOG.string( FND_LOG.LEVEL_PROCEDURE, g_module_prefix || l_api_name,
219                     'Entering ' || l_api_name );
220     END IF;
221   END IF;
222 
223   x_result := 1;
224 
225   IF NOT FND_API.Compatible_API_Call ( l_api_version, p_VERSION,
226                                        l_api_name, g_pkg_name ) THEN
227     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
228   END IF;
229 
230   FND_MSG_PUB.initialize;
231 
232   -- <PO_CHANGE_API FPJ START>
233   -- Moved the following logic from the private API (PO_DOCUMENT_UPDATE_PVT)
234   -- to the group API, because the private API now takes changes as a
235   -- PO_CHANGES_REC_TYPE object instead of individual procedure arguments.
236 
237   l_progress := '010';
238 
239   -- Verify that the caller passed in values for all the required parameters.
240   IF (check_mandatory_params (
241         x_api_errors, p_po_number, p_revision_number, p_line_number,
242         p_new_quantity, p_new_price, p_new_promised_date, p_new_need_by_date,
243         p_launch_approvals_flag,
244         p_secondary_qty,p_preferred_grade ) = 0)      -- <INVCONV R12>
245   THEN
246     x_result := 0;
247     RETURN;
248   END IF;
249 
250   l_progress := '020';
251 
252   -- Obtain the PO_HEADER_ID.
253   OPEN l_po_header_csr (p_po_number);
254   FETCH l_po_header_csr
255   INTO l_po_header_id, l_revision_num,
256        l_authorization_status, l_document_subtype;
257 
258   IF (l_po_header_csr%NOTFOUND) THEN
259     PO_DOCUMENT_UPDATE_PVT.add_error (
260       p_api_errors => x_api_errors,
261       x_return_status => l_return_status,
262       p_message_name => 'PO_INVALID_DOC_IDS',
263       p_table_name => 'PO_HEADERS',
264       p_column_name => 'PO_HEADER_ID'
265     );
266     x_result := 0;
267     CLOSE l_po_header_csr;
268     RETURN;
269   END IF; -- l_po_header_csr%NOTFOUND
270   CLOSE l_po_header_csr;
271 
272   l_progress := '030';
273 
274   -- Obtain the PO_RELEASE_ID if needed.
275   IF (p_release_number is not null) THEN
276     OPEN l_po_release_csr (l_po_header_id, p_release_number);
277     FETCH l_po_release_csr
278     INTO l_po_release_id, l_revision_num,
279          l_authorization_status, l_document_subtype;
280 
281     if (l_po_release_csr%NOTFOUND) then
282       PO_DOCUMENT_UPDATE_PVT.add_error (
283         p_api_errors => x_api_errors,
284         x_return_status => l_return_status,
285         p_message_name => 'PO_CHNG_INVALID_RELEASE_NUM',
286         p_table_name => 'PO_RELEASES',
287         p_column_name => 'PO_RELEASE_ID'
288       );
289       x_result := 0;
290       CLOSE l_po_release_csr;
291       RETURN;
292     END IF; -- l_po_release_csr%NOTFOUND
293     CLOSE l_po_release_csr;
294   END IF;
295 
296   l_progress := '040';
297 
298      --<INVCONV R12 START>
299      IF (l_preferred_grade IS NOT NULL OR
300          l_secondary_quantity IS NOT NULL) THEN
301         l_message_name := 'PO_CHNG_SECGRD_NOTSUPPORTED_PB';
302      ELSE
303         l_message_name := 'PO_CHNG_WRONG_DOC_TYPE';
304      END IF;
305      --<INVCONV R12 END>
306 
307   -- Check if the document is one of the supported types.
308   IF (l_po_release_id IS NULL) THEN -- PO/PA
309     l_header_table_name := 'PO_HEADERS';
310     IF l_document_subtype NOT IN ('STANDARD', 'PLANNED') THEN
311       PO_DOCUMENT_UPDATE_PVT.add_error (
312         p_api_errors => x_api_errors,
313         x_return_status => l_return_status,
314         p_message_name => l_message_name,    -- <INVCONV R12>
315         p_table_name => l_header_table_name,
316         p_column_name => 'TYPE_LOOKUP_CODE'
317       );
318       x_result := 0;
319       RETURN;
320     END IF; -- l_document_subtype
321   ELSE -- Release
322     l_header_table_name := 'PO_RELEASES';
323     IF l_document_subtype NOT IN ('SCHEDULED', 'BLANKET') THEN
324       PO_DOCUMENT_UPDATE_PVT.add_error (
325         p_api_errors => x_api_errors,
326         x_return_status => l_return_status,
327         p_message_name =>  l_message_name,   -- <INVCONV R12>
328         p_table_name => l_header_table_name,
329         p_column_name => 'RELEASE_TYPE'
330       );
331       x_result := 0;
332       RETURN;
333     END IF; -- l_document_subtype
334   END IF; -- l_po_release_id
335 
336   l_progress := '050';
337 
338   -- Check if the document is in a supported status.
339   -- Bug#4156064: allow changing of PO with incomplete status also
340   IF l_authorization_status NOT IN ('APPROVED', 'REQUIRES REAPPROVAL', 'INCOMPLETE') THEN
341     PO_DOCUMENT_UPDATE_PVT.add_error (
342       p_api_errors => x_api_errors,
343       x_return_status => l_return_status,
344       p_message_name => 'PO_ALL_DOC_CANNOT_BE_OPENED',
345       p_table_name => l_header_table_name,
346       p_column_name => 'AUTHORIZATION_STATUS'
347     );
348     x_result := 0;
349     RETURN;
350   END IF; -- l_authorization_status
351 
352   l_progress := '060';
353 
354   -- Verify that the passed in revision equals the current revision.
355   IF (l_revision_num <> p_revision_number) THEN
356     PO_DOCUMENT_UPDATE_PVT.add_error (
357       p_api_errors => x_api_errors,
358       x_return_status => l_return_status,
359       p_message_name => 'PO_CHNG_REVISION_NOT_MATCH',
360       p_table_name => l_header_table_name,
361       p_column_name => 'REVISION_NUM'
362     );
363     x_result := 0;
364     RETURN;
365   END IF; -- l_revision_num
366 
367   -- Create an empty change object for this document.
371   );
368   l_changes := PO_CHANGES_REC_TYPE.create_object (
369     p_po_header_id => l_po_header_id,
370     p_po_release_id => l_po_release_id
372 
373   l_progress := '070';
374 
375   -- Obtain the PO_LINE_ID.
376   OPEN l_po_line_csr (l_po_header_id, p_line_number);
377   FETCH l_po_line_csr INTO l_po_line_id;
378 
379   IF (l_po_line_csr%NOTFOUND) THEN
380     PO_DOCUMENT_UPDATE_PVT.add_error (
381       p_api_errors => x_api_errors,
382       x_return_status => l_return_status,
383       p_message_name => 'PO_CHNG_INVALID_LINE_NUM',
384       p_table_name => 'PO_LINES',
385       p_column_name => 'PO_LINE_ID'
386     );
387     x_result := 0;
388     CLOSE l_po_line_csr;
389     RETURN;
390   END IF;
391   CLOSE l_po_line_csr;
392 
393   -- Add the line or shipment changes to the change object.
394   IF (p_shipment_number IS NULL) THEN -- Line-level change
395 
396     l_progress := '080';
397 
398     IF (p_new_promised_date IS NOT NULL) THEN
399       -- Lines do not have promised date.
400       PO_DOCUMENT_UPDATE_PVT.add_error (
401         p_api_errors => x_api_errors,
402         x_return_status => l_return_status,
403         p_message_name => 'PO_CHNG_NO_DATE_CHANGE_LINE',
404         p_table_name => 'PO_LINES',
405         p_column_name => 'PROMISED_DATE'
406       );
407       x_result := 0;
408       RETURN;
409     END IF; -- p_new_promised_date
410 
411     IF (p_new_need_by_date IS NOT NULL) THEN
412       -- Lines do not have need by date.
413       PO_DOCUMENT_UPDATE_PVT.add_error (
414         p_api_errors => x_api_errors,
415         x_return_status => l_return_status,
416         p_message_name => 'PO_CHNG_NO_NEED_DATE_ON_LINE',
417         p_table_name => 'PO_LINES',
418         p_column_name => 'NEED_BY_DATE'
419       );
420       x_result := 0;
421       RETURN;
422     END IF; -- p_new_need_by_date
423 
424 
425     -- Add a line change.
426     l_changes.line_changes.add_change (
427       p_po_line_id => l_po_line_id,
428       p_quantity => p_new_quantity,
429       p_unit_price => p_new_price,
430       p_secondary_quantity => l_secondary_quantity,   -- <INVCONV R12>
431       p_preferred_grade  => l_preferred_grade         -- <INVCONV R12>
432     );
433 
434   ELSE -- Shipment-level change
435 
436     l_progress := '090';
437 
438     -- Obtain the LINE_LOCATION_ID.
439     IF (p_release_number IS NULL) THEN -- PO or PA
440       OPEN l_po_shipment_csr (l_po_line_id, p_shipment_number);
441       FETCH l_po_shipment_csr INTO l_line_location_id;
442 
443       IF (l_po_shipment_csr%NOTFOUND) THEN
444         PO_DOCUMENT_UPDATE_PVT.add_error (
445           p_api_errors => x_api_errors,
446           x_return_status => l_return_status,
447           p_message_name => 'PO_CHNG_INVALID_SHIPMENT_NUM',
448           p_table_name => 'PO_LINE_LOCATIONS',
449           p_column_name => 'LINE_LOCATION_ID'
450         );
451         x_result := 0;
452         CLOSE l_po_shipment_csr;
453         RETURN;
454       END IF; -- l_po_shipment_csr%NOTFOUND
455       CLOSE l_po_shipment_csr;
456 
457     ELSE -- Releases
458       OPEN l_release_shipment_csr (l_po_release_id, l_po_line_id,
459                                    p_shipment_number);
460       FETCH l_release_shipment_csr INTO l_line_location_id;
461 
462       IF (l_release_shipment_csr%NOTFOUND) THEN
463         PO_DOCUMENT_UPDATE_PVT.add_error (
464           p_api_errors => x_api_errors,
465           x_return_status => l_return_status,
466           p_message_name => 'PO_CHNG_INVALID_SHIPMENT_NUM',
467           p_table_name => 'PO_LINE_LOCATIONS',
468           p_column_name => 'LINE_LOCATION_ID'
469         );
470         x_result := 0;
471         CLOSE l_release_shipment_csr;
472         RETURN;
473       END IF; -- l_release_shipment_csr%NOTFOUND
474       CLOSE l_release_shipment_csr;
475 
476     END IF; -- p_release_number
477 
478     l_progress := '100';
479 
480     -- Shipments of standard/planned POs do not have prices.
481     -- However, for backward compatibility, if the caller requests
482     -- a shipment price change, we will automatically convert it
483     -- to a line price change if the line has only one shipment.
484     IF (p_release_number IS NULL)
485        AND (l_document_subtype IN ('STANDARD', 'PLANNED'))
486        AND (p_new_price IS NOT NULL) THEN
487 
488       -- SQL What: Returns the number of shipments on this line.
489       SELECT count(*)
490       INTO l_shipment_count
491       FROM po_line_locations
492       WHERE po_line_id = l_po_line_id
493       AND shipment_type = l_document_subtype;
494 
498         PO_DOCUMENT_UPDATE_PVT.add_error (
495       IF (l_shipment_count > 1) THEN
496         -- Do not allow shipment price changes if the line has
497         -- multiple shipments.
499           p_api_errors => x_api_errors,
500           x_return_status => l_return_status,
501           p_message_name => 'PO_CHNG_PO_NO_SHIP_PRICE',
502           p_table_name => 'PO_LINE_LOCATIONS',
503           p_column_name => 'PRICE_OVERRIDE'
504         );
505         x_result := 0;
506         RETURN;
507       END IF;
508 
509       -- Convert this shipment price change to a line price change.
510       l_changes.line_changes.add_change (
511         p_po_line_id => l_po_line_id,
512         p_unit_price => p_new_price
513       );
514       l_new_shipment_price := NULL; -- Do not add a shipment price change.
515     ELSE -- not a standard or planned PO
516       l_new_shipment_price := p_new_price;
517     END IF; -- standard or planned PO with new price
518 
519     l_progress := '110';
520 
521     -- Add a shipment change.
522 
523     l_changes.shipment_changes.add_change (
524       p_po_line_location_id => l_line_location_id,
525       p_quantity => p_new_quantity,
526       p_price_override => l_new_shipment_price,
527       p_promised_date => p_new_promised_date,
528       p_need_by_date => p_new_need_by_date,
529       p_preferred_grade => l_preferred_grade,       -- <INVCONV R12>
530       p_secondary_quantity => l_secondary_quantity  -- <INVCONV R12>
531     );
532 
533   END IF; -- p_shipment_number
534 
535   l_progress := '120';
536 
537   -- Convert the launch approvals flag from Y/N to FND_API true/false.
538   IF (p_launch_approvals_flag = 'Y') THEN
539     l_launch_approvals_flag := FND_API.G_TRUE;
540   ELSE
541     l_launch_approvals_flag := FND_API.G_FALSE;
542   END IF;
543 
544   l_progress := '130';
545 
546   -- Derive the buyer ID from the buyer name.
547   IF ( p_BUYER_NAME IS NOT NULL) THEN
548     l_buyer_id := PO_AGENTS_SV1.derive_agent_id(p_BUYER_NAME);
549     IF (l_buyer_id IS NULL) then -- could not find a buyer
550       PO_DOCUMENT_UPDATE_PVT.add_error (
551         p_api_errors => x_api_errors,
552         x_return_status => l_return_status,
553         p_message_name => 'PO_PDOI_DERV_ERROR',
554         p_column_name => 'P_BUYER_NAME',
555         p_token_name1 => 'COLUMN_NAME',
556         p_token_value1 => 'P_BUYER_NAME',
557         p_token_name2 => 'VALUE',
558         p_token_value2 => p_buyer_name
559       );
560       x_result := 0;
561       RETURN;
562     END IF;
563   END IF;
564 
565   l_progress := '150';
566 
567   -- Call the private PO Change API to derive, validate, and apply the changes.
568   PO_DOCUMENT_UPDATE_PVT.update_document(
569     p_api_version => 1.0,
570     p_init_msg_list => FND_API.G_TRUE,
571     x_return_status => l_return_status,
572     p_changes => l_changes,
573     p_run_submission_checks => FND_API.G_FALSE,
574     p_launch_approvals_flag => l_launch_approvals_flag,
575     p_buyer_id => l_buyer_id,
576     p_update_source => p_update_source,
577     p_override_date => p_override_date,
578     x_api_errors => x_api_errors
579   );
580 
581   IF (l_return_status = FND_API.G_RET_STS_SUCCESS) THEN
582     x_result := 1;
583   ELSE
584     x_result := 0;
585   END IF;
586 
587   l_progress := '150';
588 
589 EXCEPTION
593       p_api_errors => x_api_errors,
590   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
591     -- Add the errors on the API message list to x_api_errors.
592     PO_DOCUMENT_UPDATE_PVT.add_message_list_errors (
594       x_return_status => l_return_status
595     );
596     x_result := 0;
597   WHEN OTHERS THEN
598     -- Add the unexpected error to the API message list.
599     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
600                                   p_proc_name => l_api_name,
601                                   p_progress => l_progress );
602     -- Add the errors on the API message list to x_api_errors.
603     PO_DOCUMENT_UPDATE_PVT.add_message_list_errors (
604       p_api_errors => x_api_errors,
605       x_return_status => l_return_status
606     );
607     x_result := 0;
608 -- <PO_CHANGE_API FPJ END>
609 END update_document;
610 
611 -- <PO_CHANGE_API FPJ START>
612 -- In file version 115.3, moved this procedure from the private API
613 -- (PO_DOCUMENT_UPDATE_PVT) to the group API, because the private API
614 -- now takes changes as a PO_CHANGES_REC_TYPE object, not as individual
615 -- procedure arguments.
616 
617 -------------------------------------------------------------------------------
618 --Start of Comments
619 --Name: check_mandatory_params
620 --Function:
621 --  Checks that the caller has passed in values for the required parameters.
622 --  Returns 1 if all of the required parameters have non-NULL values,
623 --  0 otherwise.
624 --End of Comments
625 -------------------------------------------------------------------------------
626 FUNCTION check_mandatory_params (
627   p_api_errors                  IN OUT NOCOPY PO_API_ERRORS_REC_TYPE,
628   p_po_number                   VARCHAR2,
629   p_revision_number             NUMBER,
630   p_line_number                 NUMBER,
631   p_new_quantity                NUMBER,
632   p_new_price                   NUMBER,
633   p_new_promised_date           DATE,
634   p_new_need_by_date            DATE,
635   p_launch_approvals_flag       VARCHAR2,
636   p_secondary_qty               NUMBER ,   -- <INVCONV R12>
637   p_preferred_grade             VARCHAR2   -- <INVCONV R12>
638 ) RETURN NUMBER IS
639   l_api_name    CONSTANT VARCHAR2(50) := 'CHECK_MANDATORY_PARAMS';
640   l_return_status VARCHAR2(1);
641 BEGIN
642   IF (g_fnd_debug = 'Y') THEN
643      IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) THEN
644         FND_LOG.string( FND_LOG.LEVEL_PROCEDURE, g_module_prefix || l_api_name,
645                     'Entering ' || l_api_name );
646      END IF;
647   END IF;
648 
649   if (p_PO_NUMBER is null) then
650     PO_DOCUMENT_UPDATE_PVT.add_error (
651       p_api_errors => p_api_errors,
652       x_return_status => l_return_status,
653       p_message_name => 'PO_ALL_CNL_PARAM_NULL',
654       p_column_name => 'P_PO_NUMBER'
655     );
656     return 0;
657   end if;
658 
659   if (p_REVISION_NUMBER is null) then
660     PO_DOCUMENT_UPDATE_PVT.add_error (
661       p_api_errors => p_api_errors,
662       x_return_status => l_return_status,
663       p_message_name => 'PO_ALL_CNL_PARAM_NULL',
664       p_column_name => 'P_REVISION_NUMBER'
665     );
666     return 0;
667   end if;
668 
669   IF (NVL(p_LAUNCH_APPROVALS_FLAG,'N') NOT IN ('Y', 'N')) THEN
670     PO_DOCUMENT_UPDATE_PVT.add_error (
671       p_api_errors => p_api_errors,
672       x_return_status => l_return_status,
673       p_message_name => 'PO_CHNG_INVALID_LAUNCH_FLAG',
674       p_column_name => 'P_LAUNCH_APPROVALS_FLAG');
675     return 0;
676   END IF;
677 
678   IF (p_LINE_NUMBER IS NULL) THEN
679     PO_DOCUMENT_UPDATE_PVT.add_error (
680       p_api_errors => p_api_errors,
681       x_return_status => l_return_status,
682       p_message_name => 'PO_ALL_CNL_PARAM_NULL',
683       p_column_name => 'P_LINE_NUMBER'
684     );
685     return 0;
686   END IF;
687 
688   --<INVCONV R12 START>
689   /*
690   ===============================================================
691    check if secondary and preferred grade are not passed.
692    we want to make sure API runs even if we just pass secondary
693    or preferred grade
694   ===============================================================
695   */
696   g_process_param_chge_only := 'N';
697 
698   IF (p_new_quantity IS NULL AND p_new_price IS NULL
699       AND p_new_promised_date IS NULL AND p_new_need_by_date IS NULL) THEN
700 
701     /* check if process attributes are null */
702 
703     IF (p_secondary_qty IS NULL AND p_preferred_grade IS NULL) THEN
704        PO_DOCUMENT_UPDATE_PVT.add_error (
705         p_api_errors => p_api_errors,
706         x_return_status => l_return_status,
707         p_message_name => 'PO_CHNG_ONE_INPUT_REQUIRED');
708        return 0;
709     ELSE
710        g_process_param_chge_only := 'Y';  -- <INVCONV R12>
711     END IF;
712   END IF;
713 
714   --<INVCONV R12 END>
715 
716   return 1;
717 
718 EXCEPTION
719   WHEN OTHERS THEN
720     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
721                                   p_proc_name => l_api_name );
722     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
723 END check_mandatory_params;
724 -- <PO_CHANGE_API FPJ END>
725 
726 -- Bug 3605355 START
727 -------------------------------------------------------------------------------
728 --Start of Comments
729 --Name: launch_po_approval_wf
730 --Function:
731 --  Launches the Document Approval workflow for the given document.
732 --Note:
733 -- For details, see the package body comments for
734 -- PO_DOCUMENT_UPDATE_PVT.launch_po_approval_wf.
735 --End of Comments
736 -------------------------------------------------------------------------------
737 PROCEDURE launch_po_approval_wf (
738   p_api_version           IN NUMBER,
739   p_init_msg_list         IN VARCHAR2,
740   x_return_status         OUT NOCOPY VARCHAR2,
741   p_document_id           IN NUMBER,
742   p_document_type         IN PO_DOCUMENT_TYPES_ALL_B.document_type_code%TYPE,
743   p_document_subtype      IN PO_DOCUMENT_TYPES_ALL_B.document_subtype%TYPE,
744   p_preparer_id           IN NUMBER,
745   p_approval_background_flag IN VARCHAR2,
746   p_mass_update_releases  IN VARCHAR2
747 ) IS
748   l_proc_name CONSTANT VARCHAR2(30) := 'LAUNCH_PO_APPROVAL_WF';
749   l_api_version CONSTANT NUMBER := 1.0;
750   l_progress VARCHAR2(3) := '000';
751 BEGIN
752   x_return_status := FND_API.G_RET_STS_SUCCESS;
753 
754   -- Standard API initialization:
755   IF NOT FND_API.compatible_api_call (
756            p_current_version_number => l_api_version,
757            p_caller_version_number => p_api_version,
758            p_api_name => l_proc_name,
759            p_pkg_name => g_pkg_name ) THEN
760     RAISE FND_API.g_exc_unexpected_error;
761   END IF;
762 
763   IF (FND_API.to_boolean(p_init_msg_list)) THEN
764     FND_MSG_PUB.initialize();
765   END IF;
766 
767   l_progress := '010';
768 
769   PO_DOCUMENT_UPDATE_PVT.launch_po_approval_wf (
770     p_api_version => 1.0,
771     p_init_msg_list => FND_API.G_FALSE,
772     x_return_status => x_return_status,
773     p_document_id => p_document_id,
774     p_document_type => p_document_type,
775     p_document_subtype => p_document_subtype,
776     p_preparer_id => p_preparer_id,
777     p_approval_background_flag => p_approval_background_flag,
778     p_mass_update_releases => p_mass_update_releases,
779     p_retroactive_price_change => NULL
780   );
781 EXCEPTION
782   WHEN FND_API.g_exc_unexpected_error THEN
783     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
784                                   p_proc_name => l_proc_name,
785                                   p_progress => l_progress );
786     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
787   WHEN OTHERS THEN
788     PO_DEBUG.handle_unexp_error ( p_pkg_name => g_pkg_name,
789                                   p_proc_name => l_proc_name,
790                                   p_progress => l_progress );
791     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
792 END launch_po_approval_wf;
793 -- Bug 3605355 END
794 
795 END PO_DOCUMENT_UPDATE_GRP;