jodal / biip

📦 Biip interprets the data in barcodes.
https://biip.readthedocs.io
Apache License 2.0
44 stars 3 forks source link

Additional_ID parsing (code 240) #296

Closed kozki closed 1 month ago

kozki commented 2 months ago

Hi,

I am parsing UDIs and can parse product_number (01), serial_number (21), lot_number (10), expiration and manufacture date (17, 11), but I cannot parse additional_id (240) from the UDI. I managed to fix that by adding the separator '\x1d' before the '240' in UDI, but sometimes the string '240' appears more than once or not in the spot for the additional_id. Examples:

UDI = '0104062102661608112405271727112710S2400424282400522010301NNN003'

If I don't add a separator, the response is just GS1Message class, and I can only get product_number:

<class 'biip.gs1._messages.GS1Message'>

{'product_number': '04062102661608', 'serial_number': None, 'lot_number': None, 'expiration_date': None, 'manufacture_date': None, 'additional_id': None}

If I add a separator, then I get everything correct:

GS1Message(value='0104062102661738112401241727072410S230091624\x1d2400523000302NNN003', element_strings=[GS1ElementString(ai=GS1ApplicationIdentifier(ai='01', description='Global Trade Item Number (GTIN)', data_title='GTIN', fnc1_required=False, format='N2+N14'), value='04062102661738', pattern_groups=['04062102661738'], gln=None, gln_error=None, gtin=Gtin(value='04062102661738', format=GtinFormat.GTIN_13, prefix=GS1Prefix(value='406', usage='GS1 Germany'), company_prefix=GS1CompanyPrefix(value='4062102'), payload='406210266173', check_digit=8, packaging_level=None), gtin_error=None, sscc=None, sscc_error=None, date=None, decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='11', description='Production date (YYMMDD)', data_title='PROD DATE', fnc1_required=False, format='N2+N6'), value='240124', pattern_groups=['240124'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=datetime.date(2024, 1, 24), decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='17', description='Expiration date (YYMMDD)', data_title='USE BY OR EXPIRY', fnc1_required=False, format='N2+N6'), value='270724', pattern_groups=['270724'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=datetime.date(2027, 7, 24), decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='10', description='Batch or lot number', data_title='BATCH/LOT', fnc1_required=True, format='N2+X..20'), value='S230091624', pattern_groups=['S230091624'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=None, decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='240', description='Additional product identification assigned by the manufacturer', data_title='ADDITIONAL ID', fnc1_required=True, format='N3+X..30'), value='0523000302NNN003', pattern_groups=['0523000302NNN003'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=None, decimal=None, money=None)])

{'product_number': '04062102661738', 'serial_number': None, 'lot_number': 'S230091624', 'expiration_date': datetime.date(2027, 7, 24), 'manufacture_date': datetime.date(2024, 1, 24), 'additional_id': '0523000302NNN003'}

So basically, is there something wrong with my UDI, is there something missing?

Thanks!

jodal commented 1 month ago

AI 240 is a variable length field, and thus it requires a FNC1 control character, unless it is the last AI element in the barcode data. In a barcode with two AI 240 elements, a FNC1 character in between the two are required for the barcode to be valid and possible to parse unambiguously.

First of all, I'd use a phone app to scan the barcode and check that the barcode actually contains an FNC1 character. In one phone app I use, this is often showed as a blank space. See #137 for a similar case and an app recommendation. If you can share a photo of the barcode in question here, I can have a look as well.

If the barcode itself is in order, you probably need to configure your hardware barcode scanner to include the FNC1 character (byte 0x1d by default) or substitute it with another character (e.g. |). If you substitute it, you must tell Biip about what character to look for via the separator_chars argument. See https://biip.readthedocs.io/en/stable/quickstart/#variable-length-fields for more on this.

jodal commented 1 month ago

As I haven't heard back from you, I'm closing this issue. Feel free to start a discussion (as opposed to an issue) if you need further help with this.