Using Barcode Standards with Oracle Mobile Applications

This chapter covers the following topics:

Overview

This document discusses the implementation and use of different barcode standards within Oracle Mobile Applications. Topics include: overview standards, support within Oracle Mobile applications, configuration, setup and usage. The setup section includes the setup steps for the hardware devices, the mobile server, and the setup within Oracle Applications.

Barcode Standards

Warehouse applications use labels that comply with Barcoding standards for Automatic identification and data collection (AIDC), GS1, and PPN (Pharmacy Product Number). Barcode for data collection eliminates manual data collection, improves data collection accuracy, and reduces time and labor. Barcoding standards enable companies to encode, in barcode form, more information than basic product identification. Use this type of supplementary information (such as, Lot Number, Serial Number, License Plate Number, Quantity, etc.) to improve the management of the supply chain. Common application standards for barcoding are ANSI/FACT, EAN/UCC, SPEC2000, HIBCC, EIAJ, etc. Use the following features in Oracle Mobile applications to support barcoding standards:

Data Field Identifiers

You use Data Field Identifiers (DFIs) to identify the type of data embedded within a barcode. A DFI usually consists of one to three characters added to the beginning of the data encoded in the barcode. For example, a DFI for a Part Number might be 'P+.' If the part number encoded in a given barcode is 'AS54888', the barcode encodes the value 'P+AS54888' to indicate the barcode is for a part number and the part number is 'AS54888'.

DFIs help reduce errors caused by scanning the wrong barcode into a field on a mobile device. They also allow fields to be scanned out of order and values to be placed into the appropriate fields.

Oracle DFI Functionality

Oracle Mobile Applications provides DFI support for recognition of barcodes that contain DFIs and out-of-order scanning. You can use DFIs to effectively map ANSI/FACT data identifiers. You can also use DFIs to map Application Identifiers used in UCC/EAN-128 barcode standards.

Field Recognition

Oracle Mobile Applications recognizes a DFI included in a barcode and validates it in the proper field. If the DFI is required, a failed DFI validation results in an error message.

You can validate each field on the mobile application against one or more DFIs. If needed, you can optionally flag each field to require a DFI. If a DFI is required, a barcode you scan into this field must have at least one assigned DFI. If the system does not find a DFI, you receive an error message. If a DFI is not required, Oracle validates against a DFI if it is found, but if no DFI is found, the entire value of the barcode is inserted into the field.

Out-of-Order Scanning

Oracle also supports Out-of-Order scanning through DFIs. If you scan a field containing a DFI that corresponds to a field other than current field, the system enters the value of the barcode into the appropriate field. You can then scan the barcode that corresponds to the current field, or scan another DFI identified barcode.

The system validates the value inserted into the Out-of-Order field when you advance to the next field. Because field level validation generally depends on previous fields for validation to occur, you continue on the normal navigation path through the field to complete the transaction.

For example, if you use a mobile device to perform a Miscellaneous Issue of material, first you must scan the issued Part Number. The system validates the scan against a DFI of 'P+' for the part number. The next scan is a barcode with the value 'Q+10'. The system determines there is a field on the current page that uses 'Q+' as a DFI, and places a value '10' in the quantity field. You must then scan the issuing subinventory and locator. Then you advance through the quantity field and the quantity validates against the available quantity in the subinventory and locator scanned earlier. You can configure out-of-order scanning by setting the property mwa.OutOfOrderScanEnabled to Yes in the mwa.cfg file. To ensure that the cursor does not move to the next editable field, set the property mwa.RestrictFieldExitAtScan to Yes.

Oracle Mobile Applications DFI Flow

When you scan a barcode, the mobile device prefixes an ASCII control character (the Data Stream Indicator) to the data that transmits to the server. The Oracle Mobile Server recognizes the Data Stream Indicator and searches for a recognizable Data Field Indentifier in the barcode data. The system recognizes a DFI is assigned to a field on the current page. It extracts the value from the barcode and inserts it into the field the DFI represents. The following diagram displays the flow behind Oracle DFI support.

the picture is described in the document text

Necessary Elements for DFI Support

To support DFI, the mobile device must support automatically pre-pending of an arbitrary character to any scanned entry. All the mobile devices certified for use with Oracle Mobile Applications support this functionality. You must configure the Oracle Mobile Server to support DFI scanning.

Finally, the specific Oracle Application the mobile device uses must support DFI functionality. Oracle Mobile Supply Chain Applications, Oracle Inventory Management and Oracle Warehouse Management provide full support for DFI functionality. Check with the specific product user's guide if you are unsure if DFIs are supported.

Setup for DFI Support

The setup to enable DFI support involves the following three steps:

  1. Configure the mobile device to prefix an ASCII control character to every scan.

  2. Configure the mobile server to recognize the proper ASCII control character as indicating a scanned entry.

  3. Set up the Applications to recognize DFIs for each field on the mobile windows.

Hardware Setup

First, configure the mobile device to prefix the Data Stream Indicator to every scan. The Data Stream Indicator must be an ASCII control character (non-printable character). All certified Oracle Mobile Applications devices support this type of configuration. You can configure most scanners by scanning configuration barcodes, navigating to a configuration menu through the device keypad, or by using a remote configuration tool. Refer to the User's guide for the mobile device to determine configuration.

The default Data Stream Indicator is ASCII 28 – File Separator. Use this ASCII control character as the Data Stream Indicator unless there is a reason you cannot use it. You can use any ASCII as the Data Stream Indicator except for the following:

Mobile Server Setup

After you configure the device to prepend the Data Stream Indicator, you must configure the mobile server to recognize the appropriate Data Stream Indicator. Each device configuration can have a different Data Stream Indicator to support the capabilities of different mobile devices. The configuration setting is located in the device configuration file. The default device configuration setting (default_key.ini) that ships with the mobile server has the Data Stream Indicator set to the default: ASCII 28.

The character the device prepends to a scanned entry must match the entry in the.ini file for the device configuration in order for DFIs to be fully supported.

For more information on mobile device configurations and the configuration.ini file refer to the Oracle Mobile Server User's Guide.

Applications Setup

The AK Dictionary stores DFI information as well as the field labels for the mobile windows. If necessary, you can also make changes in the AK Dictionary to the field labels that appear on the mobile windows. To access the AK Dictionary, log on to Oracle Applications on the desktop and access the responsibility AK Developer. Contact your system administrator if you do not have this responsibility.

Navigating the AK Dictionary

DFIs may be registered at two different levels – the Attributes level or the Region Items level within the AK Developer Responsibility. Region Items are Attributes assigned to a Region. DFIs registered at the Region Items level take precedence over DFIs registered at the Attribute level.

To register DFIs at the Attributes level, open the Define Attributes window. From that window, you can access the mobile windows fields. You can query attributes by Attribute Name or Label. Enter the DFI string in the Default Varchar2 Value field. The details on the format of the DFI string are as follows: To register DFIs at the Region Items level, you must know the Resource table the specific mobile applications uses (for Oracle Inventory and Oracle Warehouse Management it is INVRESOURCETABLE). You can query the Resource table in the Define Regions window. For example, to query the Oracle Inventory Resource table, query on Region ID = 'INVRESOURCETABLE.'

Once you find the appropriate Resource table, select Region Items. On the Region Items window, you can view all the AK Region Items used for mobile applications within the table. Locate the field that corresponds to the proper field on the mobile page, and enter the DFI string into the field Default Varchar2 Value.

Entering the DFI String

The DFI String should be entered into the field “Default Varchar2 Value” either on the Attributes level, or the Region Items level. Enter the text in the following format:

“DFI=Q+,q+,Q,q REQ=N”

The above text indicates you can use four DFIs for this field: the characters ‘Q+', ‘q+', ‘Q', and ‘q'. It also indicates this field does not require a DFI. To set the field to required, use the text “REQ=Y” after the DFI list. List DFIs in the proper validation order.

Note: Include DFIs that are subsets of other DFIs after the original DFI. For example, if the DFI ‘Q' is listed before the DFI ‘Q+' and you scan a barcode that uses the DFI ‘Q+', the ‘Q' is removed from the barcode, but the ‘+' remains as part of the field value and an error occurs.

Seeded Data Field Identifiers

The following chart lists the seeded Data Field Identifiers (DFI) in Oracle Inventory and Oracle Warehouse Management. The seeded identifiers are from the ANSI Data Identifier Standard, document reference ANSI MH10.8.2-1995.

Seeded Data Field Identifiers
Mobile Prompt Data Field Information
Card Num DFI=15K REQ=N
SO Num DFI=1K REQ=N
Sales Order DFI=1K REQ=N
From Sub DFI=1L,20L REQ=N
Src Sub DFI=1L,20L REQ=N
To Sub DFI=1L,20L REQ=N
Sub DFI=1L,20L REQ=N
Res Sub DFI=1L,20L REQ=N
RMA Num DFI=1R REQ=N
RMA DFI=1R REQ=N
From Loc DFI=21L REQ=N
Src Loc DFI=21L REQ=N
To Loc DFI=21L REQ=N
Locator DFI=21L REQ=N
Res Loc DFI=21L REQ=N
Location DFI=2L REQ=N
Rev DFI=2P REQ=N
ASN Num DFI=2S REQ=N
ASN DFI=2S REQ=N
Deliv UOM DFI=3Q REQ=N
Rcpt UOM DFI=3Q REQ=N
UOM DFI=3Q REQ=N
Res UOM DFI=3Q REQ=N
Line Num DFI=4K REQ=N
Release DFI=5K REQ=N
Rel Num DFI=5K REQ=N
LPN DFI=J REQ=N
ParentLPN DFI=J REQ=N
&Create LPN DFI=J REQ=N
Inner LPN DFI=J REQ=N
Outer LPN DFI=J REQ=N
LPN DFI=J REQ=N
Acc LPN DFI=J REQ=N
Rej LPN DFI=J REQ=N
From LPN DFI=J REQ=N
To LPN DFI=J REQ=N
Drop LPN DFI=J REQ=N
Res LPN DFI=J REQ=N
Child LPN DFI=J REQ=N
PO Num DFI=K REQ=N
Item DFI=P REQ=N
Alloc Qty DFI=Q REQ=N
Deliv Qty DFI=Q REQ=N
Insp Qty DFI=Q REQ=N
Lot Qty DFI=Q REQ=N
Miss Qty DFI=Q REQ=N
Rcpt Qty DFI=Q REQ=N
Req Qty DFI=Q REQ=N
Ship Qty DFI=Q REQ=N
Total Qty DFI=Q REQ=N
Ship Qty DFI=Q REQ=N
Acc Qty DFI=Q REQ=N
Rej Qty DFI=Q REQ=N
Ea Lot Qty DFI=Q REQ=N
Qty DFI=Q REQ=N
Res Qty DFI=Q REQ=N
Split Qty DFI=Q REQ=N
Ret Qty DFI=Q REQ=N
From SN DFI=S REQ=N
To SN DFI=S REQ=N
SN DFI=S REQ=N
Serial DFI=S REQ=N
SN DFI=S REQ=N
From Lot DFI=T REQ=N
To Lot DFI=T REQ=N
Lot DFI=T REQ=N
Res Lot DFI=T REQ=N
Loc DFI=Z REQ=N

Customized Barcode Scanning

Customized barcode scanning imbeds user-defined logic to handle scanned input from a barcode scanner. It supports the following scenarios:

There are two ways to implement user-defined logic to handle scanned input. Customized barcode scanning functionality enables a scanned input to make either a PL/SQL or a java custom class callout. The java custom class is more scaleable and performs better. You must set up the hardware and the mobile server in order to use customized barcode scanning.

The following figure shows a sample concatenated UCC-128 barcode symbol. A single scan of concatenated barcode yields values for multiple data fields and should populate multiple field values in the form. In the following example a single scan of the following barcode should populate the Item, Lot Number, Quantity and Unit of Measure as Kilograms. Standard DFI functionality in Oracle Warehouse Management does not handle this requirement.

Concatenated UCC-128 Barcode Symbol

the picture is described in the document text

Data Field Identifier String Setup for UCC/EAN-128 Application Identifiers

The following identifiers are taken from the UCC/EAN-128 application identifiers standards, document reference ANSI/UCC4-1995.

UCC/EAN-128 Identifiers
Mobile Prompt EAN/UCC 128 AI Data Field Identifier String
LPN 00 DFI=00 REQ=N
ParentLPN 00 DFI=00 REQ=N
Create LPN 00 DFI=00 REQ=N
Inner LPN 00 DFI=00 REQ=N
Outer LPN 00 DFI=00 REQ=N
LPN 00 DFI=00 REQ=N
ACC LPN 00 DFI=00 REQ=N
Rej LPN 00 DFI=00 REQ=N
From LPN 00 DFI=00 REQ=N
To LPN 00 DFI=00 REQ=N
Drop LPN 00 DFI=00 REQ=N
Res LPN 00 DFI=00 REQ=N
Child LPN 00 DFI=00 REQ=N
PO Number 400 DFI=400 REQ=N
Item 01 DFI=01 REQ=N
Alloc Qty 30 DFI=30 REQ=N
Deliv Qty 30 DFI=30 REQ=N
Insp. Qty 30 DFI=30 REQ=N
Lot Qty 30 DFI=30 REQ=N
Miss Qty 30 DFI=30 REQ=N
Rcpt Qty 30 DFI=30 REQ=N
Req Qty 30 DFI=30 REQ=N
Ship Qty 30 DFI=30 REQ=N
Total Qty 30 DFI=30 REQ=N
Ship Qty 30 DFI=30 REQ=N
Acc Qty 30 DFI=30 REQ=N
Rej Qty 30 DFI=30 REQ=N
Ea Lot Qty 30 DFI=30 REQ=N
Qty 30 DFI=30 REQ=N
Res Qty 30 DFI=30 REQ=N
Split Qty 30 DFI=30 REQ=N
Ret Qty 30 DFI=30 REQ=N
From SN 21 DFI=21 REQ=N
To SN 21 DFI=21 REQ=N
SN 21 DFI=21 REQ=N
Serial 21 DFI=21 REQ=N
SN 21 DFI=21 REQ=N
From Lot 10 DFI=10 REQ=N
To Lot 10 DFI=10 REQ=N
Res Lot 10 DFI=10 REQ=N

Sample Java Code

The following is sample Java Code for handling scanned input from a concatenated UCC-128 barcode symbol. Please note the following code has been provided to demonstrate the customizable barcode scanning functionality. Oracle is not responsible for maintaining it. The following code can be modified and distributed without permission from Oracle.

                           |+======================================================+
|  FILENA

ME |

| ScanManager.java |

| DESCRIPTION |

|Class to manage the scans. It will pre-process the | scans. |

| |

|  NOTES                                                                    |

|  DEPENDENCIES                                                             |

|  HISTORY                                                                  |

|       10-Oct-02 Karun Jain     created.                                   |
 +=====================================================*/
package xxx.custom;
import oracle.apps.mwa.container.*;
import oracle.apps.mwa.beans.*;
import java.util.*;
import java.sql.*;
/**
* <code>CustomScanManager</code> is the customizable 
* call out to pre-process a scanned barcode.
* It has reference to the current MWA Session, and the  
* page the scan was performed on. One can access the    
* database session using the MWA
* session passed in. Please refer to the MWA API         
* documentation or the WMS Customization document for      
* more information and ways to customize the class.
**/
public class CustomScanManager {
  private void CustomScanManager() {};
  public static boolean isInputableField(FieldBean f) {    
    if ((f instanceof InputableFieldBean) && (((InputableFieldBean) f).isEditable()))
      return true;
    else
      return false;
  }
/**
* This is a customizable method. 

**/
/**
* In this example we have scanned a concatenated UCC128 
* barcode which has Item, quantity, lot_number and 
* lot_quantity.
* With one scan we want to populate all the above fields 
* on the PO Receipt page.
* It returns the value to be set for the current field: 
* in our example is item.
**/
// curtPage passes the current MWA Page
// curtSession passes the java session
// val has the value that was scanned
  public static String processScan(oracle.apps.mwa.container.Session curtSession,
   oracle.apps.mwa.beans.PageBean curtPage,
   java.lang.String val) {
// This will log a message in the server trace file if // you have the MWA server running in the trace mode. 
// Pleade preceede your messages with CTM.
    FileLogger.getSystemLogger().trace("CTM: Pre-preocessing the scan");
    FieldBean curtBean = curtPage.getCurrentFieldBean();
    if (curtBean instanceof oracle.apps.inv.lov.server.ItemLOV) {
      int itemFieldIndex = curtPage.getCurrentFieldIndex();
      String itemValue = val;
      String [] curtFieldDFIs = null;
      int intemDFILength = 0;
      if (isInputableField(curtBean)) {
curtFieldDFIs = ((InputableFieldBean)curtBean).getDFIs();
int itemDFILength = 0;
if (curtFieldDFIs != null) {
// if prefix of value is in curt field DFI, strip it, 
// and setFieldValue
  for (int i=0; i < curtFieldDFIs.length; i++) {
    int x = itemValue.indexOf(curtFieldDFIs[i]);
    if (x == 0) {
// found a DFI in the value, let's strip it
      itemDFILength = curtFieldDFIs[i].length();
      FileLogger.getSystemLogger().trace("CTM: found matching Item DFI "+ curtFieldDFIs[i]);
      FileLogger.getSystemLogger().trace("CTM: Item DFI Length: "+ itemDFILength);
      break;
    }
  }
// After stripping the DFI only the first 14 characters // are for item Process the remaining characters for the // remaining fields
  if (itemValue.length() > (14+itemDFILength)) {
    Vector fieldBeanList = curtPage.getFieldBeanList();
    int qtyFieldIndex = 0;
    int lotNumFieldIndex = 0;
    int lotQtyFieldIndex = 0;
// Get the index for the other three fields from the 
// list of fields
    for (int i=itemFieldIndex; i<fieldBeanList.size(); i++) {
      String name = ((FieldBean)fieldBeanList.elementAt(i)).getName();
      if (name != null && name.equals("INV.QTY"))
qtyFieldIndex = i;
      if (name != null && name.equals("INV.LOT"))
lotNumFieldIndex = i;
      if (name != null && name.equals("INV.LOT_QTY"))
lotQtyFieldIndex = i;
    }
// Get the value for the item field
    String remainingValue = itemValue.substring(14+itemDFILength);
    itemValue = itemValue.substring(0,(14+itemDFILength));
    FileLogger.getSystemLogger().trace("CTM: Item value: "+ itemValue);
    FileLogger.getSystemLogger().trace("CTM: Remaining value: "+ remainingValue);
    String qtyValue = "";
// Found qty field so set the value for the quantity
    if (qtyFieldIndex > 0) {
      FileLogger.getSystemLogger().trace("CTM: Found the qty field");
      boolean doneQty = false;
      String [] qtyFieldDFIs = null;
      FieldBean qtyField = ((FieldBean)(fieldBeanList.elementAt(qtyFieldIndex)));
      if (isInputableField(qtyField)) {
qtyFieldDFIs = ((InputableFieldBean)qtyField).getDFIs();
if (qtyFieldDFIs != null) {
// if prefix of value is in curt field DFI, strip it,
// and setFieldValue
  FileLogger.getSystemLogger().trace("CTM: Got the dfi for qty fld");
  for (int j=0; j < qtyFieldDFIs.length; j++) {
    int x = remainingValue.indexOf(qtyFieldDFIs[j]);
    FileLogger.getSystemLogger().trace("CTM: "+j+"th DFI:"+qtyFieldDFIs[j]);
    if (x == 0) {
// found a DFI in the value, let's strip it
      qtyValue =
remainingValue.substring(x+qtyFieldDFIs[j].length(), 
 x+qtyFieldDFIs[j].length()+6);
      ((InputableFieldBean)qtyField).setValue(qtyValue);
      FileLogger.getSystemLogger().trace("CTM: Qty value:"+qtyValue);
      if (remainingValue.length() >
  (qtyFieldDFIs[j].length()+6)) {
doneQty = true;
remainingValue =
  remainingValue.substring(x+qtyFieldDFIs[j].length()+6);
FileLogger.getSystemLogger().trace("CTM: Remaining value:"+remainingValue);
      } else remainingValue = "";
      break;
    }
  }
}
      }
// Set the value for the lot number and lot qty field
      if (doneQty && lotNumFieldIndex > 0) {
FileLogger.getSystemLogger().trace("CTM: Found the lot Num field");
((InputableFieldBean)(fieldBeanList.elementAt(lotQtyFieldIndex))).setValue(qtyValue);
FieldBean lotNumField = ((FieldBean)(fieldBeanList.elementAt(lotNumFieldIndex)));
String [] lotNumFieldDFIs = null;
if (isInputableField(lotNumField)) {
  lotNumFieldDFIs = ((InputableFieldBean)lotNumField).getDFIs();
  if (lotNumFieldDFIs != null) {
// if prefix of value is in curt field DFI, strip it, 
// and setFieldValue
    for (int j=0; j < qtyFieldDFIs.length; j++) {
      int x = remainingValue.indexOf(lotNumFieldDFIs[j]);
      if (x == 0) {
// found a DFI in the value, let's strip it
String lotNumValue =
  remainingValue.substring(x+lotNumFieldDFIs[j].length());
((InputableFieldBean)lotNumField).setValue(lotNumValue);
FileLogger.getSystemLogger().trace("CTM: Lot value:"+lotNumValue);
      }
    }
  }
}
      }
    }
  }
}
      }
      return itemValue;
    } else {
      return val;
    }
  }
}