GrammarsRecorddefs - skilchen/bots GitHub Wiki
Recorddefs
Definition: Recorddefs defines the layout of each record.
Recorddefs is required, except for grammars for editypes 'templatehtml', 'xmlnocheck', 'jsonnocheck'.
Recorddefs is a dictionary; key is record ID/tag, value is list of fields.
There is always a field 'BOTSID' in a record; mostly BOTSID is the first field (fixed format is the exception).
Some specifics for different editypes
-
edifact: record ID is edifact tag (DTM, BGM, etc).
-
X12: record ID is the segment identifier
-
Xml: record ID is xml-tag (without angle brackets).
-
Fixed: bots has to know where record ID is. Default: first three positions in record; this can be set with syntax parameters
-
Csv: Csv/Excel does not always have a record ID (all records in an edi-file are of the same type). Bots uses the name of the record as BOTSID if you use syntax parameter:
'noBOTSID':True
For each field
Each field is a list of:
-
field ID; has to be unique (bots checks for this).
-
M/C: mandatory or conditional.
-
length. Examples:
['field name','C', 9, 'A'], #max length ['field name','C', (3,9), 'A'], #min length, max length. Use eg as: ['field name','C', (9,9), 'A'], #field length should always be 9 ['field name','C', 8.3, 'N'], #length max 8 field, must have 3 decimals.
-
format. Different per editype. Especially edifact, x12 and tradacoms have their own formatting codes, just use these. For csv, fixed, xml etc no standard formats exists, so bots uses these formats:
-
A (or AN): alphanumeric.
-
AR: right aligned alphanumeric (fixed only)
-
N: fixed decimals
- Numeric
- Fixed numbers of decimals. If no decimals are indicated: integer
- Incoming: format is checked.
- Outgoing: bots formats this (rounding if needed, add leading zeros)
-
NL: (for fixed only) as fixed decimals, left aligned, trailing blancs
-
NR: (for fixed only) as fixed decimals, right aligned, leading blancs
-
R: floating point
- Numeric
- May have any number of decimals
- Bots does no checking of formatting.
-
RL: (for fixed only) as floating point, left aligned, trailing blancs
-
RR: (for fixed only) as floating point, left aligned, leading blancs
-
I: fixed decimals implicit. Example:
['field name','C', 8.2, 'I'], #max 8 long, last 2 positions are decimals; eg for an amount. #Valid is eg: 12345 #Bots converts this to 123.45 (and vice versa)
- Numeric
- Fixed number of decimals. Is converted from/to 'normal' amount; rounded if outgoing.
- There is no decimal sign in the field, the number of decimals is implicit from the definition. Eg:
- Can be negative
-
D (or DT): date. Either 6 or 8 positions; format YYMMDD or CCYYMMDD. Bots checks for valid dates both in- en outgoing.
-
T (or TM): time. Either 4 or 6 positions; format HHMM or HHMMSS. Bots checks for valid times both in- en outgoing.
-
Composite fields
Edifact, x12 and tradacoms have composite fields. Example:
['S005', 'C', #composite field
[
['S005.0022', 'M', 14, 'AN'], #subfield nr1
['S005.0025', 'C', 2, 'AN'], #subfield nr2
]],
A composite has:
- field ID; has to be unique (bots checks for this).
- M/C (mandatory/conditional).
- a list of subfields.
Note: Bots requires that each composite ID and sub-field has an unique ID. If a composite occurs more than once, do eg like:
['C090', 'C', [ #composite contains 2 subfields with same ID
['C090.3286#1', 'M', 70, 'AN'],
['C090.3286#2', 'C', 70, 'AN'],
]],
['C542#1', 'M', [ #composite occurs twice
['C542.9425#1', 'M', 3, 'AN'],
['C542.9424#1', 'C', 35, 'AN'],
]],
['C542#2', 'C', [ #composite occurs twice
['C542.9425#2', 'M', 3, 'AN'],
['C542.9424#2', 'C', 35, 'AN'],
]],
Details of field format handling
- M/C of fields are always checked.
- min/max length of field are always checked.
- numerical:
- '-' is accepted both at beginning and end. Bots outputs only leading '-'
- '+' is accepted at beginning. Bots does not output '+'
- thousands separators are removed if specified in syntax-parameter 'triad' (see above).
- Bots does not output thousands separators
- default decimal separator is '.'; use syntax-parameter 'decimaal' to change this ('decimaal' is Dutch, sorry about that. Noticed to late to change ;-)). Internally bots only uses/accepts decimal point!
- (incoming) leading zeros are removed
- (incoming) trailing zeros are kept
- '.45' is converted to '0.45'.
- '4.' is converted to '4'.
- Note that eg edifact numeric lengths do NOT include decimal sign and negative...
Utility for positions in fixed records
A grammar does not contains the position/offset of each field in a fixed record, but it sure is useful to have this. Add this code to the bottom of the grammar and run/execute the code:
if __name__ == "__main__":
for key, record in recorddefs.items():
length = 0
for field in record:
print ' ', field, ' #pos',length+1, length + field[2]
length += field[2]
print 'Record',key,' has length ',length, '\n'
Slightly different version - output can be pasted back into grammar
if __name__ == "__main__":
space = 0
for key, record in recorddefs.items():
for field in record:
space = max(space,len(str(field))+1)
for key, record in recorddefs.items():
length = 0
print ' \'' + key + '\':['
for field in record:
print ' ', (str(field) + ',').ljust(space), ' # pos',length+1, '-', length + field[2]
length += field[2]
print ' ],'