Version 1.0

The code work with GS1 Datamatrix barcodes used on the medicine packs as per EU FMD guidelines. This version does not support the PPN barcodes.
This commit is contained in:
PinchofLogic 2021-08-13 01:31:05 +01:00 committed by GitHub
parent a01d8d1c2f
commit 86a8376291
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 130 additions and 0 deletions

28
expiry_date_validation.py Normal file
View File

@ -0,0 +1,28 @@
from datetime import datetime
def expiry_date_check(e:str):
my_year = e[:2]
my_month = e[2:4]
my_date = e[4:]
if (int(my_month) not in range(1,13)):
return False
elif (int(my_date) not in range(32)):
return False
if my_date == '00':
if my_month == '02' and int(my_year) % 4 == 0:
my_date = '29'
elif my_month == '02' and int(my_year) % 4 != 0:
my_date = '28'
elif my_month in ['01', '03', '05', '07', '08', '10', '12']:
my_date = '31'
else:
my_date = '30'
actual_date = my_year + my_month + my_date
if actual_date > datetime.today().strftime('%y%m%d'):
return True
else:
return False

11
gs1_gtin_validation.py Normal file
View File

@ -0,0 +1,11 @@
"""
The function perform validation on the GS1-GTIN(14)
"""
def gtin_check(g: str):
digit_sum = (int(g[0]) * 3) + int(g[1]) + (int(g[2]) * 3) + int(g[3]) + (int(g[4]) * 3) + int(g[5]) + (int(g[6]) * 3) + int(g[7]) + (int(g[8]) * 3) + int(g[9]) + (int(g[10]) * 3) + int(g[11]) + (int(g[12]) * 3)
nearest_ten = round(digit_sum/10) * 10
check_sum_digit = nearest_ten - digit_sum
return check_sum_digit == int(g[-1])

91
pharma_datamatrix.py Normal file
View File

@ -0,0 +1,91 @@
"""
The function parse the GS1 Datamatrix barcode used for medicine packs.
The barcodes output is in below format:
]d201034531200000111719112510ABCD1234<GS>2110EW354EWER
(01)03453120000011(17)191125(10)ABCD1234<GS>(21)10EW354EWER
(01) = GTIN Identifier - Fixed 14 chars
(17) = Expiry Date Identifer - Fixed 6 Chars
(10) = Batch Identifier - Variable length. (upto 20 chars usually between 4 - 10 Chars)
(21) = Serial Number - Variable length. (upto 20 chars - Usually between 12 - 20 Chars)
The symbology identifier ]d2 and for the second FNC1, when used as a separator character is <GS> Group-Separator.
"""
from gs1_gtin_validation import gtin_check
from expiry_date_validation import expiry_date_check
def pharma_datamatrix(barcode: str, validation: bool = False):
result = dict()
result['NHRN'] = None
if barcode[:3] == ']d2':
barcode = barcode[3:]
while barcode:
if barcode[:2] == '01':
result['GTIN'] = barcode[2:16]
barcode = barcode[16:]
elif barcode[:2] == '17':
result['EXPIRY'] = barcode[2:8]
barcode = barcode[8:]
elif barcode[:2] == '10':
if chr(29) in barcode:
for i, c in enumerate(barcode):
if ord(c) == 29:
result['BATCH'] = barcode[2:i]
barcode = barcode[i+1:]
break
else:
result['BATCH'] = barcode[2:]
barcode = None
elif barcode[:2] == '21':
if chr(29) in barcode:
#print("In the serial GS check")
for i, c in enumerate(barcode):
if ord(c) == 29:
result['SERIAL'] = barcode[2:i]
barcode = barcode[i+1:]
break
else:
result['SERIAL'] = barcode[2:]
barcode = None
elif barcode[:3] in ['710', '711', '712', '713', '714']:
if chr(29) in barcode:
for i, c in enumerate(barcode):
if ord(c) == 29:
result['NHRN'] = barcode[2:i]
barcode = barcode[i+1:]
break
else:
result['NHRN'] = barcode[2:]
barcode = None
else:
return f"Not a valid barcode"
if validation:
if gtin_check(result['GTIN']) == False and expiry_date_check(result['EXPIRY']) == False:
return f'INVALID GTIN & EXPIRY DATE'
elif expiry_date_check(result['EXPIRY']) == False:
return f'INVALID EXPIRY DATE'
elif gtin_check(result['GTIN']) == False:
return f'INVALID GTIN'
else:
return result
else:
return result
result = pharma_datamatrix("01083860077038511724013110HN5R21587E4RT10P")
print(result)