DBA Data[Home] [Help]

PACKAGE BODY: APPS.PJM_UNIT_EFF

Source


1 PACKAGE BODY PJM_UNIT_EFF AS
2 /* $Header: PJMUEFFB.pls 120.1.12010000.2 2008/09/17 10:32:53 ybabulal ship $ */
3 --  ---------------------------------------------------------------------
4 --  Global Variables
5 --  ---------------------------------------------------------------------
6 G_Unit_Number   PJM_UNIT_NUMBERS.UNIT_NUMBER%TYPE;
7 G_Enabled       VARCHAR2(1)  := NULL;
8 G_Org_ID        NUMBER       := NULL;
9 G_Item_ID       NUMBER       := NULL;
10 G_Unit_Eff_Item VARCHAR2(1)  := NULL;
11 G_WIP_Entity_ID NUMBER       := NULL;
12 G_WIP_Org_ID    NUMBER       := NULL;
13 G_WIP_Unit_Num  PJM_UNIT_NUMBERS.UNIT_NUMBER%TYPE := NULL;
14 G_RCV_Txn_ID    NUMBER       := NULL;
15 G_RCV_Unit_Num  PJM_UNIT_NUMBERS.UNIT_NUMBER%TYPE := NULL;
16 G_RMA_Txn_ID    NUMBER       := NULL;
17 G_RMA_Unit_Num  PJM_UNIT_NUMBERS.UNIT_NUMBER%TYPE := NULL;
18 G_OE_Line_ID    NUMBER       := NULL;
19 G_OE_Unit_Num   PJM_UNIT_NUMBERS.UNIT_NUMBER%TYPE := NULL;
20 
21 --  ---------------------------------------------------------------------
22 --  Private Functions / Procedures
23 --  ---------------------------------------------------------------------
24 
25 --
26 --  Name          : Item_Serial_Control
27 --  Pre-reqs      : None
28 --  Function      : This function checks the serial control for
29 --                  the item
30 --
31 --
32 --  Parameters    :
33 --  IN            : X_item_id                       NUMBER
34 --                  X_organization_id               NUMBER
35 --
36 --  OUT           : None
37 --
38 --  Returns       : Serial Number Control Code
39 --                  1 - No serial number control
40 --                  2 - Predefined serial numbers
41 --                  5 - Dynamic entry at inventory receipt
42 --                  6 - Dynamic entry at sales order issue
43 --
44 FUNCTION Item_Serial_Control
45 ( X_item_id                        IN     NUMBER
46 , X_organization_id                IN     NUMBER
47 ) RETURN NUMBER IS
48    L_ser_control   NUMBER;
49 BEGIN
50 
51    if ( X_item_id is NULL ) then
52       return ( NULL );
53    end if;
54 
55    SELECT serial_number_control_code
56    INTO   L_ser_control
57    FROM   mtl_system_items
58    WHERE  inventory_item_id = X_item_id
59    AND    organization_id = X_organization_id;
60 
61    return ( L_ser_control );
62 
63 EXCEPTION
64 WHEN NO_DATA_FOUND THEN
65    RETURN ( NULL );
66 WHEN OTHERS THEN
67    RETURN ( NULL );
68 
69 END Item_Serial_Control;
70 
71 
72 --  ---------------------------------------------------------------------
73 --  Public Functions / Procedures
74 --  ---------------------------------------------------------------------
75 
76 --
77 --  Name          : Enabled
78 --  Pre-reqs      : None
79 --  Function      : This function returns a Y/N indicator whether
80 --                  Model/Unit effectivity has been enabled or not
81 --
82 --
83 --  Parameters    :
84 --  IN            : None
85 --
86 --  Returns       : Y/N
87 --
88 FUNCTION Enabled
89   RETURN VARCHAR2 IS
90 
91 BEGIN
92 
93    --
94    -- The result is cached into global variable to speed up repeated
95    -- Initially the cache is NULL.  Once the cache is populated, the
96    -- cached result will be used instead of hitting the DB again.
97    --
98    if ( G_Enabled IS NULL ) then
99      --
100      -- A Law 06/07/2002
101      --
102      -- Check is now based on whether PJM is implemented (existence
103      -- of rows in pjm_org_parameters), not whether PJM is installed
104      --
105      if ( PJM_INSTALL.Check_Implementation_Status ) then
106        G_Enabled := 'Y';
107      else
108        G_Enabled := 'N';
109      end if;
110    end if;
111    RETURN ( G_Enabled );
112 
113 END Enabled;
114 
115 
116 --
117 --  Name          : Allow_Cross_UnitNum_Issues
118 --  Pre-reqs      : None
119 --  Function      : This function returns a Y/N indicator whether
120 --                  Cross-Unit Number WIP Issues are allowed
121 --
122 --
123 --  Parameters    :
124 --  IN            : None
125 --
126 --  Returns       : Y/N
127 --
128 FUNCTION Allow_Cross_UnitNum_Issues
129 ( X_organization_id                IN     NUMBER
130 ) RETURN VARCHAR2 IS
131    L_allowed  VARCHAR2(1);
132    L_org_id   number;
133 BEGIN
134 
135    if ( X_organization_id is null ) then
136       L_org_id := Fnd_Profile.Value_WNPS('MFG_ORGANIZATION_ID');
137    else
138       L_org_id := X_organization_id;
139    end if;
140 
141    SELECT nvl(allow_cross_unitnum_issues,'N')
142    INTO   L_allowed
143    FROM   pjm_org_parameters
144    WHERE  organization_id = L_org_id;
145 
146    if (L_allowed = 'Y') then
147       RETURN( 'Y' );
148    else
149       RETURN( 'N' );
150    end if;
151 
152 EXCEPTION
153 WHEN NO_DATA_FOUND THEN
154    RETURN( 'N' );
155 WHEN OTHERS THEN
156    RETURN( 'N' );
157 
158 END Allow_Cross_UnitNum_Issues;
159 
160 
161 --
162 --  Name          : Unit_Effective_Item
163 --  Pre-reqs      : None
164 --  Function      : This function checks the effectivity control for
165 --                  the item
166 --
167 --
168 --  Parameters    :
169 --  IN            : X_item_id                       NUMBER
170 --                  X_organization_id               NUMBER
171 --
172 --  OUT           : None
173 --
174 --  Returns       : Y/N
175 --
176 FUNCTION Unit_Effective_Item
177 ( X_item_id                        IN     NUMBER
178 , X_organization_id                IN     NUMBER
179 ) RETURN VARCHAR2 IS
180 
181 l_item number; -- add for R12 EAM request, bug#4521664
182 BEGIN
183 
184    if ( X_item_id is NULL ) then
185       return ( NULL );
186    end if;
187 
188    --
189    -- The input and output are all cached into global variables to
190    -- speed up repeated lookups.  If the input parameters of the
191    -- current lookup matches the input parameters of the previous
192    -- lookup, the cached result will be used instead of hitting the DB
193    -- again.
194    --
195    if (  G_Unit_Eff_Item IS NULL
196       OR G_Item_ID <> X_Item_ID
197       OR G_Org_ID  <> X_organization_ID ) then
198       --
199       -- No cache output or input parameters have changed; recache
200       --
201       G_Org_ID := X_Organization_ID;
202       G_Item_ID := X_Item_ID;
203 
204 /* bug 4521664 for EAM - Ignore Unit effectivity Attribute for Asset Group
205        Items (eam_item_type = 2 in MSI table) */
206 
207       select nvl(eam_item_type, -2)
208       into l_item
209       from mtl_system_items_b
210       where inventory_item_id =X_ITEM_ID
211       and organization_id = X_organization_id;
212 
213       if l_item = 1 then
214             G_Unit_Eff_Item := 'N'; --Always return N for Asset Group Item
215       else
216         /* end of change for EAM, process  all other type of items */
217          SELECT decode(effectivity_control , 2 , 'Y' , 'N')
218          INTO   G_Unit_Eff_Item
219          FROM   mtl_system_items
220          WHERE  inventory_item_id = X_item_id
221          AND    organization_id = X_organization_id;
222       end if;
223    end if;
224 
225    RETURN ( G_Unit_Eff_Item );
226 
227 EXCEPTION
228 WHEN NO_DATA_FOUND THEN
229    G_Unit_Eff_Item := 'N';
230    RETURN ( G_Unit_Eff_Item );
231 WHEN OTHERS THEN
232    RETURN ( NULL );
233 
234 END Unit_Effective_Item;
235 
236 
237 --
238 --  Name          : Set_Unit_Number
239 --  Pre-reqs      : None
240 --  Function      : This procedure sets the global variable
241 --                  G_Unit_Number
242 --
243 --
244 --  Parameters    :
245 --  IN            : X_Unit_Number                   NUMBER
246 --
247 --  Returns       : None
248 --
249 PROCEDURE Set_Unit_Number
250 ( X_Unit_Number                    IN     VARCHAR2
251 ) IS
252 BEGIN
253 
254    G_Unit_Number := X_Unit_Number;
255 
256 END Set_Unit_Number;
257 
258 
259 --
260 --  Name          : Current_Unit_Number
261 --  Pre-reqs      : None
262 --  Function      : This procedure gets the value in global variable
263 --                  G_Unit_Number
264 --
265 --
266 --  Parameters    :
267 --  IN            : None
268 --
269 --  Returns       : VARCHAR2
270 --
271 FUNCTION Current_Unit_Number
272   RETURN VARCHAR2 IS
273 BEGIN
274 
275    return ( G_Unit_Number );
276 
277 END Current_Unit_Number;
278 
279 
280 --
281 --  Name          : Prev_Unit_Number
282 --  Pre-reqs      : None
283 --  Function      : This function returns the previous unit number in
284 --                  ascending order for the same end item
285 --
286 --
287 --  Parameters    :
288 --  IN            : X_Unit_Number                   NUMBER
289 --
290 --  Returns       : VARCHAR2
291 --
292 FUNCTION Prev_Unit_Number
293 ( X_Unit_Number                    IN     VARCHAR2
294 ) RETURN VARCHAR2 IS
295   L_unit_number     VARCHAR2(30) := NULL;
296 
297   CURSOR c IS
298   SELECT N2.unit_number
299   FROM   pjm_unit_numbers N1
300   ,      pjm_unit_numbers N2
301   WHERE  N1.unit_number = X_unit_number
302   AND    N2.end_item_id = N1.end_item_id
303   AND    N2.master_organization_id = N1.master_organization_id
304   AND    N2.unit_number < N1.unit_number
305   ORDER BY N2.unit_number desc;
306 
307 BEGIN
308 
309   OPEN c;
310   FETCH c INTO L_unit_number;
311   RETURN ( L_unit_number );
312 
313 EXCEPTION
314 WHEN OTHERS THEN
315   RAISE;
316 END Prev_Unit_Number;
317 
318 
319 --
320 --  Name          : Next_Unit_Number
321 --  Pre-reqs      : None
322 --  Function      : This function returns the next unit number in
323 --                  ascending order for the same end item
324 --
325 --
326 --  Parameters    :
327 --  IN            : X_Unit_Number                   NUMBER
328 --
329 --  Returns       : VARCHAR2
330 --
331 FUNCTION Next_Unit_Number
332 ( X_Unit_Number                    IN     VARCHAR2
333 ) RETURN VARCHAR2 IS
334   L_unit_number     VARCHAR2(30) := NULL;
335 
336   CURSOR c IS
337   SELECT N2.unit_number
338   FROM   pjm_unit_numbers N1
339   ,      pjm_unit_numbers N2
340   WHERE  N1.unit_number = X_unit_number
341   AND    N2.end_item_id = N1.end_item_id
342   AND    N2.master_organization_id = N1.master_organization_id
343   AND    N2.unit_number > N1.unit_number
344   ORDER BY N2.unit_number asc;
345 
346 BEGIN
347 
348   OPEN c;
349   FETCH c INTO L_unit_number;
350   RETURN ( L_unit_number );
351 
352 EXCEPTION
353 WHEN OTHERS THEN
354   RAISE;
355 END Next_Unit_Number;
356 
357 
358 --
359 --  Name          : WIP_Unit_Number
360 --  Pre-reqs      : None
361 --  Function      : This function returns the unit number on a discrete
362 --                  job or flow schedule
363 --
364 --
365 --  Parameters    :
366 --  IN            : X_wip_entity_id                 NUMBER
367 --                  X_organization_id               NUMBER
368 --
369 --  OUT           : None
370 --
371 --  Returns       : VARCHAR2
372 --
373 FUNCTION WIP_Unit_Number
374 ( X_wip_entity_id                  IN     NUMBER
375 , X_organization_id                IN     NUMBER
376 ) RETURN VARCHAR2 IS
377 
378 BEGIN
379 
380    SELECT DECODE(e.entity_type, 1, dj.end_item_unit_number,
381                                 4, fs.end_item_unit_number)
382    INTO   G_WIP_Unit_Num
383    FROM   wip_flow_schedules fs
384    ,      wip_discrete_jobs dj
385    ,      wip_entities e
386    WHERE  e.wip_entity_id = X_wip_entity_id
387    AND    e.organization_id = X_organization_id
388    AND    fs.organization_id (+) = e.organization_id
389    AND    fs.wip_entity_id (+) = e.wip_entity_id
390    AND    dj.organization_id (+) = e.organization_id
391    AND    dj.wip_entity_id (+) = e.wip_entity_id;
392 
393    G_Wip_Entity_ID := X_wip_entity_id;
394    G_WIP_Org_ID    := X_organization_id;
395 
396    RETURN ( G_WIP_Unit_Num );
397 
398 EXCEPTION
399 WHEN OTHERS THEN
400    RETURN ( NULL );
401 
402 END WIP_Unit_Number;
403 
404 
405 FUNCTION WIP_Unit_Number_Cached
406 ( X_wip_entity_id                  IN     NUMBER
407 , X_organization_id                IN     NUMBER
408 ) RETURN VARCHAR2 IS
409 
410 BEGIN
411 
412    IF (  G_WIP_Unit_Num IS NULL
413       OR G_WIP_Entity_ID <> X_wip_entity_id
414       OR G_WIP_Org_ID <> X_organization_id ) THEN
415 
416       SELECT DECODE(e.entity_type, 1, dj.end_item_unit_number,
417                                    4, fs.end_item_unit_number)
418       INTO   G_WIP_Unit_Num
419       FROM   wip_flow_schedules fs
420       ,      wip_discrete_jobs dj
421       ,      wip_entities e
422       WHERE  e.wip_entity_id = X_wip_entity_id
423       AND    e.organization_id = X_organization_id
424       AND    fs.organization_id (+) = e.organization_id
425       AND    fs.wip_entity_id (+) = e.wip_entity_id
426       AND    dj.organization_id (+) = e.organization_id
427       AND    dj.wip_entity_id (+) = e.wip_entity_id;
428 
429      G_Wip_Entity_ID := X_wip_entity_id;
430      G_WIP_Org_ID    := X_organization_id;
431 
432    END IF;
433 
434    RETURN ( G_WIP_Unit_Num );
435 
436 EXCEPTION
437 WHEN OTHERS THEN
438    RETURN ( NULL );
439 
440 END WIP_Unit_Number_Cached;
441 
442 
443 --
444 --  Name          : RCV_Unit_Number
445 --  Pre-reqs      : None
446 --  Function      : This function returns the unit number on a PO
447 --                  distribution or Internal Req distribution based on the
448 --                  receiving transaction
449 --
450 --
451 --  Parameters    :
452 --  IN            : X_rcv_transaction_id            NUMBER
453 --
454 --  OUT           : None
455 --
456 --  Returns       : VARCHAR2
457 --
458 FUNCTION RCV_Unit_Number
459 ( X_rcv_transaction_id             IN     NUMBER
460 ) RETURN VARCHAR2 IS
461 
462    L_po_distribution_id NUMBER;
463    L_req_line_id        NUMBER;
464 
465 BEGIN
466 
467    IF (  G_RCV_Unit_Num IS NULL
468       OR G_RCV_Txn_ID <> X_rcv_transaction_id ) THEN
469 
470       SELECT po_distribution_id
471       ,      requisition_line_id
472       INTO   L_po_distribution_id
473       ,      L_req_line_id
474       FROM   rcv_transactions
475       WHERE  transaction_id = X_rcv_transaction_id;
476 
477       IF L_po_distribution_id IS NOT NULL THEN
478 
479          SELECT end_item_unit_number
480          INTO   G_RCV_Unit_Num
481          FROM   po_distributions_all
482          WHERE  po_distribution_id = L_po_distribution_id;
483 
484       ELSIF L_req_line_id IS NOT NULL THEN
485 
486          SELECT end_item_unit_number
487          INTO   G_RCV_Unit_Num
488          FROM   po_req_distributions_all
489          WHERE  requisition_line_id = L_req_line_id;
490 
491       ELSE
492 
493          G_RCV_Unit_Num := null;
494 
495       END IF;
496 
497       G_RCV_Txn_ID := X_rcv_transaction_id;
498 
499    END IF;
500 
501    RETURN ( G_RCV_Unit_Num );
502 
503 EXCEPTION
504 WHEN OTHERS THEN
505    RETURN ( NULL );
506 
507 END RCV_Unit_Number;
508 
509 
510 --
511 --  Name          : OE_Line_Unit_Number
512 --  Pre-reqs      : None
513 --  Function      : This function returns the unit number on a sales order
514 --                  line
515 --
516 --
517 --  Parameters    :
518 --  IN            : X_so_line_id                    NUMBER
519 --
520 --  OUT           : None
521 --
522 --  Returns       : VARCHAR2
523 --
524 FUNCTION OE_Line_Unit_Number
525 ( X_so_line_id                     IN     NUMBER
526 ) RETURN VARCHAR2 IS
527 
528 BEGIN
529 
530    SELECT end_item_unit_number
531    INTO   G_OE_Unit_Num
532    FROM   oe_order_lines_all
533    WHERE  line_id = X_so_line_id;
534 
535    G_OE_Line_ID := X_so_line_id;
536 
537    RETURN( G_OE_Unit_Num );
538 
539 EXCEPTION
540 WHEN OTHERS THEN
541    RETURN ( NULL );
542 
543 END OE_Line_Unit_Number;
544 
545 
546 FUNCTION OE_Line_Unit_Number_Cached
547 ( X_so_line_id                     IN     NUMBER
548 ) RETURN VARCHAR2 IS
549 
550 BEGIN
551 
552    IF (  G_OE_Unit_Num IS NULL
553       OR G_OE_Line_ID <> X_so_line_id ) THEN
554 
555       SELECT end_item_unit_number
556       INTO   G_OE_Unit_Num
557       FROM   oe_order_lines_all
558       WHERE  line_id = X_so_line_id;
559 
560       G_OE_Line_ID := X_so_line_id;
561 
562    END IF;
563 
564    RETURN( G_OE_Unit_Num );
565 
566 EXCEPTION
567 WHEN OTHERS THEN
568    RETURN ( NULL );
569 
570 END OE_Line_Unit_Number_Cached;
571 
572 
573 --
574 --  Name          : RMA_Rcpt_Unit_Number
575 --  Pre-reqs      : None
576 --  Function      : This function returns the unit number on a RMA
577 --                  order line based on the receiving transaction
578 --
579 --
580 --  Parameters    :
581 --  IN            : X_rcv_transaction_id            NUMBER
582 --
583 --  OUT           : None
584 --
585 --  Returns       : VARCHAR2
586 --
587 FUNCTION RMA_Rcpt_Unit_Number
588 ( X_rcv_transaction_id             IN     NUMBER
589 ) RETURN VARCHAR2 IS
590    L_oe_order_line_id   NUMBER;
591 BEGIN
592 
593    IF (  G_RMA_Unit_Num IS NULL
594       OR G_RMA_Txn_ID <> X_rcv_transaction_id ) THEN
595 
596       SELECT oe_order_line_id
597       INTO   L_oe_order_line_id
598       FROM   rcv_transactions
599       WHERE  transaction_id = X_rcv_transaction_id;
600 
601       IF L_oe_order_line_id IS NOT NULL THEN
602          G_RMA_Unit_Num := OE_Line_Unit_Number( L_oe_order_line_id );
603       ELSE
604          G_RMA_Unit_Num := NULL;
605       END IF;
606 
607       G_RMA_Txn_ID := X_rcv_transaction_id;
608 
609    END IF;
610 
611    RETURN ( G_RMA_Unit_Num );
612 
613 EXCEPTION
614 WHEN OTHERS THEN
615    RETURN ( NULL );
616 
617 END RMA_Rcpt_Unit_Number;
618 
619 
620 --
621 --  Name          : Validate_Serial
622 --  Pre-reqs      : None
623 --  Function      : This function validates the transaction serial numbers
624 --                  against the unit number on the transaction entity
625 --                  (e.g. WIP job)
626 --
627 --
628 --  Parameters    :
629 --  IN            : X_trx_source_type_id            NUMBER
630 --                  X_trx_action_id                 NUMBER
631 --                  X_item_id                       NUMBER
632 --                  X_organization_id               NUMBER
633 --                  X_serial_number                 VARCHAR2
634 --                  X_unit_number                   VARCHAR2
635 --
636 --  OUT           : X_error_code                    VARCHAR2
637 --
638 --  Returns       : Boolean
639 --
640 --  Algorithm     :
641 --
642 --    If Model/Unit Effectivity is not enabled then
643 --       Return "TRUE"
644 --
645 --    If transaction type is not
646 --    "WIP Component Issue" or
647 --    "WIP Assembly Return" or
648 --    "RMA Receipt" or
649 --    "Direct Interorg transfer" or
650 --    "Sales order staging transfer" or
651 --    "Intransit shipment" then
652 --       Return "TRUE"
653 --
654 --    If transaction type is "RMA Receipt" and item serial control is
655 --    Dynamic Entry at Receipt
656 --       Return "TRUE"
657 --
658 --    Get Effectivity Control attribute from item
659 --
660 --    Fetch the Unit Number from the serial number
661 --
662 --    If item is date effective and serial has unit number link then
663 --       Get error message (UEFF-Item Not Unit Effective)
664 --       populate ERROR_CODE column
665 --       Return "FALSE"
666 --
667 --    If item is unit effective and upstream unit number is null then
668 --       Get error message (UEFF-Item Unit Effective)
669 --       populate ERROR_CODE column
670 --       Return "FALSE"
671 --
672 --    If the two Unit Numbers match then
673 --       Return "TRUE"
674 --    Else
675 --       If Cross-Unit Number Issue is enabled then
676 --          Get warning message (UEFF-Cross Unit Number Issue)
677 --          populate ERROR_CODE column
678 --          Return "TRUE"
679 --       Else
680 --          Get error message (UEFF-Unit Number Mismatch)
681 --          populate ERROR_CODE column
682 --          Return "FALSE"
683 --
684 
685 FUNCTION Validate_Serial
686 ( X_trx_source_type_id             IN            NUMBER
687 , X_trx_action_id                  IN            NUMBER
688 , X_item_id                        IN            NUMBER
689 , X_organization_id                IN            NUMBER
690 , X_serial_number                  IN            VARCHAR2
691 , X_unit_number                    IN            VARCHAR2
692 , X_error_code                     OUT NOCOPY    VARCHAR2
693 ) RETURN BOOLEAN IS
694   L_serial_unitnum        PJM_UNIT_NUMBERS.UNIT_NUMBER%TYPE;
695   L_unit_eff_item         VARCHAR2(1);
696 BEGIN
697 
698    --
699    -- If Model/Unit Effectivity is not enabled, there is no need for
700    -- further processing
701    --
702    if ( enabled = 'N' ) then
703       return ( TRUE );
704    end if;
705 
706    --
707    -- If transaction type is not "WIP Component Issue" or "WIP Assembly Return"
708    -- or "Direct Interorg transfer" or "Intransit shipment"
709    -- there is no need for further processing
710    --
711    -- 11.08.1999
712    -- Added support for RMA receipts
713    --
714    -- 01.29.2003
715    -- Added support for sales orders staging transfers
716    --
717    if not ( ( X_trx_source_type_id = 5    -- Job or Schedule
718             AND (  X_trx_action_id = 1    -- Issue from stores
719                 OR X_trx_action_id = 32   -- Assembly return
720                 )
721             ) OR
722             ( X_trx_source_type_id = 12   -- RMA
723             AND (  X_trx_action_id = 27   -- Receipt into stores
724                 )
725             ) OR
726             ( (  X_trx_source_type_id = 2 -- Sales order
727               OR X_trx_source_type_id = 8 -- Internal sales order
728               )
729             AND (  X_trx_action_id = 28   -- Staging transfer
730                 )
731             ) OR
732             ( X_trx_source_type_id = 13   -- Inventory
733             AND (  X_trx_action_id = 3    -- Direct organization transfer
734                 OR X_trx_action_id = 21   -- Intransit shipment
735                 )
736             )
737           ) then
738       return ( TRUE );
739    end if;
740 
741    --
742    -- A Law  01/31/2003
743    --
744    -- If transaction type is sales order staging transfer and the
745    -- input unit number is NULL, do not perform validation.
746    --
747    -- This is put in as a kludge but should be removed with a future fix
748    -- in the transaction processor.
749    --
750    if ( ( (  X_trx_source_type_id = 2 -- Sales order
751           OR X_trx_source_type_id = 8 -- Internal sales order
752           )
753         AND (  X_trx_action_id = 28   -- Staging transfer
754             )
755         ) AND
756         X_unit_number is null
757       ) then
758       return ( TRUE );
759    end if;
760 
761    --
762    -- A Law  02/17/2000
763    --
764    -- Bug 1200761:
765    --
766    -- If transaction type is RMA Receipt and item serial control is
767    -- Dynamic Entry at Receipt, there is no need for further
768    -- processing
769    --
770    if ( ( X_trx_source_type_id = 12   -- RMA
771         AND (  X_trx_action_id = 27   -- Receipt into stores
772             )
773         ) AND
774         Item_Serial_Control( X_item_id
775 			   , X_organization_id ) = 5
776       ) then
777       return ( TRUE );
778    end if;
779 
780    L_unit_eff_item := Unit_Effective_Item( X_item_id
781 					 , X_organization_id );
782 
783    SELECT end_item_unit_number
784    INTO   L_serial_unitnum
785    FROM   mtl_serial_numbers
786    WHERE  serial_number = X_serial_number
787    AND    inventory_item_id = X_item_id;
788 
789    --
790    -- If item is not under Unit Effective control but serial is link to
791    -- to a unit number, raise error
792    --
793    if ( L_unit_eff_item = 'N' ) then
794       if ( L_serial_unitnum is null ) then
795 
796          return ( TRUE );
797 
798       else
799 
800          X_error_code := 'UEFF-Item Not Unit Effective';
801          fnd_message.set_name('PJM','UEFF-Item Not Unit Effective');
802          return ( FALSE );
803 
804       end if;
805    end if;
806 
807    --
808    -- If item is under Unit Effective control but upstream unit number
809    -- is NULL, raise error
810    --
811    if ( X_unit_number is null ) then
812 
813       X_error_code := 'UEFF-Item Unit Effective';
814       fnd_message.set_name('PJM','UEFF-Item Unit Effective');
815       return ( FALSE );
816 
817    end if;
818 
819    --
820    -- Now the validation logic
821    --
822    if ( X_unit_number = L_serial_unitnum ) then
823 
824       return ( TRUE );
825 
826    else
827       if ( Allow_Cross_UnitNum_Issues(X_organization_id) = 'Y' ) then
828 
829          X_error_code := 'UEFF-Cross Unit Number Issue';
830          fnd_message.set_name('PJM','UEFF-Cross Unit Number Issue');
831          fnd_message.set_token('SERIAL', X_serial_number);
832          return ( TRUE );
833 
834       else
835 
836          X_error_code := 'UEFF-Unit Number Mismatch';
837          fnd_message.set_name('PJM','UEFF-Unit Number Mismatch');
838          fnd_message.set_token('SERIAL', X_serial_number);
839          fnd_message.set_token('UNIT1', L_serial_unitnum);
840          fnd_message.set_token('UNIT2', X_unit_number);
841          return ( FALSE );
842 
843       end if;
844    end if;
845 
846 END Validate_Serial;
847 
848 
849 --
850 --  Name          : Serial_UnitNum_Link
851 --  Pre-reqs      : None
852 --  Function      : This function links the transaction serial numbers
853 --                  to the unit number on the transaction entity
854 --                  (e.g. WIP job)
855 --
856 --
857 --  Parameters    :
858 --  IN            : X_transaction_id                NUMBER
859 --
860 --  OUT           : X_error_code                    VARCHAR2
861 --
862 --  Returns       : Boolean
863 --
864 FUNCTION Serial_UnitNum_Link
865 ( X_transaction_id                 IN            NUMBER
866 , X_error_code                     OUT NOCOPY    VARCHAR2
867 ) RETURN BOOLEAN IS
868   L_organization_id NUMBER;
869   L_item_id         NUMBER;
870   L_src_type_id     NUMBER;
871   L_trx_action_Id   NUMBER;
872   L_trx_src_id      NUMBER;
873   L_rcv_trx_id      NUMBER;
874   L_direction       NUMBER;
875   L_unit_number     PJM_UNIT_NUMBERS.UNIT_NUMBER%TYPE;
876 BEGIN
877 
878    --
879    -- If Model/Unit Effectivity is not enabled, there is no need for
880    -- further processing
881    --
882    if ( enabled = 'N' ) then
883       return ( TRUE );
884    end if;
885 
886    SELECT organization_id
887    ,      inventory_item_id
888    ,      transaction_source_type_id
889    ,      transaction_action_id
890    ,      transaction_source_id
891    ,      rcv_transaction_id
892    ,      SIGN(primary_quantity)
893    INTO   L_organization_id
894    ,      L_item_id
895    ,      L_src_type_id
896    ,      L_trx_action_id
897    ,      L_trx_src_id
898    ,      L_rcv_trx_id
899    ,      L_direction
900    FROM   mtl_material_transactions
901    WHERE  transaction_id = X_transaction_id;
902 
903    --
904    -- If item is not under Unit Effective control, there is no need for
905    -- further processing
906    --
907    if ( Unit_Effective_Item( L_item_id, L_organization_id ) = 'N' ) then
908       return ( TRUE );
909    end if;
910 
911    --
912    -- If transaction type is not any one of the following, there is no
913    -- need for further processing
914    --
915    -- 11.08.1999
916    -- Added support for RMA receipts
917    --
918    if not (
919       ( L_src_type_id = 1          -- Purchase Order
920        AND
921         (  L_trx_action_id = 27    -- Receipt into stores
922         OR L_trx_action_id = 1 )   -- Issue from stores
923       )
924    OR ( L_src_type_id = 5          -- Job or schedule
925        AND
926         (  L_trx_action_id = 31    -- Assembly completion
927         OR L_trx_action_id = 32    -- Assembly return
928         OR L_trx_action_id = 33    -- Negative component issue
929         OR L_trx_action_id = 34 )  -- Negative component return
930       )
931    OR ( L_src_type_id = 12         -- RMA
932        AND
933         (  L_trx_action_id = 27    -- Receipt into stores
934         OR L_trx_action_id = 1 )   -- Issue from stores
935       )
936    ) then
937       return ( TRUE );
938    end if;
939 
940    if ( L_src_type_id = 5 ) then
941       L_unit_number := WIP_Unit_Number(L_trx_src_id, L_organization_id);
942    elsif ( L_src_type_id = 1 ) then
943       L_unit_number := RCV_Unit_Number(L_rcv_trx_id);
944    else
945       L_unit_number := RMA_Rcpt_Unit_Number(L_rcv_trx_id);
946    end if;
947 
948    UPDATE mtl_serial_numbers
949    SET    end_item_unit_number =
950      DECODE(L_direction, 1, L_unit_number, NULL)
951    WHERE  (inventory_item_id, serial_number) in (
952      SELECT inventory_item_id, serial_number
953      FROM   mtl_unit_transactions
954      WHERE  transaction_id = X_transaction_id
955     UNION ALL   /*Bug 7207502 (FP of 6391634): Added union part to select serial when assembly is lot serial controlled.*/
956      SELECT mut.inventory_item_id, mut.serial_number
957      FROM   mtl_transaction_lot_numbers mtln,   mtl_unit_transactions mut
958      WHERE  mtln.transaction_id = X_transaction_id
959      AND   mtln.serial_transaction_id =   mut.transaction_id
960    );
961 
962    return ( TRUE );
963 
964 EXCEPTION
965 when others then
966    X_error_code := sqlerrm;
967    return ( FALSE );
968 END Serial_UnitNum_Link;
969 
970 
971 --
972 --  Name          : Unit_Serial_History
973 --  Pre-reqs      : None
974 --  Function      : This function creates audit trail information for
975 --                  unit number changes to serial numbers
976 --
977 --
978 --  Parameters    :
979 --  IN            : X_serial_number                 VARCHAR2
980 --                  X_item_id                       NUMBER
981 --                  X_old_unit_number               VARCHAR2
982 --                  X_new_unit_number               VARCHAR2
983 --                  X_start_num                     NUMBER
984 --                  X_counts                        NUMBER
985 --
986 --  OUT           : X_error_code                    VARCHAR2
987 --
988 --  Returns       : Boolean
989 --
990 FUNCTION Unit_Serial_History
991 ( X_serial_number                  IN            VARCHAR2
992 , X_item_id                        IN            NUMBER
993 , X_organization_id                IN            NUMBER
994 , X_old_unit_number                IN            VARCHAR2
995 , X_new_unit_number                IN            VARCHAR2
996 , X_error_code                     OUT NOCOPY    VARCHAR2
997 ) return BOOLEAN IS
998   L_user_id              NUMBER;
999   L_login_id             NUMBER;
1000 BEGIN
1001 
1002    L_user_id := fnd_global.user_id;
1003    L_login_id := fnd_global.conc_login_id;
1004 
1005    INSERT INTO pjm_unit_serial_history
1006    ( serial_number
1007    , inventory_item_id
1008    , organization_id
1009    , old_unit_number
1010    , new_unit_number
1011    , creation_date
1012    , created_by
1013    , last_update_date
1014    , last_updated_by
1015    , last_update_login )
1016    SELECT X_serial_number
1017    ,      X_item_id
1018    ,      X_organization_id
1019    ,      X_old_unit_number
1020    ,      X_new_unit_number
1021    ,      sysdate
1022    ,      L_user_id
1023    ,      sysdate
1024    ,      L_user_id
1025    ,      L_login_id
1026    FROM   dual;
1027 
1028    return ( TRUE );
1029 
1030 EXCEPTION
1031 when others then
1032    X_error_code := sqlerrm;
1033    return ( FALSE );
1034 
1035 END Unit_Serial_History;
1036 
1037 
1038 --
1039 --  Name          : OE_Attribute
1040 --  Pre-reqs      : None
1041 --  Function      : This function returns the attribute column in the
1042 --                  SO_LINES descriptive flexfield that stores the unit
1043 --                  number value.  The column name is captured in the
1044 --                  profile PJM_UEFF_OE_ATTRIBUTE.
1045 --
1046 --
1047 --  Parameters    :
1048 --  IN            : None
1049 --
1050 --  Returns       : Boolean
1051 --
1052 FUNCTION OE_Attribute
1053   RETURN VARCHAR2 IS
1054 BEGIN
1055 
1056    RETURN( Fnd_Profile.Value_WNPS('PJM_UEFF_OE_ATTRIBUTE') );
1057 
1058 END OE_Attribute;
1059 
1060 
1061 END PJM_UNIT_EFF;