Introduction
This document outlines how barcode processing works in the Android version of the Warehousing app. It will detail what happens when a barcode is scanned, supported scanner manufacturers and models, how the scanner can be configured and tested in the app and how the scanned data links with information sent to the app from Business Central.
It is useful to understand barcode symbology’s before reading this document. A symbology is how the pattern in a barcode is converted to / from the data it represents. On top of this the data may or may not be in GS1 format. The GS1 specification allows you to pair data to specific categories. You can include more than one of these in an individual barcode. For example, using the GS1 specification you can include the lot number and expiration date in a single barcode. The GS1 specification is not a symbology – it is a formatting specification for the data that sits on top of the symbology.
Operations in the Warehouse app are driven by a list of data items. For example, a receipt will contain a list of data items specifying what data the app needs to get from the user in order to process the receipt. Each data item may contain one or more GS1 identifiers. When a barcode containing GS1 formatted data is scanned by the app it will check each data item to see if it contains a GS1 identifier that matches a field contained in the barcode. If it does, then the value of that data item is set to the value of that field and the data items are submitted to the server.
GS1 Data and Processing Logic
Format of GS1 barcodes
GS1 barcodes allow you to store data for several fields in a single barcode. For example, you could store the item number and serial number in a single barcode instead of generating a barcode for each field. This has obvious efficiency gains in that a single scan, and a single round trip to the server, can be used instead of separate scans for each field.
The GS1 data format uses Application Identifiers (henceforth called AIs) to store the data for each field. Different fields have different AIs. A full list can be seen at https://www.gs1.org/standards/barcodes/application-identifiers The Warehouse app only supports a subset of these AIs – see Appendix 1 for a list of these AIs. AIs fall into two categories – fixed length and variable length. Fixed length items have their length set in the GS1 specification – for example expiration dates are set to be 6 characters long. Variable length items are ended by a delimiter (typically ASCII character 29) or the end of the barcode if a delimiter is not present.
The below diagram illustrates the format of a GS1 barcode:
All GS1 barcodes start with a FNC1 character. Following that there must be an AI. If an AI is not present, then it is not a valid GS1 barcode. Following that is the data for that AI – if it is fixed length then the next n characters are read where n is the length from the GS1 specification. If it is variable length, then characters are read until a delimiter or the end of the barcode is encountered. In our example the barcode’s first AI is for the variable length Serial No. field (21). So, the data is read up to the delimiter to give ‘SERIALNO’.
If there is any data after the end of the last AI’s data, then the process is repeated (excluding the FNC1 check). In our example the next AI is for the fixed length Global Trade Item Number field (01) which must be 14 characters long. The data for this field is ‘GLOBALTRADEITE’.
NB: The text below the barcode is in human readable form. The actual data does not contain the brackets around the AIs. The delimiter (ASCII 29) is also not a visible character in text representations of the data.
Processing Logic for GS1 barcodes
The below flow chart displays the logic for parsing a GS1 barcode in the Warehouse App:
There are a few points to make about the GS1 parsing logic:
-
As previously mentioned GS1 barcodes start with a FNC1 character. Some barcode readers strip this out when the barcode is read but some do not. Also, barcodes may contain GS1 data but omit the FNC1 if they have not been produced in accordance with the GS1 specification (‘nonstandard’ mode). Therefore, the first step is to check whether this character exists at the start of the barcode, and to remove it if it does. This character is set to ‘]C1’ but it can be overridden in the settings (see the ‘Scanner Setup’ section) if a customer has used an incorrect character when generating their barcodes.
-
The next step is to see if the next 2, 3 or 4 characters match one of the supported application identifiers. If they do not, then the barcode is not valid, and it is not processed as GS1.
-
If an application identifier is detected it falls into two categories:
-
Fixed length identifiers. In this case the GS1 specification says the data must be a specified length – for example Global Trade Item Numbers must be 14 characters long. In this case the parser will read the required number of characters from the data. If there is not enough data present (for example 14 characters are required in the specification but there are only 12 present) the parser reads the characters that are present and still says the barcode is valid GS1 data.
-
Variable length identifiers. In this case the parser reads the data after the identifier until it encounters the delimiter (a gsep or FNC1) or the end of the data.
-
-
At the end of the process a series of AIs are returned along with the data extracted from the barcode for each AI.
Processing Logic
The below flow chart displays what the warehouse app does when it receives a barcode from the scanner.
The app supports ‘strict’ (StandardGS1) and ‘non strict’ (NonStandardGS1) processing modes. If the scanner does not say it is a GS1 formatted barcode the data may nevertheless still be GS1 compliant. If the app is set to non-standard mode it will try and process this data as GS1 even if the scanner says it is not a GS1 barcode. If parsing the data as GS1 fails, the entire text from the barcode is assigned to the current data item.
If the barcode is parsed successfully as GS1 data, the parser returns a list of the AIs present and their data. These are then checked against the data items in the current operation. If a scanned AI matches the AI for a data item, then the value of that data item is set to the data for that AI. Appendix 3 lists the AIs that are defined for each operation.
Supported Scanners
The Warehouse app can work with Honeywell and Zebra scanners. The below tables say which scanners should work with the app according to the manufacturer’s documentation, and which scanners we have actually tested.
Honeywell Scanners
We use version 1.31 of the Honeywell Barcode reader SDK. This supports the below models:
Model Name | Android Version | Tested | Notes |
---|---|---|---|
CN51 | Marshmallow | Y | |
CN75, CN75e, CK75 | Marshmallow | ||
Dolphin CN80 | Nougat | ||
Dolphin CT50 | KitKat, Marshmallow | ||
Dolphin CT60 | Nougat | ||
Dolphin 75e | KitKat, Marshmallow | ||
EDA50, EDA50K, EDA70 | Nougat | ||
EDA60K | Nougat | Y | This device is not listed in the release notes from the Honeywell SDK but it works |
NB: That some Honeywell scanners are not configured to return the GS1 delimiter by default – so parsing of variable length GS1 data may give incorrect results. To enable the scanner to return this delimiter scan this barcode:
Zebra Scanners
We use version 4 of the Zebra SDK (Symbol. Xamarin EMDK). This supports the below models:
Model Name | Android Version | Tested | Notes |
---|---|---|---|
MC33 | Nougat, Oreo | Y | |
PS20 | Oreo | ||
TC20 | Nougat | ||
TC25 | Nougat | ||
TC51 | Marshmallow, Nougat | ||
TC52 | Oreo | ||
TC56 | Marshmallow, Nougat | ||
TC57 | Oreo | ||
TC70x | Marshmallow, Nougat | ||
TC72 | Oreo | ||
TC75x | Marshmallow, Nougat | ||
TC77 | Oreo | ||
VC80x | Nougat | ||
WT6000 | Nougat | ||
RS507 | - | ||
RS6000 | - | ||
RS5000 | - | ||
RS4000 | - | ||
DS2278 | - | ||
DS3678 | - | ||
DS3608 | - | ||
LI3608 | - | ||
LI3678 | - | ||
TC8000 | Lollipop | Y | This device is supported in a previous version of the Zebra SDK. It works with V4 of the SDK, but not all barcode formats in V4 of the SDK are supported (it does not support Gs1DataMatrix and Gs1QRCode) |
Android Scanners
We support version 4.1 and above.
Scanner Set Up
In the Warehouse app the scanner can be configured in the Device tab of the settings screen:
The fields are:
-
Manufacturer – this lets you choose the scanner you wish to use. What you can choose depends on the device the app is running on. If the device has a camera one of the options will be Camera – this will use the Android camera and the ZXing barcode library. If the device has a built-in scanner then this will be selected by default.
-
Barcode Processing – whether to use ‘StandardGS1’ (strict) or NonStandardGS1 (non-strict) mode when processing a barcode. See the flowchart earlier in Processing Logic for how it affects the processing.
-
Alternative FNC1 – if this is populated then the value entered is used instead of the normal FNC1 when a barcode is processed.
If nothing is chosen in the Manufacturer field, then no barcodes will be processed in the app. There is a distinction between scanners that can be started automatically (e.g. built in scanners) and those that need to be triggered by the user (e.g. the device’s camera.) The automatic scanners are enabled in the background when barcode input is appropriate - the user then just scans a barcode using the trigger on the device. For the manual scanners a button is added to the user interface which the user must tap to open the scanner.
The app detects which scanners are present automatically, with one caveat. When the method in the Honeywell SDK to detect the scanners runs on a non-Honeywell device it crashes the thread the detection processes runs on, meaning no scanners are detected. To get around this the Honeywell detection only runs on devices whose manufacturer is a known Honeywell manufacturer. Currently these include Honeywell and Foxconn. If in future another manufacturer needs to be supported, they can be added to by putting an XML file in the below format at Android/data/com.tecman.Warehouse/files/HoneywellDeviceNames.xml
Scanner Diagnostics
The app contains a diagnostic facility (as of version 1.0.12.0) which lets the user scan a barcode and see how the app has processed it. It can be accessed from the main menu by viewing going to the hidden buttons (drag the left-hand side of the screen to the right) and selecting ‘Scanner Diagnostics.’ It uses the scanner that has been set up in the settings screen, if a scanner has not been configured in the app it will display a message advising you of this.
This screen contains a Supported GS1 Idents button. Tapping this displays a list of app idents supported by the app (see appendix 1 for a list of these).
If the scanner is an automatically starting one (e.g. a built-in scanner) a label will be displayed asking you to scan a barcode. Otherwise (e.g. for a scanner using the camera) a button is displayed which needs to be tapped for you to scan a barcode.
The screen also displays the selected scanner and the GS1 option:
After a barcode has been scanned the symbology, data format (GS1 or text) and raw text are displayed, and whether it was parsed as a GS1:
If the barcode was parsed as a GS1 the values for each detected app ident are displayed.
Appendix 1 – supported application identifiers in the app
The below table displays the AIs currently supported (as of version 1.0.12.0) in the Warehouse app.
Code | Description | Length | Divisor |
---|---|---|---|
00 | Serial shipping container code (SSCC) | 18 | N/A |
01 | Global trade item number (GTIN / SSC) | 14 | N/A |
02 | GTIN of contained trade items | 14 | N/A |
10 | Batch or lot number | Variable (20) | N/A |
11 | Production Date | 6 (YYMMDD) | N/A |
15 | Best before date | 6 (YYMMDD) | N/A |
17 | Expiration date | 6 (YYMMDD) | N/A |
21 | Serial number | Variable (20) | N/A |
240 | Additional product identification assigned by the manufacturer | Variable (30) | N/A |
243 | Packaging component number | Variable (20) | N/A |
30 | Variable count of items (quantity) | Variable (8) | N/A |
3100 | Net weight (kg) | 6 | N/A |
3101 | Net weight (kg) | 6 | 10 |
3102 | Net weight (kg) | 6 | 100 |
3103 | Net weight (kg) | 6 | 1000 |
3104 | Net weight (kg) | 6 | 10000 |
3105 | Net weight (kg) | 6 | 100000 |
3106 | Net weight (kg) | 6 | 1000000 |
3107 | Net weight (kg) | 6 | 10000000 |
3108 | Net weight (kg) | 6 | 100000000 |
3109 | Net weight (kg) | 6 | 1000000000 |
37 | Count of trade items (quantity) | Variable (8) | N/A |
403 | Routing code | Variable (30) | N/A |
91 | Company internal information (weight) | 1 | N/A |
If the divisor field is set then the value for that application identifier is divided by the divisor’s value. For example, if the value for the AI 3103 is 1568 then the parser will return 1568 / 1000 = 1.568.
See https://www.gs1.org/standards/barcodes/application-identifiers for more information about GS1 identifiers.
The list of supported identifiers can also be viewed in the app by swiping in from the left-hand edge of the screen and tapping on “Scanner Diagnostics”
Swipe in from the left to reveal the About and Scanner Diagnostics options
Options to list the supported GS1 identifiers and to scan a barcode and read the identifiers and values that have been recognized in the barcode
Appendix 2 – Supported Symbology Mappings for Scanners
This lists the symbology specifier returned by each scanner and what they are converted to for use in the app.
Honeywell
Honeywell Output | App Symbology | App Datatype |
---|---|---|
2 | Aztec | Text |
5 | ChinaPost | Text |
6 | Codabar | Text |
7 | CodablockA | Text |
8 | CodablockF | Text |
9 | Code11 | Text |
11 | Code93 | Text |
12 | Code128 | Text |
13 | Code128 | Text |
14 | Isbt128 | Text |
15 | Datamatrix | Text |
16 | Ean8 | Text |
17 | Ean13 | Text |
25 | Interleaved25 | Text |
26 | Matrix25 | Text |
27 | Standard25 | Text |
29 | KoreanPost | Text |
30 | Maxicode | Text |
31 | MicroPdf417 | Text |
32 | Msi | Text |
33 | Pdf417 | Text |
36 | QrCode | Text |
38 | Telepen | Text |
39 | Tlc39 | Text |
40 | Trioptic | Text |
41 | UpcA | Text |
42 | UpcE | Text |
44 | lata25 | Text |
21 | RSS | Text |
Note the EDA60 only supports 2D barcodes.
Zebra
Zebra Output | App Symbology | App Datatype |
---|---|---|
aztec | Aztec | Text |
chinese2of15 | ChinaPost | Text |
codabar | Codabar | Text |
compositec | Compositec | GS1 |
compositeab | Compositeab | GS1 |
code11 | Code11 | Text |
code93 | Code93 | Text |
code128 | Code128 | GS1 |
ean128 | Code128 | Text |
datamatrix | Datamatrix | Text |
ean8 | Ean8 | Text |
ean13 | Ean13 | Text |
i2of5 | Interleaved25 | Text |
matrix2of5 | Matrix25 | Text |
isbt128 | Isbt128 | Text |
korean3of5 | KoreanPost | Text |
maxicode | Maxicode | Text |
micropdf | MicroPdf417 | Text |
msi | Msi | Text |
pdf417 | Pdf417 | Text |
qrcode | QrCode | Text |
tlc39 | Tlc39 | Text |
trioptic39 | Trioptic39 | Text |
upca | UpcA | Text |
upce0 | UpcE | Text |
Iata2of5 | Iata25 | Text |
gs1_databar | RSS | GS1 |
gs1_databar_exp | RssExpanded | GS1 |
gs1_databar_lim | RssLimited | GS1 |
gs1datamatrix | DataMatrix | GS1 |
gs1qrcode | QRCode | GS1 |
ZXing (Android Camera)
ZXing Format | App Symbology | App Datatype |
---|---|---|
Aztec | Aztec | Text |
Codabar | Codabar | Text |
Code_128 | Code128 | * |
Code_93 | Code93 | Text |
Data_Matrix | Datamatrix | Text |
Ean_8 | Ean8 | Text |
Ean_13 | Ean13 | Text |
MAXICODE | Maxicode | Text |
MSI | Msi | Text |
PDF_417 | Pdf417 | * |
QR_Code | QrCode | Text |
RSS_14 | Rss | Text |
RSS_EXPANDED | RssExpanded | * |
UPC_A | UpcA | Text |
UPC_E | UpcE | Text |
ITF | Interleaved25 | Text |
* The app checks if the barcode starts with a FNC1 character. If it does it sets the data type as GS1. The ZXing library does not detect GS1 formatted data.
Appendix 3 – App Ident Mappings in Clever WMS Devices
Below are tables for various functions detailing which AIs are mapped to which data items in version 7.1.2.0 of Clever WMS Devices.
Pick, Express Pick, Directed Movement and Movement
Data Item | Application Identifier | Application Identifier Code |
---|---|---|
ItemNo | SCC | 01 |
ItemNo | AddlProduct | 240 |
ItemNo | SSCTradeItems | 02 |
LotNo | BatchNumber | 10 |
SerialNo | SerialNumber | 21 |
Production Consumption
Data Item | Application Identifier | Application Identifier Code |
---|---|---|
CompItemNo | SCC | 01 |
CompItemNo | AddlProduct | 240 |
ItemNo | SSCTradeItems | 02 |
LotNo | BatchNumber | 10 |
SerialNo | SerialNumber | 21 |
Assembly Order
Data Item | Application Identifier | Application Identifier Code |
---|---|---|
ComponentNo | SCC | 01 |
ComponentNo | AddlProduct | 240 |
ComponentNo | SSCTradeItems | 02 |
Receipt
Data Item | Application Identifier | Application Identifier Code |
---|---|---|
ItemNo | SCC | 01 |
ItemNo | AddlProduct | 240 |
ItemNo | SSCTradeItems | 02 |
LotNo | BatchNumber | 10 |
SerialNo | SerialNumber | 21 |
ScannedExpirationDate | ExpirationDate | 15 or 17 |
Quantity | Quantity | 37 |
Item Attribute, Item Photo, Add Bins, Item Substitution and Item Cross Reference
Data Item | Application Identifier | Application Identifier Code |
---|---|---|
ItemNo | SCC | 01 |
ItemNo | AddlProduct | 240 |
ItemNo | SSCTradeItems | 02 |
Physical Inventory, Put Away and Inventory Put Aways
Data Item | Application Identifier | Application Identifier Code |
---|---|---|
ItemNo | SCC | 01 |
ItemNo | AddlProduct | 240 |
ItemNo | SSCTradeItems | 02 |
LotNo | BatchNumber | 10 |
SerialNo | SerialNumber | 21 |
ScannedExpirationDate | ExpirationDate | 15 or 17 |
Production Output
Data Item | Application Identifier | Application Identifier Code |
---|---|---|
LotNo | BatchNumber | 10 |
SerialNo | SerialNumber | 21 |
ScannedExpirationDate | ExpirationDate | 15 or 17 |
Quantity | Quantity | 37 |