1 PACKAGE BODY GMICUOM AS
2 /* $Header: gmicuomb.pls 115.17 2003/04/07 22:15:57 adeshmuk ship $ */
3 /* =============================================
4 PROCEDURE:
5 icuomcv
6
7 DESCRIPTION:
8 This PL/SQL procedure is responsible for
9 calling the unit of measure function contained
10 in this package and handling all error messaging
11 centrally.
12
13 SYNOPSIS:
14 GMICUOM.icuomcv(pitem_id, plot_id, pcur_qty,
15 pcur_uom, pnew_uom);
16
17 ============================================= */
18 PROCEDURE icuomcv(pitem_id NUMBER,
19 plot_id NUMBER,
20 pcur_qty NUMBER,
21 pcur_uom VARCHAR2,
22 pnew_uom VARCHAR2,
23 onew_qty OUT NOCOPY NUMBER) IS
24
25 /* Local variable initialization and
26 declarations.
27 ================================= */
28 l_iret NUMBER := -1;
29 l_atomic NUMBER := 0;
30 l_neg_flag NUMBER := 0;
31 l_cur_qty NUMBER := 0;
32
33 BEGIN
34
35 IF(pcur_qty < 0) THEN
36 l_cur_qty := (pcur_qty * -1);
37 l_neg_flag := 1;
38 ELSE
39 l_cur_qty := pcur_qty;
40 END IF;
41
42 l_iret := GMICUOM.uom_conversion(pitem_id,
43 plot_id, l_cur_qty, pcur_uom, pnew_uom,
44 l_atomic);
45
46 IF(l_iret >= 0) THEN
47 IF(l_neg_flag = 1) THEN
48 onew_qty := (l_iret * -1);
49 ELSE
50 onew_qty := l_iret;
51 END IF;
52 ELSIF (l_iret = -1) THEN
53 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_PACKAGE_ERR');
54 APP_EXCEPTION.raise_exception;
55
56 ELSIF (l_iret = -3) THEN
57 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_CURUMTYPE_ERR');
58 APP_EXCEPTION.raise_exception;
59
60 ELSIF (l_iret = -4) THEN
61 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_NEWUMTYPE_ERR');
62 APP_EXCEPTION.raise_exception;
63
64 ELSIF (l_iret = -5) THEN
65 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_INVUOMTYPE_ERR2');
66 FND_MESSAGE.set_token('FROMUOM',pcur_uom);
67 FND_MESSAGE.set_token('TOUOM',pnew_uom);
68 APP_EXCEPTION.raise_exception;
69
70 ELSIF (l_iret = -6) THEN
71 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_INVUMTYPE_ERR');
72 APP_EXCEPTION.raise_exception;
73
74 ELSIF (l_iret = -7) THEN
75 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_CURFACTOR_ERR');
76 APP_EXCEPTION.raise_exception;
77
78 ELSIF (l_iret = -10) THEN
79 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_INVUOMTYPE_ERR2');
80 FND_MESSAGE.set_token('FROMUOM',pcur_uom);
81 FND_MESSAGE.set_token('TOUOM',pnew_uom);
82 APP_EXCEPTION.raise_exception;
83
84 ELSIF (l_iret = -11) THEN
85 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_NOITEMID_ERR');
86 APP_EXCEPTION.raise_exception;
87
88 ELSIF (l_iret < -11) THEN
89 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_FATAL_ERR');
90 APP_EXCEPTION.raise_exception;
91
92 END IF;
93
94 END icuomcv;
95 /* =============================================
96 PROCEDURE:
97 icuomcvl LAB MGT ONLY!
98
99 DESCRIPTION:
100 This PL/SQL procedure is responsible for
101 calling the unit of measure function contained
102 in this package and handling all error messaging
103 centrally.
104
105 SYNOPSIS:
106 GMICUOM.icuomcvl(pitem_id, plot_id, pcur_qty,
107 pcur_uom, pnew_uom, pnew_qty,
108 plab_type, pcnv_factor);
109
110 ================================================
111 WJ Harris III 19-NOV-98 R11.0 resynch
112 Modified function uom_conversion for LAB.
113 Modified procedure icuomcvl for LAB.
114 Added parameter pcnv_factor to both to comply
115 with Sierra Atlantic changes for Laboratory Mgt.
116 ============================================= */
117 PROCEDURE icuomcvl(pitem_id NUMBER,
118 pformula_id NUMBER,
119 pcur_qty NUMBER,
120 pcur_uom VARCHAR2,
121 pnew_uom VARCHAR2,
122 plab_type VARCHAR2,
123 pcnv_factor NUMBER,
124 onew_qty OUT NOCOPY NUMBER) IS
125
126 /* Local variable initialization and
127 declarations.
128 ================================= */
129 l_iret NUMBER := -1;
130 l_atomic NUMBER := 0;
131 l_neg_flag NUMBER := 0;
132 l_cur_qty NUMBER := 0;
133
134 BEGIN
135
136 IF(pcur_qty < 0) THEN
137 l_cur_qty := (pcur_qty * -1);
138 l_neg_flag := 1;
139 ELSE
140 l_cur_qty := pcur_qty;
141 END IF;
142
143 l_iret := GMICUOM.uom_conversion(pitem_id,
144 pformula_id, l_cur_qty, pcur_uom, pnew_uom,
145 l_atomic, plab_type, pcnv_factor);
146
147 IF(l_iret >= 0) THEN
148 IF(l_neg_flag = 1) THEN
149 onew_qty := (l_iret * -1);
150 ELSE
151 onew_qty := l_iret;
152 END IF;
153 ELSIF (l_iret = -1) THEN
154 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_PACKAGE_ERR');
155 APP_EXCEPTION.raise_exception;
156
157 ELSIF (l_iret = -2) THEN
158 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_LABTYPE_ERR');
159 APP_EXCEPTION.raise_exception;
160
161 ELSIF (l_iret = -3) THEN
162 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_CURUMTYPE_ERR');
163 APP_EXCEPTION.raise_exception;
164
165 ELSIF (l_iret = -4) THEN
166 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_NEWUMTYPE_ERR');
167 APP_EXCEPTION.raise_exception;
168
169 ELSIF (l_iret = -5) THEN
170 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_INVUOMTYPE_ERR');
171 APP_EXCEPTION.raise_exception;
172
173 ELSIF (l_iret = -6) THEN
174 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_INVUMTYPE_ERR');
175 APP_EXCEPTION.raise_exception;
176
177 ELSIF (l_iret = -7) THEN
178 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_CURFACTOR_ERR');
179 APP_EXCEPTION.raise_exception;
180
181 ELSIF (l_iret = -8) THEN
182 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_LMDENSITY_ERR');
183 APP_EXCEPTION.raise_exception;
184
185 ELSIF (l_iret = -9) THEN
186 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_LABFACTOR_ERR');
187 APP_EXCEPTION.raise_exception;
188
189 ELSIF (l_iret = -10) THEN
190 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_INVUOMTYPE_ERR2');
191 FND_MESSAGE.set_token('FROMUOM',pcur_uom);
192 FND_MESSAGE.set_token('TOUOM',pnew_uom);
193 APP_EXCEPTION.raise_exception;
194
195 ELSIF (l_iret = -11) THEN
196 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_NOITEMID_ERR');
197 APP_EXCEPTION.raise_exception;
198
199 ELSIF (l_iret < -11) THEN
200 FND_MESSAGE.set_name('GMI', 'IC_UOMCV_FATAL_ERR');
201 APP_EXCEPTION.raise_exception;
202
203 END IF;
204
205 END icuomcvl;
206 /* =============================================
207 FUNCTION:
208 uom_conversion OVERLOADED FUNCTION!
209
210 DESCRIPTION:
211 This PL/SQL function is responsible for
212 calculating and returning the converted
213 quantity of an item in the unit of measure
214 specified.
215
216 The uom_conversion function ASSUMES POSITIVE NUMBERS ONLY!
217 ALL CALLERS MUST DEAL WITH NEGATIVE NUMBERS PRIOR TO
218 CALLING THIS FUNCTION!
219
220 PARAMETERS:
221 pitem_id The surrogate key of the item number
222
223 plot_id The surrogate key for the lot number/
224 sublot of the item number being converted.
225 ALLOWS ZERO if performing a LAB conversion.
226
227 pcur_qty The current quantity to convert.
228
229 pcur_uom The current unit of measure to convert from.
230
231 pnew_uom The unit of measure to convert to.
232
233 patomic Flag to determine if decimal percision is
234 required as part of the conversion.
235 0 = No, provide full precision.
236 1 = Yes, provide integer ONLY!
237
238 SPECIAL NOTES:
239
240 RETURNS:
241 >=0 - SUCCESS
242 -1 - Package problem.
243 -3 - UM_TYPE and conversion factor for current UOM not found.
244 -4 - UM_TYPE and conversion factor for NEW UOM not found.
245 -5 - Cannot determine INVENTORY UOM for item.
246 -6 - UM_TYPE and conversion factor for INV UOM not found.
247 -7 - Cannot find conversion factor for CURRENT UOM.
248 -10 - Cannot find conversion factor for NEW UOM.
249 -11 - Item_id not passed as a parameter.
250
251 HISTORY
252 Jalaj Srivastava Bug 1713699 05-APR-2001
253 Apps provides item specific intra class conversion.
254 we need to use them if it exists for a item.
255
256 G. Muratore Bug 2236392 15-APR-2002
257 Rounding problem corrected by changing the order of operations
258 in uom_conversion. The code no longer derives the factor and
259 then applies. It does the full calculation in one step.
260
261 A. Mundhe Bug 2844068 07-APR-2003
262 Modified the uom_conversion function to use more - precise type
263 factor or type factorrev and to calculate the new qty accordingly.
264 ============================================================== */
265 FUNCTION uom_conversion(pitem_id NUMBER,
266 plot_id NUMBER,
267 pcur_qty NUMBER ,
268 pcur_uom VARCHAR2,
269 pnew_uom VARCHAR2,
270 patomic NUMBER)
271 RETURN NUMBER IS
272 /* Variable Declarations
273 ===================== */
274 l_item_invum_code uomcode_type;
275 l_cur_uom_code uomcode_type;
276 l_new_uom_code uomcode_type;
277 l_cur_um_type sy_uoms_typ.um_type%TYPE;
278 l_new_um_type sy_uoms_typ.um_type%TYPE;
279 l_inv_um_type sy_uoms_typ.um_type%TYPE;
280 l_cur_uom_factor ic_item_cnv.type_factor%TYPE;
281 l_cur_conv_factor ic_item_cnv.type_factor%TYPE;
282 l_cur_conv_factorrev ic_item_cnv.type_factor%TYPE; /* Bug 2844068 */
283 l_new_uom_factor ic_item_cnv.type_factor%TYPE;
284 l_new_conv_factor ic_item_cnv.type_factor%TYPE;
285 l_new_conv_factorrev ic_item_cnv.type_factor%TYPE; /* Bug 2844068 */
286 l_inv_uom_factor ic_item_cnv.type_factor%TYPE;
287 l_lab_conv_factor lm_item_dat.num_data%TYPE;
288 l_parm_name lm_item_dat.tech_parm_name%TYPE;
289 l_factor NUMBER;
290 l_new_qty NUMBER;
291 l_item_no ic_item_mst.item_no%type;
292 l_inventory_item_id mtl_system_items.inventory_item_id%type;
293 var1 NUMBER;
294
295 /* Bug 2844068 */
296 l_factor_len NUMBER;
297 l_factorrev_len NUMBER;
298
299 /* Cursor Definitions
300 ==================*/
301 CURSOR get_uom_type(Vum_code uomcode_type,
302 Vinventory_item_id mtl_system_items.inventory_item_id%type) IS
303 SELECT 1, uomc.uom_class um_type, uomc.conversion_rate std_factor
304 FROM mtl_uom_conversions uomc, mtl_units_of_measure uom, sy_uoms_mst sy
305 WHERE sy.um_code = Vum_code
306 AND uom.unit_of_measure = sy.unit_of_measure
307 AND uomc.uom_code = uom.uom_code
308 AND uomc.inventory_item_id = Vinventory_item_id
309 AND ( (uomc.disable_date IS NULL)
310 OR (uomc.disable_date > sysdate) )
311 UNION
312 SELECT 2, um_type, std_factor
313 FROM sy_uoms_mst
314 WHERE um_code = Vum_code
315 AND delete_mark = 0
316 ORDER by 1;
317
318
319 CURSOR get_inv_uom(v_item_id itm_surg_type) IS
320 SELECT item_um
321 FROM ic_item_mst
322 WHERE item_id = v_item_id;
323
324 /* Bug 2844068 */
325 /* Added type_factorrev to the query */
326 CURSOR get_conversion_factor(v_item_id itm_surg_type,
327 v_lot_id lot_surg_type,
328 v_um_type sy_uoms_typ.um_type%TYPE) IS
329 SELECT type_factor, type_factorrev
330 FROM ic_item_cnv
331 WHERE item_id = v_item_id
332 AND lot_id = v_lot_id
333 AND delete_mark = 0
334 AND um_type = v_um_type;
335
336 CURSOR get_item_no (Vitem_id ic_item_mst.item_id%type) IS
337 SELECT item_no
338 FROM ic_item_mst
339 WHERE item_id = Vitem_id;
340
341 CURSOR get_inventory_item_id(Vitem_no ic_item_mst.item_no%type) IS
342 SELECT inventory_item_id
343 FROM mtl_system_items
344 WHERE segment1= Vitem_no
345 AND rownum = 1;
346 /* ================================================*/
347 BEGIN
348
349 l_cur_uom_code := pcur_uom;
350 l_new_uom_code := pnew_uom;
351 l_item_invum_code := NULL;
352 l_cur_um_type := NULL;
353 l_new_um_type := NULL;
354 l_inv_um_type := NULL;
355 l_cur_uom_factor := 0;
356 l_cur_conv_factor := 0;
357 l_cur_conv_factorrev := 0; /* Bug 2844068 */
358 l_new_uom_factor := 0;
359 l_new_conv_factor := 0;
360 l_new_conv_factorrev := 0; /* Bug 2844068 */
361 l_inv_uom_factor := 0;
362 l_factor := 0;
363 l_new_qty := 0;
364
365 /* ===================================
366 ENFORCE PARAMETER LAWS!
367 ===================================*/
368 IF(pitem_id IS NULL) THEN
369 RETURN UOM_NOITEM_ERR;
370 END IF;
371
372 /* ===================================
373 OK ... if the passed units of
374 measure are the same, then there is
375 nothing to do!
376 ===================================*/
377 IF(pcur_uom = pnew_uom) THEN
378 l_new_qty := pcur_qty;
379 RETURN l_new_qty;
380 END IF;
381 /*====================================
382 Jalaj Srivastava Bug 1713699
383 We need opm item no and inventory item
384 id in order to get specific
385 item conversions.
386 ===================================*/
387 OPEN get_item_no(pitem_id);
388 FETCH get_item_no INTO l_item_no;
389 CLOSE get_item_no;
390
391 OPEN get_inventory_item_id(l_item_no);
392 FETCH get_inventory_item_id INTO l_inventory_item_id;
393 CLOSE get_inventory_item_id;
394
395 /* ===================================
396 Step One - determine the um_type
397 and standard factor for the current
398 unit of measure.
399 ===================================*/
400 OPEN get_uom_type(l_cur_uom_code, l_inventory_item_id);
401 FETCH get_uom_type INTO
402 var1, l_cur_um_type, l_cur_uom_factor;
403
404 IF(get_uom_type%NOTFOUND) THEN
405
406 CLOSE get_uom_type;
407 RETURN UOM_CUR_UOMTYPE_ERR;
408 END IF;
409
410
411 CLOSE get_uom_type;
412
413 /* ==================================
414 Step TWO - determine the um_type
415 and standard factor for the new
416 unit of measure.
417 ==================================*/
418 OPEN get_uom_type(l_new_uom_code, l_inventory_item_id);
419 FETCH get_uom_type INTO
420 var1, l_new_um_type, l_new_uom_factor;
421
422 IF(get_uom_type%NOTFOUND) THEN
423
424 CLOSE get_uom_type;
425 RETURN UOM_NEW_UOMTYPE_ERR;
426 END IF;
427
428
429 CLOSE get_uom_type;
430
431 /* =========================================
432 Step Three - If the unit of measure types
433 are the SAME, perform calculation cause
434 we are done!
435 ========================================= */
436 /*
437 IF(l_cur_um_type = l_new_um_type) THEN
438 l_factor := (l_cur_uom_factor / l_new_uom_factor);
439 IF(patomic = 1) THEN
440 l_new_qty := ROUND(pcur_qty * l_factor);
441 ELSE
442 l_new_qty := (pcur_qty * l_factor);
443 END IF;
444
445 RETURN l_new_qty;
446 END IF;
447 */
448
449 /* Bug 2236392 Rounding problem corrected by
450 changing the order of operations in uom_conversion.
451 Old code commented out above. */
452 IF(l_cur_um_type = l_new_um_type) THEN
453 l_new_qty := (pcur_qty * l_cur_uom_factor / l_new_uom_factor);
454
455 IF(patomic = 1) THEN
456 l_new_qty := ROUND(l_new_qty);
457 END IF;
458
459 RETURN l_new_qty;
460 END IF;
461
462
463 /* =========================================
464 Step Four - If the unit of measure types
465 are NOT THE SAME, get the item's inventory
466 uom type an conversion factor.
467 ========================================= */
468 IF(l_cur_um_type <> l_new_um_type) THEN
469 OPEN get_inv_uom(pitem_id);
470 FETCH get_inv_uom INTO
471 l_item_invum_code;
472
473 IF(get_inv_uom%NOTFOUND) THEN
474
475 CLOSE get_inv_uom;
476 RETURN UOM_INVUOM_ERR;
477 END IF;
478 CLOSE get_inv_uom;
479
480 OPEN get_uom_type(l_item_invum_code, l_inventory_item_id);
481 FETCH get_uom_type INTO
482 var1, l_inv_um_type, l_inv_uom_factor;
483
484 IF(get_uom_type%NOTFOUND) THEN
485
486 CLOSE get_uom_type;
487 RETURN UOM_INV_UOMTYPE_ERR;
488 END IF;
489
490 CLOSE get_uom_type;
491
492 END IF;
493
494 /* ==============================================
495 Step FIVE - If the uom types for the current
496 and the inventory uoms are NOT THE SAME,
497 we need the CONVERSION factors for both the
498 current and new uoms so that we can convert
499 to the items primary uom.
500 ============================================== */
501
502 /* Bug 2844068 */
503 /* Fetch type_factorrev from the cursor */
504 IF(l_cur_um_type <> l_inv_um_type) THEN
505 OPEN get_conversion_factor(pitem_id, plot_id, l_cur_um_type);
506 FETCH get_conversion_factor INTO
507 l_cur_conv_factor, l_cur_conv_factorrev;
508
509 IF(get_conversion_factor%NOTFOUND) THEN
510 /* =======================================
511 We have to check for an ITEM SPECIFIC
512 conversion factor if one does not exist
513 for the lot.
514 ======================================= */
515 CLOSE get_conversion_factor;
516
517 /* Bug 2844068 */
518 /* Fetch type_factorrev from the cursor */
519 OPEN get_conversion_factor(pitem_id, default_lot,
520 l_cur_um_type);
521 FETCH get_conversion_factor INTO
522 l_cur_conv_factor, l_cur_conv_factorrev;
523
524 IF(get_conversion_factor%NOTFOUND) THEN
525 CLOSE get_conversion_factor;
526 RETURN UOM_CUR_CONV_ERR;
527 END IF;
528 END IF;
529 CLOSE get_conversion_factor;
530 ELSIF(l_cur_um_type = l_inv_um_type) THEN
531 l_cur_conv_factor := cur_factor_default;
532 /* Bug 2844068 */
533 l_cur_conv_factorrev := cur_factor_default;
534 END IF;
535
536 /* ==============================================
537 Step SEVEN - If the uom types are NOT THE SAME,
538 we need the CONVERSION factors for both the
539 current and new uoms so that we can convert
540 to the items primary uom.
541 ==============================================*/
542
543 IF(l_inv_um_type <> l_new_um_type) THEN
544 /* Bug 2844068 */
545 /* Fetch type_factorrev from the cursor */
546 OPEN get_conversion_factor(pitem_id, plot_id, l_new_um_type);
547 FETCH get_conversion_factor INTO
548 l_new_conv_factor, l_new_conv_factorrev;
549
550 IF(get_conversion_factor%NOTFOUND) THEN
551 /* =======================================
552 We have to check for an ITEM SPECIFIC
553 conversion factor if one does not exist
554 for the lot.
555 =======================================*/
556 CLOSE get_conversion_factor;
557
558 OPEN get_conversion_factor(pitem_id, default_lot,
559 l_new_um_type);
560 /* Bug 2844068 */
561 /* Fetch type_factorrev from the cursor */
562 FETCH get_conversion_factor INTO
563 l_new_conv_factor, l_new_conv_factorrev;
564
565 IF(get_conversion_factor%NOTFOUND) THEN
566 CLOSE get_conversion_factor;
567 RETURN UOM_NEW_CONV_ERR;
568 END IF;
569 END IF;
570 CLOSE get_conversion_factor;
571
572 ELSIF(l_inv_um_type = l_new_um_type) THEN
573 l_new_conv_factor := new_factor_default;
574 /* Bug 2844068 */
575 l_new_conv_factorrev := new_factor_default;
576 END IF;
577
578 /* ======================================
579 Conversion Please .... Thank you very
580 much!!!
581 ======================================*/
582 /*
583 l_factor := ((l_cur_uom_factor * l_cur_conv_factor) /
584 (l_new_uom_factor * l_new_conv_factor));
585 IF(patomic = 1) THEN
586 l_new_qty := ROUND(pcur_qty * l_factor);
587 ELSE
588 l_new_qty := (pcur_qty * l_factor);
589 END IF;
590
591 RETURN l_new_qty;
592 */
593
594 /* Bug 2236392 Rounding problem corrected by
595 changing the order of operations in uom_conversion.
596 Old code commented out above. */
597
598 /* Bug 2844068 */
599 /* Calculate the number of decimal places in type factor and type factorrev.
600 Use the factor with less number of decimal places and calcualte the new qty
601 accordingly. */
602
603 l_factor_len := length(TO_CHAR(l_new_conv_factor - floor(l_new_conv_factor)))-1;
604 l_factorrev_len := length(TO_CHAR(l_new_conv_factorrev - floor(l_new_conv_factorrev)))-1;
605
606 IF (l_factor_len < l_factorrev_len) THEN
607 l_new_qty := ((pcur_qty * l_cur_uom_factor * l_cur_conv_factor) /
608 (l_new_uom_factor * l_new_conv_factor));
609 ELSE
610 l_new_qty := ((pcur_qty * l_cur_uom_factor * l_cur_conv_factor * l_new_conv_factorrev) /
611 (l_new_uom_factor));
612 END IF;
613
614 IF(patomic = 1) THEN
615 l_new_qty := ROUND(l_new_qty);
616 END IF;
617
618 RETURN l_new_qty;
619
620 EXCEPTION
621 WHEN OTHERS THEN
622
623 RETURN SQLCODE;
624 END uom_conversion;
625 /* =============================================
626 FUNCTION:
627 uom_conversion OVERLOADED FUNCTION
628 LAB ONLY!
629
630 DESCRIPTION:
631 This PL/SQL function is responsible for
632 calculating and returning the converted
633 quantity of an item in the unit of measure
634 specified.
635
636 The uom_conversion function ASSUMES POSITIVE NUMBERS ONLY!
637 ALL CALLERS MUST DEAL WITH NEGATIVE NUMBERS PRIOR TO
638 CALLING THIS FUNCTION!
639
640 PARAMETERS:
641 pitem_id The surrogate key of the item number
642
643 pformula_id The surrogate key for the formula/version
644 being converted. ALLOWS ZERO if performing
645 a regular conversion. FOR LAB MGT ONLY!
646
647 pcur_qty The current quantity to convert.
648
649 pcur_uom The current unit of measure to convert from.
650
651 pnew_uom The unit of measure to convert to.
652
653 patomic Flag to determine if decimal percision is
654 required as part of the conversion.
655 0 = No, provide full precision.
656 1 = Yes, provide integer ONLY!
657
658 plab_type The technical parameter group name.
659 IT IS REQUIRED.
660
661 pcnv_factor Conversion factor for density passed
662 by the user. NOT REQUIRED!
663
664 SPECIAL NOTES:
665 Added new parameter pcnv_factor to coincide with
666 Sierra Atlantic changes for lab UOM conversions. This
667 allows the user to perform conversions based on user
668 entry for the value of conversion factor instead of
669 getting the value from the database.
670
671 RETURNS:
672 >=0 - SUCCESS
673 -1 - Package problem.
674 -2 - Lab Type not passed for LAB conversion.
675 -3 - UM_TYPE and conversion factor for current UOM not found.
676 -4 - UM_TYPE and conversion factor for NEW UOM not found.
677 -5 - Cannot determine INVENTORY UOM for item.
678 -6 - UM_TYPE and conversion factor for INV UOM not found.
679 -7 - Cannot find conversion factor for CURRENT UOM.
680 -8 - LAB CONVERSION - LM$DENSITY variable not found.
681 -9 - LAB CONVERSION - conversion factor not found.
682 -10 - Cannot find conversion factor for NEW UOM.
683 -11 - Item_id not passed as a parameter.
684
685 HISTORY:
686 WJ Harris III 19-NOV-98 resynch
687 Added pcnv_factor parameter for laboratory management to
688 coincide with Sierra Atlantic modifications approved by
689 Karen Theel. These were not communicated or approved by
690 anyone else.
691 Jalaj Srivastava Bug 1713699 05-APR-2001
692 Apps provides item specific intra class conversion.
693 we need to use them if it exists for a item.
694
695 G. Muratore Bug 2236392 15-APR-2002
696 Rounding problem corrected by changing the order of operations
697 in uom_conversion. The code no longer derives the factor and
698 then applies. It does the full calculation in one step.
699
700 ============================================================== */
701 FUNCTION uom_conversion(pitem_id NUMBER,
702 pformula_id NUMBER,
703 pcur_qty NUMBER,
704 pcur_uom VARCHAR2,
705 pnew_uom VARCHAR2,
706 patomic NUMBER,
707 plab_type VARCHAR2,
708 pcnv_factor NUMBER DEFAULT 0)
709 RETURN NUMBER IS
710 /* Variable Declarations
711 =====================*/
712 l_item_invum_code uomcode_type;
713 l_cur_uom_code uomcode_type;
714 l_new_uom_code uomcode_type;
715 l_cur_um_type sy_uoms_typ.um_type%TYPE;
716 l_new_um_type sy_uoms_typ.um_type%TYPE;
717 l_inv_um_type sy_uoms_typ.um_type%TYPE;
718 l_cur_uom_factor ic_item_cnv.type_factor%TYPE;
719 l_cur_conv_factor ic_item_cnv.type_factor%TYPE;
720 l_new_uom_factor ic_item_cnv.type_factor%TYPE;
721 l_new_conv_factor ic_item_cnv.type_factor%TYPE;
722 l_inv_uom_factor ic_item_cnv.type_factor%TYPE;
723 l_lab_conv_factor lm_item_dat.num_data%TYPE;
724 l_parm_name lm_item_dat.tech_parm_name%TYPE;
725 l_factor NUMBER;
726 l_new_qty NUMBER;
727 l_item_no ic_item_mst.item_no%type;
728 l_inventory_item_id mtl_system_items.inventory_item_id%type;
729 var1 NUMBER;
730
731 /* Cursor Definitions
732 ==================*/
733 CURSOR get_uom_type(Vum_code uomcode_type,
734 Vinventory_item_id mtl_system_items.inventory_item_id%type) IS
735 SELECT 1, uomc.uom_class um_type, uomc.conversion_rate std_factor
736 FROM mtl_uom_conversions uomc, mtl_units_of_measure uom, sy_uoms_mst sy
737 WHERE sy.um_code = Vum_code
738 AND uom.unit_of_measure = sy.unit_of_measure
739 AND uomc.uom_code = uom.uom_code
740 AND uomc.inventory_item_id = Vinventory_item_id
741 UNION
742 SELECT 2, um_type, std_factor
743 FROM sy_uoms_mst
744 WHERE um_code = Vum_code
745 AND delete_mark = 0
746 ORDER by 1;
747
748 CURSOR get_inv_uom(v_item_id itm_surg_type) IS
749 SELECT item_um
750 FROM ic_item_mst
751 WHERE item_id = v_item_id;
752
753 CURSOR get_conversion_factor(v_item_id itm_surg_type,
754 v_lot_id lot_surg_type,
755 v_um_type sy_uoms_typ.um_type%TYPE) IS
756 SELECT type_factor
757 FROM ic_item_cnv
758 WHERE item_id = v_item_id
759 AND lot_id = v_lot_id
760 AND delete_mark = 0
761 AND um_type = v_um_type;
762
763 CURSOR get_lab_conv_factor(v_lab_type lab_type,
764 v_item_id itm_surg_type,
765 v_formula_id form_surg_type,
766 v_parm_name lm_item_dat.tech_parm_name%TYPE) IS
767 SELECT num_data
768 FROM lm_item_dat
769 WHERE orgn_code = v_lab_type
770 AND item_id = v_item_id
771 AND formula_id = v_formula_id
772 AND tech_parm_name = v_parm_name
773 AND delete_mark = 0;
774
775 CURSOR get_item_no (Vitem_id ic_item_mst.item_id%type) IS
776 SELECT item_no
777 FROM ic_item_mst
778 WHERE item_id = Vitem_id;
779
780 CURSOR get_inventory_item_id(Vitem_no ic_item_mst.item_no%type) IS
781 SELECT inventory_item_id
782 FROM mtl_system_items
783 WHERE segment1= Vitem_no
784 AND rownum = 1;
785
786 /* ================================================*/
787 BEGIN
788
789 l_cur_uom_code := pcur_uom;
790 l_new_uom_code := pnew_uom;
791 l_item_invum_code := NULL;
792 l_cur_um_type := NULL;
793 l_new_um_type := NULL;
794 l_inv_um_type := NULL;
795 l_cur_uom_factor := 0;
796 l_cur_conv_factor := 0;
797 l_new_uom_factor := 0;
798 l_new_conv_factor := 0;
799 l_inv_uom_factor := 0;
800 l_factor := 0;
801 l_new_qty := 0;
802
803 /* ===================================
804 ENFORCE PARAMETER LAWS!
805 ===================================*/
806 IF(pitem_id IS NULL OR pitem_id = 0) THEN
807 RETURN UOM_NOITEM_ERR;
808 END IF;
809
810 IF(plab_type IS NULL) THEN
811 RETURN UOM_LAB_TYPE_ERR;
812 END IF;
813
814 /* First we must get the SYSTEMS density parameter
815 NAME. If we do not have one bail dude .... there
816 is a setup error!
817 =================================================*/
818 l_parm_name := FND_PROFILE.value('LM$DENSITY');
819
820 IF(l_parm_name IS NULL) THEN
821 RETURN UOM_LAB_CONST_ERR;
822 END IF;
823 /* ===================================
824 OK ... if the passed units of
825 measure are the same, then there is
826 nothing to do!
827 ===================================*/
828 IF(pcur_uom = pnew_uom) THEN
829 l_new_qty := pcur_qty;
830 RETURN l_new_qty;
831 END IF;
832
833 /*====================================
834 Jalaj Srivastava Bug 1713699
835 We need to get the item no and
836 inventory item id in order to get
837 specific item conversions.
838 ===================================*/
839 OPEN get_item_no(pitem_id);
840 FETCH get_item_no INTO l_item_no;
841 CLOSE get_item_no;
842
843 OPEN get_inventory_item_id(l_item_no);
844 FETCH get_inventory_item_id INTO l_inventory_item_id;
845 CLOSE get_inventory_item_id;
846
847
848 /* ===================================
849 Step One - determine the um_type
850 and standard factor for the current
851 unit of measure.
852 ===================================*/
853 OPEN get_uom_type(l_cur_uom_code, l_inventory_item_id);
854 FETCH get_uom_type INTO
855 var1, l_cur_um_type, l_cur_uom_factor;
856
857 IF(get_uom_type%NOTFOUND) THEN
858 CLOSE get_uom_type;
859 RETURN UOM_CUR_UOMTYPE_ERR;
860 END IF;
861
862 CLOSE get_uom_type;
863
864 /* ==================================
865 Step TWO - determine the um_type
866 and standard factor for the new
867 unit of measure.
868 ==================================*/
869 OPEN get_uom_type(l_new_uom_code, l_inventory_item_id);
870 FETCH get_uom_type INTO
871 var1, l_new_um_type, l_new_uom_factor;
872
873 IF(get_uom_type%NOTFOUND) THEN
874
875 CLOSE get_uom_type;
876 RETURN UOM_NEW_UOMTYPE_ERR;
877 END IF;
878
879 CLOSE get_uom_type;
880
881 /* =========================================
882 Step Three - If the unit of measure types
883 are the SAME, perform calculation cause
884 we are done!
885 =========================================*/
886 /*
887 IF(l_cur_um_type = l_new_um_type) THEN
888 l_factor := (l_cur_uom_factor / l_new_uom_factor);
889 IF(patomic = 1) THEN
890 l_new_qty := ROUND(pcur_qty * l_factor);
891 ELSE
892 l_new_qty := (pcur_qty * l_factor);
893 END IF;
894
895
896 RETURN l_new_qty;
897 END IF;
898 */
899
900 /* Bug 2236392 Rounding problem corrected by
901 changing the order of operations in uom_conversion.
902 Old code commented out above. */
903 IF(l_cur_um_type = l_new_um_type) THEN
904 l_new_qty := (pcur_qty * l_cur_uom_factor / l_new_uom_factor);
905
906 IF(patomic = 1) THEN
907 l_new_qty := ROUND(l_new_qty);
908 END IF;
909
910 RETURN l_new_qty;
911 END IF;
912
913
914 /* =========================================
915 Step Four - If the unit of measure types
916 are NOT THE SAME, get the item's inventory
917 uom type an conversion factor.
918 =========================================*/
919 IF(l_cur_um_type <> l_new_um_type) THEN
920 OPEN get_inv_uom(pitem_id);
921 FETCH get_inv_uom INTO
922 l_item_invum_code;
923
924 IF(get_inv_uom%NOTFOUND) THEN
925
926 CLOSE get_inv_uom;
927 RETURN UOM_INVUOM_ERR;
928 END IF;
929 CLOSE get_inv_uom;
930
931 OPEN get_uom_type(l_item_invum_code, l_inventory_item_id);
932 FETCH get_uom_type INTO
933 var1, l_inv_um_type, l_inv_uom_factor;
934
935 IF(get_uom_type%NOTFOUND) THEN
936
937 CLOSE get_uom_type;
938 RETURN UOM_INV_UOMTYPE_ERR;
939 END IF;
940
941 CLOSE get_uom_type;
942
943 END IF;
944
945 /* ==============================================
946 Step FIVE - If the uom types for the current
947 and the inventory uoms are NOT THE SAME,
948 we need the CONVERSION factors for both the
949 current and new uoms so that we can convert
950 to the items primary uom.
951 ==============================================*/
952 IF(l_cur_um_type <> l_inv_um_type) THEN
953 /* ===========================================
954 let's get the lab conversion factor
955 shall we ?! If the user has passed a
956 conversion factor to use, then use it.
957 Otherwise ..... lets get it from the database.
958 ==============================================*/
959 IF(pcnv_factor <> 0) THEN
960 l_cur_conv_factor := pcnv_factor;
961 ELSE
962 OPEN get_lab_conv_factor(plab_type, pitem_id, pformula_id,
963 l_parm_name);
964 FETCH get_lab_conv_factor INTO
965 l_cur_conv_factor;
966
967 IF(get_lab_conv_factor%NOTFOUND) THEN
968 CLOSE get_lab_conv_factor;
969 RETURN UOM_LAB_CONV_ERR;
970 END IF;
971 CLOSE get_lab_conv_factor;
972 END IF;
973 ELSIF(l_cur_um_type = l_inv_um_type) THEN
974 l_cur_conv_factor := cur_factor_default;
975 END IF;
976
977 /* ==============================================
978 Step SEVEN - If the uom types are NOT THE SAME,
979 we need the CONVERSION factors for both the
980 current and new uoms so that we can convert
981 to the items primary uom.
982 ==============================================*/
983 IF(l_inv_um_type <> l_new_um_type) THEN
984 /* ===========================================
985 Let's get the lab conversion factor
986 shall we ?! If the user has passed a
987 conversion factor to use, then use it.
988 Otherwise ..... lets get it from the database.
989 ===========================================*/
990 IF(pcnv_factor <> 0) THEN
991 l_new_conv_factor := pcnv_factor;
992 ELSE
993 OPEN get_lab_conv_factor(plab_type, pitem_id, pformula_id,
994 l_parm_name);
995 FETCH get_lab_conv_factor INTO
996 l_new_conv_factor;
997
998 IF(get_lab_conv_factor%NOTFOUND) THEN
999 CLOSE get_lab_conv_factor;
1000 RETURN UOM_LAB_CONV_ERR;
1001 END IF;
1002 CLOSE get_lab_conv_factor;
1003 END IF;
1004 ELSIF(l_inv_um_type = l_new_um_type) THEN
1005 l_new_conv_factor := new_factor_default;
1006 END IF;
1007
1008 /* ======================================
1009 Conversion Please .... Thank you very
1010 much!!!
1011 ======================================*/
1012 /*
1013 l_factor := ((l_cur_uom_factor * l_cur_conv_factor) /
1014 (l_new_uom_factor * l_new_conv_factor));
1015 IF(patomic = 1) THEN
1016 l_new_qty := ROUND(pcur_qty * l_factor);
1017 ELSE
1018 l_new_qty := (pcur_qty * l_factor);
1019 END IF;
1020
1021
1022 RETURN l_new_qty;
1023 */
1024
1025 /* Bug 2236392 Rounding problem corrected by
1026 changing the order of operations in uom_conversion.
1027 Old code commented out above. */
1028 l_new_qty := ((pcur_qty * l_cur_uom_factor * l_cur_conv_factor) /
1029 (l_new_uom_factor * l_new_conv_factor));
1030
1031 IF(patomic = 1) THEN
1032 l_new_qty := ROUND(l_new_qty);
1033 END IF;
1034
1035 RETURN l_new_qty;
1036
1037
1038 EXCEPTION
1039 WHEN OTHERS THEN
1040
1041 RETURN SQLCODE;
1042 END uom_conversion;
1043 /* =============================================
1044 FUNCTION:
1045 i2uom_cv
1046
1047 DESCRIPTION:
1048 This PL/SQL function is responsible for
1049 calculating and returning the converted
1050 quantity of an item in the unit of measure
1051 specified from within a select statement for I2.
1052
1053 PARAMETERS:
1054 pitem_id The surrogate key of the item number
1055
1056 plot_id The surrogate key for the lot number/
1057 sublot of the item number being converted.
1058 ALLOWS ZERO if performing a LAB conversion.
1059
1060 pcur_qty The current quantity to convert.
1061
1062 pcur_uom The current unit of measure to convert from.
1063
1064 pnew_uom The unit of measure to convert to.
1065
1066 SPECIAL NOTES:
1067
1068 RETURNS:
1069 0 - SUCCESS
1070 -1 - Package problem.
1071 -3 - UM_TYPE and conversion factor for current UOM not found.
1072 -4 - UM_TYPE and conversion factor for NEW UOM not found.
1073 -5 - Cannot determine INVENTORY UOM for item.
1074 -6 - UM_TYPE and conversion factor for INV UOM not found.
1075 -7 - Cannot find conversion factor for CURRENT UOM.
1076 -10 - Cannot find conversion factor for NEW UOM.
1077 ============================================================== */
1078 FUNCTION i2uom_cv(pitem_id NUMBER,
1079 plot_id NUMBER,
1080 pcur_uom VARCHAR2,
1081 pcur_qty NUMBER ,
1082 pnew_uom VARCHAR2)
1083 RETURN NUMBER IS
1084
1085 /* Variable Declarations
1086 =====================*/
1087 l_iret NUMBER := -1;
1088 l_atomic NUMBER := 0;
1089
1090 BEGIN
1091
1092 l_iret := GMICUOM.uom_conversion(pitem_id, plot_id,
1093 pcur_qty, pcur_uom, pnew_uom, l_atomic);
1094
1095 IF(l_iret <= 0) THEN
1096 RETURN 0;
1097 ELSE
1098 RETURN l_iret;
1099 END IF;
1100
1101 EXCEPTION
1102 WHEN OTHERS THEN
1103 RETURN SQLCODE;
1104
1105 END i2uom_cv;
1106
1107
1108 END;