1 PACKAGE BODY ITG_SyncPoInbound_PVT AS
2 /* ARCS: $Header: itgvspib.pls 120.7 2006/08/29 16:35:19 pvaddana noship $
3 * CVS: itgvspib.pls,v 1.20 2002/12/23 21:20:30 ecoe Exp
4 */
5
6 G_PKG_NAME CONSTANT VARCHAR2(30) := 'ITG_SyncPoInbound_PVT';
7 g_action VARCHAR2(400);
8
9 /* This is a single-line cache of the PO header id. */
10 g_po_id NUMBER;
11 g_po_code VARCHAR2(20);
12 g_org_id NUMBER;
13
14 /* Private function to make sure that the g_po_id value is correct. */
15 PROCEDURE lookup_po_header(
16 p_po_code VARCHAR2, /* width 20 */
17 p_org_id NUMBER,
18 p_release_id VARCHAR2,
19 p_doc_type IN OUT NOCOPY VARCHAR2) IS
20 l_var VARCHAR2(50);
21 BEGIN
22 IF g_po_id IS NULL OR
23 p_po_code <> g_po_code OR
24 p_org_id <> g_org_id THEN
25
26 /* Clear first. */
27 g_po_code := NULL;
28 g_po_id := NULL;
29 g_org_id := NULL;
30
31 /* Lookup po_id from p_po_code (segment1). */
32 /* Exceptions here get thrown to caller. */
33 SELECT po_header_id, type_lookup_code
34 INTO g_po_id, p_doc_type /* The value we were looking for. */
35 FROM po_headers_all
36 WHERE segment1 = p_po_code
37 AND org_id = p_org_id;
38
39 /* Save the keys for repeated lookups. */
40 g_po_code := p_po_code;
41 g_org_id := p_org_id;
42 END IF;
43 EXCEPTION
44 WHEN NO_DATA_FOUND THEN
45 ITG_MSG.no_po_found(p_po_code, p_org_id);
46 RAISE FND_API.G_EXC_ERROR;
47 END lookup_po_header;
48
49 PROCEDURE Update_PoLine(
50 x_return_status OUT NOCOPY VARCHAR2,
51 x_msg_count OUT NOCOPY NUMBER,
52 x_msg_data OUT NOCOPY VARCHAR2,
53
54 p_po_code IN VARCHAR2,
55 p_org_id IN VARCHAR2,
56 p_release_id IN VARCHAR2 := NULL,
57 p_line_num IN NUMBER,
58 p_doc_type IN VARCHAR2,
59 p_quantity IN NUMBER,
60 p_amount IN NUMBER
61 ) AS
62
63 /* Business object constants. */
64 l_api_name CONSTANT VARCHAR2(30) := 'Update_PoLine';
65 l_api_version CONSTANT NUMBER := 1.0;
66
67 /* rec_po_line_locations */
68 TYPE lloc_rec IS RECORD (
69 line_location_id po_line_locations.line_location_id%TYPE,
70 quantity po_line_locations.quantity%TYPE,
71 quantity_received po_line_locations.quantity_received%TYPE,
72 quantity_accepted po_line_locations.quantity_accepted%TYPE,
73 quantity_billed po_line_locations.quantity_billed%TYPE,
74 qty_rcv_tolerance po_line_locations.qty_rcv_tolerance%TYPE,
75 qty_rcv_exception_code po_line_locations.qty_rcv_exception_code%TYPE,
76 closed_code po_line_locations.closed_code%TYPE,
77 receive_close_tolerance po_line_locations.receive_close_tolerance%TYPE,
78 process_date po_line_locations.creation_date%TYPE,
79 new_quantity NUMBER,
80 changed NUMBER
81 );
82 /* table_po_line_locations_ot */
83 TYPE lloc_tab IS TABLE OF lloc_rec
84 INDEX BY BINARY_INTEGER;
85
86 CURSOR po_line_csr IS
87 SELECT po_line_id,closed_code
88 FROM po_lines_all
89 WHERE po_header_id = g_po_id
90 AND line_num = p_line_num;
91
92 CURSOR po_relid_csr(p_header_id IN VARCHAR2,
93 p_org IN VARCHAR2,
94 p_release_num IN VARCHAR2) IS
95 SELECT po_release_id
96 FROM po_releases_all
97 WHERE po_header_id = p_header_id
98 AND release_num = p_release_num
99 AND org_id = p_org;
100
101 l_rec po_line_csr%ROWTYPE;
102 l_notfound BOOLEAN;
103 l_release_id NUMBER;
104 l_doc_typ VARCHAR2(50);
105
106 /* getClosedCodeForLineLocation */
107 FUNCTION get_closed_code(
108 p_lloc IN lloc_rec,
109 p_qty_oper IN NUMBER
110 ) RETURN VARCHAR2 IS
111 BEGIN
112 ITG_Debug.msg('GCC', 'Entering ...');
113 ITG_Debug.msg('GCC', 'Quantity', p_lloc.quantity);
114 ITG_Debug.msg('GCC', 'Quantity operation', p_qty_oper);
115 ITG_Debug.msg('GCC', 'Tolerance', p_lloc.receive_close_tolerance);
116 ITG_Debug.msg('GCC', 'Closed code', p_lloc.closed_code);
117 IF p_qty_oper >= (p_lloc.quantity - ROUND(
118 p_lloc.quantity * p_lloc.receive_close_tolerance/100)) THEN
119 IF NVL(p_lloc.closed_code, 'OPEN') = 'OPEN' THEN
120 IF p_doc_type = 'RECEIPT' THEN
121 RETURN 'RECEIVE CLOSE';
122 ELSE
123 RETURN 'INVOICE CLOSE';
124 END IF;
125 ELSIF p_lloc.closed_code = 'CLOSED FOR INVOICE' THEN
126 IF p_doc_type = 'RECEIPT' THEN
127 RETURN 'CLOSE';
128 END IF;
129 ELSIF p_lloc.closed_code = 'CLOSED FOR RECEIVING' THEN
130 IF p_doc_type = 'INVOICE' THEN
131 RETURN 'CLOSE';
132 END IF;
133 END IF;
134 ELSE
135 IF p_lloc.closed_code = 'CLOSED' THEN
136 IF p_doc_type = 'RECEIPT' THEN
137 RETURN 'INVOICE OPEN';
138 ELSE
139 RETURN 'RECEIVE OPEN';
140 END IF;
141 ELSIF p_lloc.closed_code = 'CLOSED FOR INVOICE' THEN
142 IF p_doc_type = 'INVOICE' THEN
143 RETURN 'INVOICE OPEN';
144 END IF;
145 ELSIF p_lloc.closed_code = 'CLOSED FOR RECEIVING' THEN
146 IF p_doc_type = 'RECEIPT' THEN
147 RETURN 'RECEIPT OPEN';
148 END IF;
149 END IF;
150 END IF;
151 RETURN NULL;
152 END get_closed_code;
153
154 /* allocateAcrossLineLocations */
155 FUNCTION aa_llocs(
156 l_lltab IN OUT NOCOPY lloc_tab
157 ) RETURN BOOLEAN /* leftover */ AS
158
159 TYPE line_loc_csr_typ IS REF CURSOR RETURN lloc_rec;
160
161 line_loc_csr line_loc_csr_typ;
162 l_tmp lloc_rec;
163 l_subj_qty NUMBER;
164 l_base_qty NUMBER;
165 l_qty NUMBER;
166 l_tmp_qty NUMBER;
167 l_last NUMBER;
168 l_tot_rec_qty number :=0; -- Added following 3 declarations to fix bug 4882347
169 l_tot_bill_qty number :=0;
170 l_tot_insp_qty number :=0;
171 PROCEDURE setup_doctype_qtys(x_rec IN OUT NOCOPY lloc_rec) IS
172 BEGIN
173 IF p_doc_type = 'RECEIPT' THEN
174 l_subj_qty := x_rec.quantity_received;
175 l_base_qty := x_rec.quantity;
176 ELSIF p_doc_type = 'INSPECTION' THEN
177 l_subj_qty := x_rec.quantity_accepted;
178 l_base_qty := x_rec.quantity_received;
179 ELSIF p_doc_type = 'INVOICE' THEN
180 l_subj_qty := x_rec.quantity_billed;
181 l_base_qty := x_rec.quantity;
182 END IF;
183 END;
184
185 PROCEDURE change_doctype_qtys(x_rec IN OUT NOCOPY lloc_rec) IS
186 BEGIN
187 /* Set the newly allocated value for this line to the
188 * appropriate PLS table field, based on doctype.
189 */
190 IF p_doc_type = 'RECEIPT' THEN
191 x_rec.quantity_received := l_subj_qty;
192 ELSIF p_doc_type = 'INSPECTION' THEN
193 x_rec.quantity_accepted := l_subj_qty;
194 ELSIF p_doc_type = 'INVOICE' THEN
195 x_rec.quantity_billed := l_subj_qty;
196 END IF;
197 x_rec.changed := 1;
198 END;
199
200 BEGIN
201 ITG_Debug.msg('AALL', 'Entering...');
202
203 l_lltab.delete;
204 l_qty := p_quantity;
205 IF l_release_id IS NULL THEN
206 /* This is a standard PO. */
207 IF l_qty > 0 THEN
208 /* Positive quantity, this is a RECEIPT against standard POs */
209 OPEN line_loc_csr FOR
210 SELECT line_location_id,
211 quantity,
212 quantity_received,
213 quantity_accepted,
214 quantity_billed,
215 qty_rcv_tolerance,
216 qty_rcv_exception_code,
217 closed_code,
218 receive_close_tolerance,
219 NVL(need_by_date, promised_date) process_date,
220 0 new_quantity,
221 0 changed
222 FROM po_line_locations_all
223 WHERE po_line_id = l_rec.po_line_id
224 ORDER BY process_date;
225 ELSE
226 /* Negative quantity, this is a RETURN against standard POs.
227 * The only difference is reverse sort order.
228 */
229 OPEN line_loc_csr FOR
230 SELECT line_location_id,
231 quantity,
232 quantity_received,
233 quantity_accepted,
234 quantity_billed,
235 qty_rcv_tolerance,
236 qty_rcv_exception_code,
237 closed_code,
238 receive_close_tolerance,
239 NVL(promised_date, need_by_date) process_date,
240 0 new_quantity,
241 0 changed
242 FROM po_line_locations_all
243 WHERE po_line_id = l_rec.po_line_id
244 ORDER BY process_date DESC;
245 END IF;
246 ELSE
247 /* This is a RELEASE against a BPO. */
248 IF l_qty > 0 THEN
249
250 /* Positive quantity, this is a RECEIPT against blanket PO
251 * releases.
252 */
253 OPEN line_loc_csr FOR
254 SELECT line_location_id,
255 quantity,
256 quantity_received,
257 quantity_accepted,
258 quantity_billed,
259 qty_rcv_tolerance,
260 qty_rcv_exception_code,
261 closed_code,
262 receive_close_tolerance,
263 NVL(need_by_date, promised_date) process_date,
264 0 new_quantity,
265 0 changed
266 FROM po_line_locations_all
267 WHERE po_release_id = l_release_id
268 AND po_header_id = g_po_id
269 ORDER BY process_date;
270 ELSE
271 /* Negative quantity, this is a RETURN against blanket PO releases.
272 * The only difference is reverse sort order.
273 */
274 OPEN line_loc_csr FOR
275 SELECT line_location_id,
276 quantity,
277 quantity_received,
278 quantity_accepted,
279 quantity_billed,
280 qty_rcv_tolerance,
281 qty_rcv_exception_code,
282 closed_code,
283 receive_close_tolerance,
284 NVL(promised_date, need_by_date) process_date,
285 0 new_quantity,
286 0 changed
287 FROM po_line_locations_all
288 WHERE po_release_id = l_release_id
289 AND po_header_id = g_po_id
290 ORDER BY process_date DESC;
291 END IF;
292 END IF;
293
294 /* Read the data. */
295 ITG_Debug.msg('AALL', 'Reading the data.');
296 LOOP
297 FETCH line_loc_csr INTO l_tmp;
298 IF line_loc_csr%NOTFOUND THEN
299 EXIT;
300 END IF;
301 l_lltab(line_loc_csr%ROWCOUNT) := l_tmp; /* Added following assignments to fix bug 4882347 */
302 l_tot_rec_qty := l_tot_rec_qty + l_lltab(line_loc_csr%ROWCOUNT).quantity_received;
303 l_tot_bill_qty := l_tot_bill_qty + l_lltab(line_loc_csr%ROWCOUNT).quantity_billed;
304 l_tot_insp_qty := l_tot_insp_qty + l_lltab(line_loc_csr%ROWCOUNT).quantity_accepted;
305 END LOOP;
306 CLOSE line_loc_csr;
307 /* Added if-else block to check whether Invoice and Inspection qty is more than allowable qty, to fix 4882347 bug*/
308 IF p_doc_type = 'INVOICE' THEN
309 IF ( l_tot_rec_qty - l_tot_bill_qty ) < l_qty THEN
310 ITG_MSG.inv_qty_larg_than_exp;
311 RAISE FND_API.G_EXC_ERROR;
312 END IF;
313 ELSIF p_doc_type = 'INSPECTION' THEN
314 IF ( l_tot_rec_qty - l_tot_insp_qty ) < l_qty THEN
315 ITG_MSG.insp_qty_larg_than_exp;
316 RAISE FND_API.G_EXC_ERROR;
317 END IF;
318 END IF;
319
320 l_last := -1;
321 /* Distrubute the quantity. */
322 ITG_Debug.msg('AALL', 'Distributing the quantity.');
323 FOR i in 1 .. l_lltab.count LOOP
324 l_last := i;
325 setup_doctype_qtys(l_lltab(i));
326 IF l_qty > 0 THEN
327 IF l_base_qty - l_subj_qty >= l_qty THEN
328 /* Additional quantity available to allocate is greater than or
329 * equal to the Quantity to allocate, thus total quantity can be
330 * allocated here.
331 */
332 ITG_Debug.msg('AALL', 'Full allocate.');
333 l_subj_qty := l_subj_qty + l_qty;
334 l_lltab(i).new_quantity := l_qty;
335 l_qty := 0;
336 ELSE
337 /* Quantity to allocate is more than the additional Quantity
338 * available to allocate, thus allocate the max available without
339 * tolerance.
340 */
341 ITG_Debug.msg('AALL', 'Partial allocate.');
342 l_lltab(i).new_quantity := l_base_qty - l_subj_qty;
343 l_subj_qty := l_base_qty;
344 l_qty := l_qty - l_lltab(i).new_quantity;
345 END IF;
346 ELSE
347 /* Negative l_qty for RETURNs or CR INVOICEs, no NEG INSPECTIONs. */
348 IF l_subj_qty >= ABS(l_qty) THEN
349 /* Quantity previously received and available to return is
350 * greater than or equal to the Quantity to allocate, thus
351 * total quantity can be allocated here.
352 */
353 ITG_Debug.msg('AALL', 'Full CR allocate.');
354 l_subj_qty := l_subj_qty + l_qty;
355 l_lltab(i).new_quantity := l_qty;
356 l_qty := 0;
357 ELSE
358 /* Quantity to allocate is more than the Quantity previously
359 * received, thus allocate the max available without tolerance.
360 */
361 ITG_Debug.msg('AALL', 'Partial CR allocate.');
362 l_lltab(i).new_quantity := 0 - l_subj_qty;
363 l_subj_qty := 0;
364 l_qty := l_qty - l_lltab(i).new_quantity;
365 END IF;
366 END IF;
367 ITG_Debug.msg('AALL', 'l_qty', l_qty);
368 ITG_Debug.msg('AALL', 'l_subj_qty', l_subj_qty);
369 change_doctype_qtys(l_lltab(i));
370 EXIT WHEN l_qty = 0;
371 END LOOP;
372
373 /* If p_qty isn't 0, then we need to check for error or continue with
374 * tolerance processing. (Note that the last used index value is
375 * carried forward from the loop as 'l_last'.)
376 */
377 IF l_qty < 0 THEN
378 /* Trying to RETURN or CREDIT more than received or billed. */
379 ITG_MSG.allocship_toomany_rtn;
380 RAISE FND_API.G_EXC_ERROR;
381 ELSIF l_qty > 0 THEN
382 ITG_Debug.msg('AALL', 'More quantity', l_qty);
383 /* Still have more? Lets try put those in the last shipment line.
384 * We need to worry about the tolerance level while trying to
385 * allocate remaining l_qty if exception code is REJECT. Calculate
386 * the maximum additional tolerance quantity receiveable on this
387 * line.
388 */
389 IF l_last < 0 THEN
390 ITG_MSG.no_line_locs_found;
391 RAISE FND_API.G_EXC_ERROR;
392 END IF;
393 l_tmp := l_lltab(l_last);
394 l_tmp_qty := ROUND(l_base_qty * NVL(l_tmp.qty_rcv_tolerance, 0) / 100);
395
396 IF l_tmp.qty_rcv_exception_code = 'REJECT'
397 AND l_tmp_qty < l_qty
398 THEN
399 /* Allocate the additional quantity, even though it's not enough.
400 * (The non-zero l_qty will cause the aa_llocs function to return
401 * TRUE, indicating a leftover quantity problem).
402 */
403 l_subj_qty := l_subj_qty + l_tmp_qty;
404 l_tmp.new_quantity := l_tmp.new_quantity + l_tmp_qty;
405 l_qty := l_qty - l_tmp_qty;
406 ITG_Debug.msg('AALL', 'Partial DB tolerance.');
407 ELSE
408 /* Exception code is not REJECT or the tolerance quantity is
409 * enough to cover the extra needed, put everything in last
410 * shipment line.
411 */
412 l_subj_qty := l_subj_qty + l_qty;
413 l_tmp.new_quantity := l_tmp.new_quantity + l_qty;
414 l_qty := 0;
415 IF l_tmp.qty_rcv_exception_code = 'REJECT' THEN
416 ITG_Debug.msg('AALL', 'Full DB tolerance.');
417 ELSE
418 ITG_Debug.msg('AALL', 'Partial DB no tolerance.');
419 END IF;
420 END IF;
421 ITG_Debug.msg('AALL', 'l_qty', l_qty);
422 ITG_Debug.msg('AALL', 'l_subj_qty', l_subj_qty);
423 change_doctype_qtys(l_tmp);
424 l_lltab(l_last) := l_tmp;
425 END IF;
426 ITG_Debug.msg('AALL', 'Leaving with leftover', l_qty);
427 /* Indicate any leftover quantity problem. */
428 RETURN l_qty <> 0;
429 END aa_llocs;
430
431 /* allocateAcrossDistributions */
432 PROCEDURE aa_dists(
433 p_line_loc_id NUMBER,
434 p_quantity NUMBER,
435 p_total_amount NUMBER
436 ) IS
437
438 CURSOR po_dist_csr IS
439 SELECT po_distribution_id,
440 quantity_ordered,
441 quantity_billed,
442 quantity_delivered,
443 amount_billed
444 FROM po_distributions_all
445 WHERE line_location_id = p_line_loc_id;
446
447 TYPE po_dist_rec IS RECORD (
448 po_distribution_id po_distributions_all.po_distribution_id%TYPE,
449 quantity_ordered po_distributions_all.quantity_ordered%TYPE,
450 quantity_billed po_distributions_all.quantity_billed%TYPE,
451 quantity_delivered po_distributions_all.quantity_delivered%TYPE,
452 amount_billed po_distributions_all.amount_billed%TYPE);
453
454 TYPE po_dist_tab IS TABLE OF po_dist_rec
455 INDEX BY BINARY_INTEGER;
456
457 i NUMBER;
458 l_oper NUMBER;
459 l_quantity NUMBER;
460 l_disttab po_dist_tab;
461
462 BEGIN
463 ITG_Debug.msg('AAD', 'Entering..');
464 ITG_Debug.msg('AAD', 'line_loc_id', p_line_loc_id);
465 ITG_Debug.msg('AAD', 'quantity', p_quantity);
466 l_quantity := p_quantity;
467 l_disttab.DELETE;
468 FOR rec IN po_dist_csr LOOP
469 /* Determine how much to allocate to each distribution line. */
470 i := po_dist_csr%ROWCOUNT;
471 l_disttab(i) := rec;
472 ITG_Debug.msg('AAD', 'i', i);
473 ITG_Debug.msg('AAD', 'po_distribution_id',
474 l_disttab(i).po_distribution_id);
475 ITG_Debug.msg('AAD', 'quantity_ordered',
476 l_disttab(i).quantity_ordered);
477 ITG_Debug.msg('AAD', 'quantity_billed',
478 l_disttab(i).quantity_billed);
479 ITG_Debug.msg('AAD', 'quantity_delivered',
480 l_disttab(i).quantity_delivered);
481 ITG_Debug.msg('AAD', 'amount_billed',
482 l_disttab(i).amount_billed);
483
484 /* Get the appropriate quantity to compare, based on doctype. */
485 IF p_doc_type = 'RECEIPT' THEN
486 l_oper := l_disttab(i).quantity_delivered;
487 ELSIF p_doc_type = 'INVOICE' THEN
488 l_oper := l_disttab(i).quantity_billed;
489 END IF;
490 ITG_Debug.msg('AAD', 'quantity_ordered',l_disttab(i).quantity_ordered);
491 ITG_Debug.msg('AAD', 'quantity_operate',l_oper);
492 ITG_Debug.msg('AAD', 'quantity', l_quantity);
493
494 IF l_quantity > 0 THEN
495 IF l_disttab(i).quantity_ordered - l_oper >= l_quantity THEN
496 /* Additional quantity which can be allocated is greater than or
497 * equal to the quantity to allocate, thus total quantity can be
498 * allocated here.
499 */
500 l_oper := l_oper + l_quantity;
501 l_quantity := 0;
502 ITG_Debug.msg('AAD', 'Full allocate ...');
503 ELSE
504 /* Quantity to allocate is more than the additional quantity
505 * available to allocate, thus allocate the max available.
506 */
507 l_quantity := l_quantity -
508 (l_disttab(i).quantity_ordered - l_oper);
509 l_oper := l_disttab(i).quantity_ordered;
510 ITG_Debug.msg('AAD', 'Partial allocate ...');
511 END IF; /* Full or Partial allocation to this line? */
512 ELSIF l_quantity < 0 THEN
513 IF l_oper >= ABS(l_quantity) THEN
514 /* Quantity previously received and available to return is
515 * greater than or equal to the quantity to allocate, thus
516 * total quantity can be allocated here.
517 */
518 l_oper := l_oper + l_quantity;
519 l_quantity := 0;
520 ITG_Debug.msg('AAD', 'Full CR allocate ...');
521 ELSE
522 /* Quantity to allocate is more than the quantity previously
523 * received, thus allocate the max available without tolerance.
524 */
525 l_quantity := l_quantity + l_oper;
526 l_oper := 0;
527 ITG_Debug.msg('AAD', 'Partial CR allocate ...');
528 END IF; /* Full or Partial allocation to this line? */
529 END IF; /* POS or NEG totalQuantity? */
530 ITG_Debug.msg('AAD', 'quantity_operate', l_oper);
531 ITG_Debug.msg('AAD', 'quantity', l_quantity);
532
533 /* Return the newly allocated value for this line to the appropriate
534 * PLS table field, based on doctype.
535 */
536 IF p_doc_type = 'RECEIPT' THEN
537 l_disttab(i).quantity_delivered := l_oper;
538 ELSIF p_doc_type = 'INVOICE' THEN
539 l_disttab(i).quantity_billed := l_oper;
540 END IF;
541 EXIT WHEN l_quantity = 0;
542 END LOOP;
543
544 /* If there is more to allocate, then allocate all to the LAST
545 * distribution, as there is no tolerance processing for distributions.
546 */
547 IF l_quantity > 0 THEN
548 IF p_doc_type = 'RECEIPT' THEN
549 l_disttab(i).quantity_delivered := l_disttab(i).quantity_delivered +
550 l_quantity;
551 l_quantity := 0;
552 ITG_Debug.msg('AAD', 'Recv. DB no tolerance ...');
553 ELSIF p_doc_type = 'INVOICE' THEN
554 l_disttab(i).quantity_billed := l_disttab(i).quantity_billed +
555 l_quantity;
556 l_quantity := 0;
557 ITG_Debug.msg('AAD', 'Invoice DB no tolerance ...');
558 END IF;
559 ITG_Debug.msg('AAD', 'quantity_operate', l_oper);
560 ITG_Debug.msg('AAD', 'quantity', l_quantity);
561 ELSIF l_quantity < 0 THEN
562 /* Trying to distribute a RETURN and more is needed to RETURN than
563 * was initially distributed. This should NOT be able to happen.
564 */
565 ITG_MSG.allocdist_toomany_rtn;
566 RAISE FND_API.G_EXC_ERROR;
567 END IF;
568
569 /* Ok time to update the table.. */
570 ITG_Debug.msg('AAD', 'Update po_distributions_all ...');
571 IF p_doc_type = 'RECEIPT' THEN
572 FOR i IN 1 .. l_disttab.COUNT LOOP
573 UPDATE po_distributions_all
574 SET quantity_delivered = l_disttab(i).quantity_delivered,
575 last_update_date = SYSDATE,
576 last_updated_by = FND_GLOBAL.user_id
577 WHERE po_distribution_id = l_disttab(i).po_distribution_id;
578 ITG_Debug.msg('AAD', 'po_distribution_id',
579 l_disttab(i).po_distribution_id);
580 ITG_Debug.msg('AAD', 'quantity_delivered',
581 l_disttab(i).quantity_delivered);
582 END LOOP;
583 ELSIF p_doc_type = 'INVOICE' THEN
584 FOR i IN 1 .. l_disttab.COUNT LOOP
585 UPDATE po_distributions_all
586 SET quantity_billed = l_disttab(i).quantity_billed,
587 amount_billed = NVL(amount_billed,0) +
588 (l_disttab(i).quantity_billed / p_quantity) *
589 p_total_amount,
590 last_update_date = SYSDATE,
591 last_updated_by = FND_GLOBAL.user_id
592 WHERE po_distribution_id = l_disttab(i).po_distribution_id;
593 ITG_Debug.msg('AAD', 'po_distribution_id',
594 l_disttab(i).po_distribution_id);
595 ITG_Debug.msg('AAD', 'quantity_billed',
596 l_disttab(i).quantity_billed);
597 END LOOP;
598 END IF;
599 ITG_Debug.msg('AAD', 'Leaving.');
600 END aa_dists;
601
602 /* allocateAcrossReqLineLocs */
603 PROCEDURE aa_rllocs(
604 p_new_quantity NUMBER
605 ) IS
606 /* There is not a 1:1 match between Requisition lines and Shipment
607 * lines, nor is the PO Line ID stored in the requisition line...
608 * the shipment line is... even though there could be more than 1
609 * shipment line for this req line. Thus, the requisition line is
610 * matched in this cursor against any of the shipment lines for the
611 * PO line.
612 */
613 CURSOR po_req_lines_csr IS
614 SELECT requisition_line_id,
615 quantity,
616 quantity_delivered
617 FROM po_requisition_lines_all
618 WHERE line_location_id IN (
619 SELECT line_location_id
620 FROM po_line_locations_all
621 WHERE po_line_id = l_rec.po_line_id)
622 ORDER BY need_by_date;
623
624 TYPE po_req_lines_rec IS RECORD (
625 requisition_line_id po_requisition_lines_all.requisition_line_id%TYPE,
626 quantity po_requisition_lines_all.quantity%TYPE,
627 quantity_delivered po_requisition_lines_all.quantity_delivered%TYPE
628 );
629
630 TYPE po_req_lines_tab IS TABLE OF po_req_lines_rec
631 INDEX BY BINARY_INTEGER;
632
633 l_reqlltab po_req_lines_tab;
634 i NUMBER := 0;
635 l_qty NUMBER;
636
637 BEGIN
638 ITG_Debug.msg('ARL', 'Entering...');
639 ITG_Debug.msg('ARL', 'new_quantity', p_new_quantity);
640 l_qty := p_new_quantity;
641 l_reqlltab.DELETE;
642
643 FOR rec IN po_req_lines_csr LOOP
644 /* Determine how much to allocate to each requisition line */
645 i := po_req_lines_csr%ROWCOUNT;
646 l_reqlltab(i) := rec;
647 ITG_Debug.msg('ARL', 'i', i);
648
649 IF l_qty > 0 THEN
650 IF l_reqlltab(i).quantity -
651 l_reqlltab(i).quantity_delivered >= l_qty THEN
652 /* Additional quantity which can be allocated is greater than
653 * or to the quantity to allocate, thus totalQuantity can be
654 * allocated here.
655 */
656 ITG_Debug.msg('ARL', 'Allocating full ...');
657 l_reqlltab(i).quantity_delivered :=
658 l_reqlltab(i).quantity_delivered + l_qty;
659 l_qty := 0;
660 ELSE
661 /* Quantity to allocate is more than the additional Quantity to
662 * allocate, thus allocate the max available.
663 */
664 ITG_Debug.msg('ARL', 'Allocating max ...');
665 l_qty := l_qty -
666 (l_reqlltab(i).quantity - l_reqlltab(i).quantity_delivered);
667 l_reqlltab(i).quantity_delivered := l_reqlltab(i).quantity;
668 END IF; /* Full or Partial allocation to this line? */
669 ITG_Debug.msg('ARL', 'quantity', l_reqlltab(i).quantity);
670 ITG_Debug.msg('ARL', 'quantity_delivered',
671 l_reqlltab(i).quantity_delivered);
672 ITG_Debug.msg('ARL', 'quantity need', l_qty);
673 ELSIF l_qty < 0 THEN
674 IF l_reqlltab(i).quantity_delivered >= ABS(l_qty) THEN
675 /* Quantity previously received and available to return is greater
676 * than or equal to the quantity to allocate, thus totalQuantity
677 * can be allocated here.
678 */
679 ITG_Debug.msg('ARL', 'Allocating CR full ...');
680 l_reqlltab(i).quantity_delivered :=
681 l_reqlltab(i).quantity_delivered + l_qty;
682 l_qty := 0;
683 ELSE
684 /* Quantity to allocate is more than the additional quantity to
685 * allocate, thus allocate the max available.
686 */
687 ITG_Debug.msg('ARL', 'Allocating CR Partial ...');
688 l_qty := l_qty + l_reqlltab(i).quantity_delivered;
689 l_reqlltab(i).quantity_delivered := 0;
690 END IF; /* Full or Partial CR allocation to this line? */
691 ELSE /* l_qty = 0, so all have been allocated */
692 EXIT;
693 END IF; /* POS or NEG totalQuantity? */
694 EXIT WHEN l_qty = 0;
695 END LOOP; /* For each requisition line */
696
697 ITG_Debug.msg('ARL', '# of req. ship lines', i);
698 /* IF no lines were found, THEN return. */
699 IF i = 0 THEN
700 ITG_Debug.msg('ARL', 'NO req. ship lines found ...');
701 RETURN;
702 END IF;
703
704 /* If there is more to allocate, the allocate all to the LAST
705 * requisition line, as there is no tolerance processing for
706 * requisitions.
707 */
708 IF l_qty > 0 THEN
709 ITG_Debug.msg('ARL', 'Over-allocating to the last ...');
710 l_reqlltab(i).quantity_delivered := l_reqlltab(i).quantity_delivered +
711 l_qty;
712 l_qty := 0;
713 ELSIF l_qty < 0 THEN
714 /* Trying to distribute a RETURN and more is needed to RETURN than
715 * was initially distributed. This should NOT be able to happen.
716 */
717 ITG_MSG.allocreqn_toomany_rtn;
718 RAISE FND_API.G_EXC_ERROR;
719 END IF;
720
721 /* Time to update the table */
722 ITG_Debug.msg('ARL', 'Updating po_requisition_lines_all ...');
723 ITG_Debug.msg('ARL', 'l_reqlltab.COUNT', l_reqlltab.COUNT);
724 FOR i IN 1 .. l_reqlltab.COUNT LOOP
725 UPDATE po_requisition_lines_all
726 SET quantity_delivered = l_reqlltab(i).quantity_delivered,
727 last_update_date = SYSDATE,
728 last_updated_by = FND_GLOBAL.user_id
729 WHERE requisition_line_id = l_reqlltab(i).requisition_line_id;
730 ITG_Debug.msg('ARL', 'requisition_line_id',
731 l_reqlltab(i).requisition_line_id);
732 ITG_Debug.msg('ARL', 'quantity_delivered',
733 l_reqlltab(i).quantity_delivered);
734 END LOOP;
735 ITG_Debug.msg('ARL', 'Leaving.');
736 END aa_rllocs;
737
738 /* ~processReceipt */
739 PROCEDURE process_receipt_doc IS
740 i NUMBER;
741 l_closed_code po_line_locations.closed_code%TYPE;
742 l_doc_type VARCHAR2(10);
743 l_doc_subtype VARCHAR2(10);
744 l_return_code VARCHAR2(25) := ' ';
745 l_lltab lloc_tab;
746 BEGIN
747 g_action := 'processing receipt information';
748 ITG_Debug.msg('PRD', 'Entering...');
749 IF p_quantity > 0 AND (l_rec.closed_code = 'CLOSED FOR RECEIVING' OR
750 l_rec.closed_code = 'CLOSED') THEN
751 ITG_MSG.poline_closed_rcv;
752 RAISE FND_API.G_EXC_ERROR;
753 /*Added p_quantiyy < 0 to fix bug 5438268 */
754 ELSIF p_quantity < 0 THEN
755 ITG_MSG.poline_negqty_rcv;
756 RAISE FND_API.G_EXC_ERROR;
757 ELSIF p_quantity = 0 THEN
758 ITG_MSG.poline_zeroqty_rcv;
759 RAISE FND_API.G_EXC_ERROR;
760
761 ELSE
762 /* processReceipt */
763 IF aa_llocs(l_lltab) THEN
764 ITG_MSG.receipt_tol_exceeded;
765 RAISE FND_API.G_EXC_ERROR;
766 END IF;
767
768 IF l_release_id IS NULL THEN
769 l_doc_type := 'PO';
770 l_doc_subtype := 'STANDARD';
771 ELSE
772 l_doc_type := 'RELEASE';
773 l_doc_subtype := 'BLANKET';
774 END IF;
775
776 FOR i IN 1 .. l_lltab.count LOOP
777 ITG_Debug.msg('PRD', 'Line location id',l_lltab(i).line_location_id);
778 IF l_lltab(i).changed <> 0 THEN
779 ITG_Debug.msg('PRD', 'Call distributions', i);
780 ITG_Debug.msg('PRD', 'New quantity',
781 l_lltab(i).new_quantity);
782 aa_dists(l_lltab(i).line_location_id,
783 l_lltab(i).new_quantity, 0);
784 aa_rllocs(l_lltab(i).new_quantity);
785 END IF;
786
787 ITG_Debug.msg('PRD', 'update po_line_locations_all');
788 UPDATE po_line_locations_all
789 SET quantity_received = l_lltab(i).quantity_received,
790 last_update_date = SYSDATE,
791 last_updated_by = FND_GLOBAL.user_id
792 WHERE line_location_id = l_lltab(i).line_location_id;
793 ITG_Debug.msg('PRD', 'quantity_received',
794 l_lltab(i).quantity_received);
795
796 l_closed_code := get_closed_code(
797 l_lltab(i), l_lltab(i).quantity_received);
798 ITG_Debug.msg('PRD', 'closed_code', l_closed_code);
799 IF l_closed_code IS NOT NULL THEN
800 ITG_Debug.msg('PRD', 'close PO called...');
801 ITG_Debug.msg('PRD', 'doc ID', g_po_id);
802 ITG_Debug.msg('PRD', 'doc type', l_doc_type);
803 ITG_Debug.msg('PRD', 'line ID', l_rec.po_line_id);
804 ITG_Debug.msg('PRD', 'ship ID', l_lltab(i).line_location_id);
805
806 /*Added following if <cond> and else part to fix bug :5258514 */
807 IF p_release_id IS NULL or p_release_id =0 THEN
808
809 IF NOT PO_ACTIONS.close_po(
810 p_docID => g_po_id,
811 p_doctyp => l_doc_type,
812 p_docsubtyp => l_doc_subtype,
813 p_lineid => l_rec.po_line_id,
814 p_shipid => l_lltab(i).line_location_id,
815 p_action => l_closed_code,
816 p_calling_mode => 'RCV',
817 p_return_code => l_return_code,
818 p_auto_close => 'Y'
819 ) THEN
820 ITG_Debug.msg('PRD', 'Close PO failed...');
821 ITG_Debug.msg('PRD', 'return code', l_return_code);
822 ITG_MSG.receipt_closepo_fail(l_return_code);
823 RAISE FND_API.G_EXC_ERROR;
824 ELSE
825 ITG_Debug.msg('PRD', 'Close PO succeded');
826 ITG_Debug.msg('PRD', 'return code', l_return_code);
827 END IF;
828 ELSE
829 IF NOT PO_ACTIONS.close_po(
830 p_docID => l_release_id,
831 p_doctyp => l_doc_type,
832 p_docsubtyp => l_doc_subtype,
833 p_lineid => l_rec.po_line_id,
834 p_shipid => l_lltab(i).line_location_id,
835 p_action => l_closed_code,
836 p_calling_mode => 'RCV',
837 p_return_code => l_return_code,
838 p_auto_close => 'Y'
839 ) THEN
840 ITG_Debug.msg('PRD', 'Close Release failed...');
841 ITG_Debug.msg('PRD', 'return code', l_return_code);
842 ITG_MSG.receipt_closerelease_fail(l_return_code);
843 RAISE FND_API.G_EXC_ERROR;
844 ELSE
845 ITG_Debug.msg('PRD', 'Close Release succeded');
846 ITG_Debug.msg('PRD', 'return code', l_return_code);
847 END IF;
848 END IF; --END FOR P_RELAESE_ID BLOCK
849 END IF; --END FOR L_CLOSED_CODE BLOCK
850 END LOOP;
851 END IF;
852 END process_receipt_doc;
853
854 /* ~processInspection */
855 PROCEDURE process_inspection_doc IS
856 i NUMBER;
857 l_lltab lloc_tab;
858 BEGIN
859 g_action := 'processing inspection information';
860 ITG_Debug.msg('PID', 'Entering...');
861 IF p_quantity > 0 THEN
862 /* processInspection */
863 IF aa_llocs(l_lltab) THEN
864 ITG_MSG.inspect_tol_exceeded;
865 RAISE FND_API.G_EXC_ERROR;
866 END IF;
867
868 FOR i IN 1 .. l_lltab.count LOOP
869 UPDATE po_line_locations_all
870 SET quantity_accepted = l_lltab(i).quantity_accepted,
871 last_update_date = SYSDATE,
872 last_updated_by = FND_GLOBAL.user_id
873 WHERE line_location_id = l_lltab(i).line_location_id;
874 ITG_Debug.msg('PID', 'Update po_line_locations_all');
875 ITG_Debug.msg('PID', 'quantity_accepted',
876 l_lltab(i).quantity_accepted);
877 ITG_Debug.msg('PID', 'line_location_id',
878 l_lltab(i).line_location_id);
879 END LOOP;
880 ELSIF p_quantity < 0 THEN
881 ITG_MSG.poline_negqty_ins;
882 RAISE FND_API.G_EXC_ERROR;
883 ELSE
884 ITG_MSG.poline_zeroqty_ins;
885 RAISE FND_API.G_EXC_ERROR;
886 END IF;
887 END process_inspection_doc;
888
889 /* ~processInvoice */
890 PROCEDURE process_invoice_doc IS
891 i NUMBER;
892 l_closed_code po_line_locations.closed_code%TYPE;
893 l_doc_type VARCHAR2(10);
894 l_doc_subtype VARCHAR2(10);
895 l_return_code VARCHAR2(25) := ' ';
896 l_qty NUMBER;
897 l_lltab lloc_tab;
898 BEGIN
899 g_action := 'processing invoice information';
900 ITG_Debug.msg('PI', 'Entering...');
901 IF p_amount = 0 THEN
902 ITG_MSG.poline_zeroamt_inv;
903 RAISE FND_API.G_EXC_ERROR;
904 ELSIF SIGN(p_quantity) <> SIGN(p_amount) AND
905 SIGN(p_quantity) <> 0 THEN
906 ITG_MSG.poline_badsign_inv;
907 RAISE FND_API.G_EXC_ERROR;
908 ELSIF l_rec.closed_code = 'CLOSED FOR INVOICE' OR
909 l_rec.closed_code = 'CLOSED' THEN
910 ITG_MSG.poline_closed_inv;
911 RAISE FND_API.G_EXC_ERROR;
912 ELSE
913 /* processInvoice */
914 IF aa_llocs(l_lltab) THEN
915 /* If there more stuff to allocate, then we got a problem, send a
916 * message: 'Receipt Tolerance Exceeded'
917 */
918 ITG_MSG.invoice_tol_exceeded;
919 RAISE FND_API.G_EXC_ERROR;
920 END IF;
921
922 /* Process the distributions */
923 FOR i IN 1 .. l_lltab.COUNT LOOP
924 IF l_lltab(i).changed <> 0 THEN
925 aa_dists(l_lltab(i).line_location_id,
926 l_lltab(i).quantity_billed, p_amount);
927 END IF;
928
929 /* Get the closed code for each line_location. */
930 l_closed_code := get_closed_code(
931 l_lltab(i), l_lltab(i).quantity_billed);
932
933 /* Update the table for the quantity billed */
934 ITG_Debug.msg('PI', 'Update po_line_locations_all ...');
935 ITG_Debug.msg('PI', 'quantity_billed', l_lltab(i).quantity_billed);
936 ITG_Debug.msg('PI', 'line_location_id', l_lltab(i).line_location_id);
937 UPDATE po_line_locations_all
938 SET quantity_billed = l_lltab(i).quantity_billed,
939 last_update_date = SYSDATE,
940 last_updated_by = FND_GLOBAL.user_id
941 WHERE line_location_id = l_lltab(i).line_location_id;
942
943 IF l_release_id IS NULL THEN
944 l_doc_type := 'PO';
945 l_doc_subtype := 'STANDARD';
946 ELSE
947 l_doc_type := 'RELEASE';
948 l_doc_subtype := 'BLANKET';
949 END IF;
950 IF l_closed_code IS NOT NULL THEN
951 ITG_Debug.msg('PI', 'Close po called ...');
952 ITG_Debug.msg('PI', 'po_id', g_po_id);
953 ITG_Debug.msg('PI', 'doc_type', l_doc_type);
954 ITG_Debug.msg('PI', 'po_line_id', l_rec.po_line_id);
955 ITG_Debug.msg('PI', 'line_location_id',
956 l_lltab(i).line_location_id);
957 ITG_Debug.msg('PI', 'closed_code', l_closed_code);
958
959 /*Added following if <cond> and else part to fix bug :5258514 */
960 IF p_release_id IS NULL or p_release_id =0 THEN
961
962 IF NOT PO_ACTIONS.close_po(
963 p_docID => g_po_id,
964 p_doctyp => l_doc_type,
965 p_docsubtyp => l_doc_subtype,
966 p_lineid => l_rec.po_line_id,
967 p_shipid => l_lltab(i).line_location_id,
968 p_action => l_closed_code,
969 p_calling_mode => 'AP',
970 p_return_code => l_return_code,
971 p_auto_close => 'Y'
972 ) THEN
973 ITG_Debug.msg('PI', 'Close PO failed ...');
974 ITG_Debug.msg('PI', 'return_code', l_return_code);
975 ITG_MSG.invoice_closepo_fail(l_return_code);
976 RAISE FND_API.G_EXC_ERROR;
977 ELSE
978 ITG_Debug.msg('PI', 'Close PO succeded');
979 ITG_Debug.msg('PI', 'return_code', l_return_code);
980 END IF;
981 ELSE
982 IF NOT PO_ACTIONS.close_po(
983 p_docID => l_release_id,
984 p_doctyp => l_doc_type,
985 p_docsubtyp => l_doc_subtype,
986 p_lineid => l_rec.po_line_id,
987 p_shipid => l_lltab(i).line_location_id,
988 p_action => l_closed_code,
989 p_calling_mode => 'AP',
990 p_return_code => l_return_code,
991 p_auto_close => 'Y'
992 ) THEN
993 ITG_Debug.msg('PI', 'Close Release failed ...');
994 ITG_Debug.msg('PI', 'return_code', l_return_code);
995 ITG_MSG.invoice_closerelease_fail(l_return_code);
996 RAISE FND_API.G_EXC_ERROR;
997 ELSE
998 ITG_Debug.msg('PI', 'Close Release succeded');
999 ITG_Debug.msg('PI', 'return_code', l_return_code);
1000 END IF;
1001
1002 END IF; --end p_release_id block
1003
1004 END IF ;--end l_closed_code block
1005 END LOOP;
1006 END IF;
1007 END process_invoice_doc;
1008
1009 BEGIN
1010 /* Initialize return status */
1011 x_return_status := FND_API.G_RET_STS_SUCCESS;
1012 g_action :='updating PO line';
1013
1014 BEGIN
1015 SAVEPOINT Update_PoLine_PVT;
1016
1017 BEGIN
1018 FND_Client_Info.set_org_context(p_org_id); /*bug 4073707*/
1019 MO_GLOBAL.set_policy_context('S', p_org_id); -- MOAC
1020 EXCEPTION
1021 WHEN OTHERS THEN
1022 itg_msg.invalid_org(p_org_id);
1023 RAISE FND_API.G_EXC_ERROR;
1024 END;
1025
1026 ITG_Debug.setup(
1027 p_reset => TRUE,
1028 p_pkg_name => G_PKG_NAME,
1029 p_proc_name => l_api_name);
1030
1031 --now in wrapper, FND_MSG_PUB.Initialize;
1032
1033 ITG_Debug.msg('UPL', 'Top of procedure.');
1034
1035 /* Setup header id: g_po_id */
1036 lookup_po_header(p_po_code, p_org_id,p_release_id,l_doc_typ);
1037
1038 IF p_release_id = 0 THEN
1039 l_release_id := NULL;
1040 IF l_doc_typ = 'BLANKET' THEN
1041 -- Release no is a must for blanket PO
1042 itg_debug.msg('UPL','No po line found.');
1043 itg_msg.no_po_line(p_org_id,p_po_code || ':' ||p_release_id,p_line_num);
1044 RAISE FND_API.G_EXC_ERROR;
1045 END IF;
1046 ELSE
1047 OPEN po_relid_csr(g_po_id,p_org_id,p_release_id);
1048 FETCH po_relid_csr INTO l_release_id;
1049 l_notfound := po_relid_csr%NOTFOUND;
1050 IF l_notfound THEN
1051 itg_debug.msg('UPL','No po line found.');
1052 itg_msg.no_po_line(p_org_id,p_po_code || ':' ||p_release_id,p_line_num);
1053 RAISE FND_API.G_EXC_ERROR;
1054 END IF;
1055 END IF;
1056
1057 OPEN po_line_csr;
1058 FETCH po_line_csr INTO l_rec;
1059 l_notfound := po_line_csr%NOTFOUND;
1060 CLOSE po_line_csr;
1061 IF l_notfound THEN
1062 ITG_Debug.msg('UPL', 'No po line found.');
1063 itg_msg.no_po_line(p_org_id,p_po_code || ':' ||p_release_id,p_line_num);
1064 RAISE FND_API.G_EXC_ERROR;
1065 END IF;
1066
1067 ITG_Debug.msg('UPL', 'PO Code', p_po_code);
1068 ITG_Debug.msg('UPL', 'Org ID', p_org_id);
1069 ITG_Debug.msg('UPL', 'PO ID', g_po_id);
1070 ITG_Debug.msg('UPL', 'Release ID', l_release_id);
1071 ITG_Debug.msg('UPL', 'PO Line Num', p_line_num);
1072 ITG_Debug.msg('UPL', 'PO Line ID', l_rec.po_line_id);
1073 ITG_Debug.msg('UPL', 'Closed Code', l_rec.closed_code);
1074 ITG_Debug.msg('UPL', 'PO Line Doctype', p_doc_type);
1075 ITG_Debug.msg('UPL', 'PO Line Quantity', p_quantity);
1076 ITG_Debug.msg('UPL', 'PO Line Amount', p_amount);
1077
1078 IF l_rec.closed_code = 'FINALLY CLOSED' THEN
1079 ITG_MSG.poline_closed_final;
1080 RAISE FND_API.G_EXC_ERROR;
1081 END IF;
1082
1083 IF upper(p_doc_type) = 'RECEIPT' THEN
1084 process_receipt_doc;
1085 ELSIF upper(p_doc_type) = 'INSPECTION' THEN
1086 process_inspection_doc;
1087 ELSIF upper(p_doc_type) = 'INVOICE' THEN
1088 process_invoice_doc;
1089 ELSE
1090 ITG_MSG.poline_invalid_doctype;
1091 RAISE FND_API.G_EXC_ERROR;
1092 END IF;
1093
1094 COMMIT WORK;
1095 ITG_Debug.msg('UPL', 'Done.');
1096
1097 EXCEPTION
1098 WHEN FND_API.G_EXC_ERROR THEN
1099 ROLLBACK TO Update_PoLine_PVT;
1100 x_return_status := FND_API.G_RET_STS_ERROR;
1101 ITG_msg.checked_error(g_action);
1102
1103
1104 WHEN OTHERS THEN
1105 ROLLBACK TO Update_PoLine_PVT;
1106 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1107 itg_debug.msg('Unexpected error (PO sync) - ' || substr(SQLERRM,1,255),true);
1108 ITG_msg.unexpected_error(g_action);
1109 END;
1110
1111 -- Removed FND_MSG_PUB.Count_And_Get
1112 END Update_PoLine;
1113
1114 END ITG_SyncPoInbound_PVT;