├── .gitignore ├── LICENSE ├── README.md ├── pythonedi ├── EDIGenerator.py ├── EDIParser.py ├── __init__.py ├── debug.py ├── formats │ ├── 810.json │ ├── 850.json │ └── ST.json ├── hint.py └── supported_formats.py ├── setup.py └── test ├── __init__.py ├── test_edi.txt ├── test_parse_edi.py └── test_pythonedi.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jon Winsley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-edi 2 | EDI message generator in Python. Creates & validates messages according to specific formats 3 | 4 | ## TODOs 5 | 6 | * Finish 810 definition 7 | * Implement colorful exceptions 8 | 9 | ## EDI Format Definitions 10 | EDI messages consist of a set of Segments (usually lines) comprised of Elements. Some segments can be part of a Loop. These formats are defined in JSON. See the provided format(s) for examples. 11 | 12 | A loop has certain expected properties: 13 | 14 | * `id` (Loop ID) 15 | * `repeat` (Max times the loop can repeat) 16 | 17 | Each segment has certain expected properties: 18 | 19 | * `id` (Segment ID) 20 | * `name` (Human-readable segment name) 21 | * `req` (Whether segment is required: [M]andatory, [O]ptional) 22 | * `max_uses` (Some segments can be included more than once) 23 | * `notes` (Optional details for hinting documentation) 24 | * `syntax` (An optional list of syntax rules, defined below) 25 | * `elements` (List of included elements) 26 | 27 | Each element has certain expected features: 28 | 29 | * `id` (Element ID) 30 | * `name` (Human-readable element name) 31 | * `req` (Whether segment is required: [M]andatory, [O]ptional) 32 | * `data_type` (Type of segment data, defined below) 33 | * `data_type_ids` (If `data_type` is `ID`, this is a dict of valid IDs with descriptions) 34 | * `length` (Dict specifying field length) 35 | * `min` (Min length of field) 36 | * `max` (Max length of field) 37 | 38 | Valid data types include: 39 | 40 | * `AN` (Any data type) 41 | * `DT` (Date, must be provided as Python DATE or DATETIME object) 42 | * `ID` (Alphanumeric ID. List of valid IDs provided as dict with descriptions) 43 | * `R` (Percentage) 44 | * `Nx` (Number with `x` decimal points) 45 | * `TM` (Time, must be provided as Python TIME or DATETIME object) 46 | 47 | Syntax rules are specified as a dict with a `rule` and a list of `criteria`. Valid syntax rules include: 48 | 49 | * `ATLEASTONE` (where at least one of the element IDs in the `criteria` list is included and is not empty) 50 | * `ALLORNONE` (where either all of the element IDs in the `criteria` list are included, or none are) 51 | * `IFATLEASTONE` (if the first element in `criteria` is included, then at least one of the other elements must be included) 52 | -------------------------------------------------------------------------------- /pythonedi/EDIGenerator.py: -------------------------------------------------------------------------------- 1 | """ 2 | Parses a provided dictionary set and tries to build an EDI message from the data. 3 | Provides hints if data is missing, incomplete, or incorrect. 4 | """ 5 | 6 | from .supported_formats import supported_formats 7 | from .debug import Debug 8 | 9 | class EDIGenerator(object): 10 | def __init__(self): 11 | # Set default delimiters 12 | self.element_delimiter = "^" 13 | self.segment_delimiter = "\n" 14 | self.data_delimiter = "`" 15 | 16 | def build(self, data): 17 | """ 18 | Compiles a transaction set (as a dict) into an EDI message 19 | """ 20 | # Check for transaction set ID in data 21 | 22 | if "ST" not in data: 23 | Debug.explain(supported_formats["ST"]) 24 | raise ValueError("No transaction set header found in data.") 25 | ts_id = data["ST"][0] 26 | if ts_id not in supported_formats: 27 | raise ValueError("Transaction set type '{}' is not supported. Valid types include: {}".format( 28 | ts_id, 29 | "".join(["\n - " + f for f in supported_formats]) 30 | )) 31 | edi_format = supported_formats[ts_id] 32 | 33 | output_segments = [] 34 | 35 | # Walk through the format definition to compile the output message 36 | for section in edi_format: 37 | if section["type"] == "segment": 38 | if section["id"] not in data: 39 | if section["req"] == "O": 40 | # Optional segment is missing - that's fine, keep going 41 | continue 42 | elif section["req"] == "M": 43 | # Mandatory segment is missing - explain it and then fail 44 | Debug.explain(section) 45 | raise ValueError("EDI data is missing mandatory segment '{}'.".format(section["id"])) 46 | else: 47 | raise ValueError("Unknown 'req' value '{}' when processing format for segment '{}' in set '{}'".format(section["req"], section["id"], ts_id)) 48 | output_segments.append(self.build_segment(section, data[section["id"]])) 49 | elif section["type"] == "loop": 50 | if section["id"] not in data: 51 | mandatory = [segment for segment in section["segments"] if segment["req"] == "M"] 52 | if len(mandatory) > 0: 53 | Debug.explain(section) 54 | raise ValueError("EDI data is missing loop {} with mandatory segment(s) {}".format(section["id"], ", ".join([segment["id"] for segment in mandatory]))) 55 | else: 56 | # No mandatory segments in loop - continue 57 | continue 58 | # Verify loop length 59 | if len(section["segments"]) > section["repeat"]: 60 | raise ValueError("Loop '{}' has {} segments (max {})".format(section["id"], len(section["segments"]), section["repeat"])) 61 | # Iterate through and build segments in loop 62 | for iteration in data[section["id"]]: 63 | for segment in section["segments"]: 64 | if segment["id"] not in iteration: 65 | if segment["req"] == "O": 66 | # Optional segment is missing - that's fine, keep going 67 | continue 68 | elif segment["req"] == "M": 69 | # Mandatory segment is missing - explain loop and then fail 70 | Debug.explain(section) 71 | raise ValueError("EDI data in loop '{}' is missing mandatory segment '{}'.".format(section["id"], segment["id"])) 72 | else: 73 | raise ValueError("Unknown 'req' value '{}' when processing format for segment '{}' in set '{}'".format(segment["req"], segment["id"], ts_id)) 74 | output_segments.append(self.build_segment(segment, iteration[segment["id"]])) 75 | 76 | return self.segment_delimiter.join(output_segments) 77 | 78 | def build_segment(self, segment, segment_data): 79 | # Parse segment elements 80 | output_elements = [segment["id"]] 81 | for e_data, e_format, index in zip(segment_data, segment["elements"], range(len(segment["elements"]))): 82 | output_elements.append(self.build_element(e_format, e_data)) 83 | 84 | # End of segment. If segment has syntax rules, validate them. 85 | if "syntax" in segment: 86 | for rule in segment["syntax"]: 87 | # Note that the criteria indexes are one-based 88 | # rather than zero-based. However, the output_elements 89 | # array is prepopulated with the segment name, 90 | # so the net offset works perfectly! 91 | if rule["rule"] == "ATLEASTONE": # At least one of the elements in `criteria` must be present 92 | found = False 93 | for idx in rule["criteria"]: 94 | if idx >= len(output_elements): 95 | break 96 | elif output_elements[idx] != "": 97 | found = True 98 | if found is False: 99 | # None of the elements were found 100 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"]]) 101 | Debug.explain(segment) 102 | raise ValueError("Syntax error parsing segment {}: At least one of {} is required.".format(segment["id"], required_elements)) 103 | elif rule["rule"] == "ALLORNONE": # Either all the elements in `criteria` must be present, or none of them may be 104 | found = 0 105 | for idx in rule["criteria"]: 106 | if idx >= len(output_elements): 107 | break 108 | elif output_elements[idx] != "": 109 | found += 1 110 | if 0 < found < len(rule["criteria"]): 111 | # Some but not all the elements are present 112 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"]]) 113 | Debug.explain(segment) 114 | raise ValueError("Syntax error parsing segment {}: If one of {} is present, all are required.".format(segment["id"], required_elements)) 115 | elif rule["rule"] == "IFATLEASTONE": # If the first element in `criteria` is present, at least one of the others must be 116 | found = 0 117 | # Check if first element exists and is set 118 | if rule["criteria"][0] < len(output_elements) and output_elements[rule["criteria"][0]] != "": 119 | for idx in rule["criteria"][1:]: 120 | if idx >= len(output_elements): 121 | break 122 | elif output_elements[idx] != "": 123 | found += 1 124 | if 0 < found < len(rule["criteria"]): 125 | # Some but not all the elements are present 126 | first_element = "{}{:02d}".format(segment["id"], rule["criteria"][0]) 127 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"][0]]) 128 | Debug.explain(segment) 129 | raise ValueError("Syntax error parsing segment {}: If {} is present, at least one of {} are required.".format(segment["id"], first_element, required_elements)) 130 | 131 | return self.element_delimiter.join(output_elements) 132 | 133 | def build_element(self, e_format, e_data): 134 | element_id = e_format["id"] 135 | formatted_element = "" 136 | if e_data is None: 137 | if e_format["req"] == "M": 138 | raise ValueError("Element {} ({}) is mandatory".format(element_id, e_format["name"])) 139 | elif e_format["req"] == "O": 140 | return "" 141 | else: 142 | raise ValueError("Unknown 'req' value '{}' when processing format for element '{}' in set '{}'".format(e_format["req"], element_id, ts_id)) 143 | try: 144 | if e_format["data_type"] == "AN": 145 | formatted_element = str(e_data) 146 | elif e_format["data_type"] == "DT": 147 | if e_format["length"]["max"] == 8: 148 | formatted_element = e_data.strftime("%Y%m%d") 149 | elif e_format["length"]["max"] == 6: 150 | formatted_element = e_data.strftime("%y%m%d") 151 | else: 152 | raise ValueError("Invalid length ({}) for date field in element '{}' in set '{}'".format(e_format["length"], element_id, ts_id)) 153 | elif e_format["data_type"] == "TM": 154 | if e_format["length"]["max"] in (4, 6, 7, 8): 155 | #formatted_element = e_data.strftime("%H%M%S%f") 156 | formatted_element = e_data.strftime("%H%M") 157 | else: 158 | raise ValueError("Invalid length ({}) for time field in element '{}' in set '{}'".format(e_format["length"], element_id, ts_id)) 159 | elif e_format["data_type"] == "R": 160 | formatted_element = str(float(e_data)) 161 | elif e_format["data_type"].startswith("N"): 162 | formatted_element = "{:0{length}.{decimal}f}".format(float(e_data), length=e_format["length"]["min"], decimal=e_format["data_type"][1:]) 163 | elif e_format["data_type"] == "ID": 164 | formatted_element = str(e_data) 165 | if not e_format["data_type_ids"]: 166 | #Debug.log_warning("No valid IDs provided for element '{}'. Allowing anyway.".format(e_format["name"])) 167 | pass 168 | elif e_data not in e_format["data_type_ids"]: 169 | #Debug.log_warning("ID '{}' not recognized for element '{}'. Allowing anyway.".format(e_data, e_format["name"])) 170 | pass 171 | elif e_format["data_type"] == "": 172 | if element_id == "ISA16": 173 | # Component Element Separator 174 | self.data_delimiter = str(e_data)[0] 175 | formatted_element = str(e_data) 176 | else: 177 | raise ValueError("Undefined behavior for empty data type with element '{}'".format(element_id)) 178 | except: 179 | raise ValueError("Error converting '{}' to data type '{}'".format(e_data, e_format["data_type"])) 180 | 181 | # Pad/trim formatted element to fit the field min/max length respectively 182 | formatted_element += " "*(e_format["length"]["min"]-len(formatted_element)) 183 | formatted_element = formatted_element[:e_format["length"]["max"]] 184 | 185 | # Add element to list 186 | return formatted_element -------------------------------------------------------------------------------- /pythonedi/EDIParser.py: -------------------------------------------------------------------------------- 1 | """ 2 | Parses a provided EDI message and tries to build a dictionary from the data 3 | Provides hints if data is missing, incomplete, or incorrect. 4 | """ 5 | 6 | import datetime 7 | 8 | from .supported_formats import supported_formats 9 | from .debug import Debug 10 | 11 | class EDIParser(object): 12 | def __init__(self, edi_format=None, element_delimiter="^", segment_delimiter="\n", data_delimiter="`"): 13 | # Set default delimiters 14 | self.element_delimiter = element_delimiter 15 | self.segment_delimiter = segment_delimiter 16 | self.data_delimiter = data_delimiter 17 | 18 | # Set EDI format to use 19 | if edi_format in supported_formats: 20 | self.edi_format = supported_formats[edi_format] 21 | elif edi_format is None: 22 | self.edi_format = None 23 | else: 24 | raise ValueError("Unsupported EDI format {}".format(edi_format)) 25 | 26 | def parse(self, data): 27 | """ Processes each line in the string `data`, attempting to auto-detect the EDI type. 28 | 29 | Returns the parsed message as a dict. """ 30 | 31 | # Break the message up into chunks 32 | edi_segments = data.split(self.segment_delimiter) 33 | 34 | # Eventually, find the ST header and parse the EDI format 35 | if self.edi_format is None: 36 | raise NotImplementedError("EDI format autodetection not built yet. Please specify an EDI format.") 37 | 38 | to_return = {} 39 | found_segments = [] 40 | 41 | while len(edi_segments) > 0: 42 | segment = edi_segments[0] 43 | if segment == "": 44 | edi_segments = edi_segments[1:] 45 | continue # Line is blank, skip 46 | # Capture current segment name 47 | segment_name = segment.split(self.element_delimiter)[0] 48 | segment_obj = None 49 | # Find corresponding segment/loop format 50 | for seg_format in self.edi_format: 51 | # Check if segment is just a segment, a repeating segment, or part of a loop 52 | if seg_format["id"] == segment_name and seg_format["max_uses"] == 1: 53 | # Found a segment 54 | segment_obj = self.parse_segment(segment, seg_format) 55 | edi_segments = edi_segments[1:] 56 | break 57 | elif seg_format["id"] == segment_name and seg_format["max_uses"] > 1: 58 | # Found a repeating segment 59 | segment_obj, edi_segments = self.parse_repeating_segment(edi_segments, seg_format) 60 | break 61 | elif seg_format["id"] == "L_" + segment_name: 62 | # Found a loop 63 | segment_name = seg_format["id"] 64 | segment_obj, edi_segments = self.parse_loop(edi_segments, seg_format) 65 | break 66 | 67 | if segment_obj is None: 68 | Debug.log_error("Unrecognized segment: {}".format(segment)) 69 | edi_segments = edi_segments[1:] # Skipping segment 70 | continue 71 | # raise ValueError 72 | 73 | found_segments.append(segment_name) 74 | to_return[segment_name] = segment_obj 75 | 76 | 77 | return found_segments, to_return 78 | 79 | def parse_segment(self, segment, segment_format): 80 | """ Parse a segment into a dict according to field IDs """ 81 | fields = segment.split(self.element_delimiter) 82 | if fields[0] != segment_format["id"]: 83 | raise TypeError("Segment type {} does not match provided segment format {}".format(fields[0], segment_format["id"])) 84 | elif len(fields)-1 > len(segment_format["elements"]): 85 | Debug.explain(segment_format) 86 | raise TypeError("Segment has more elements than segment definition") 87 | 88 | #segment_name = fields[0] 89 | to_return = {} 90 | for field, element in zip(fields[1:], segment_format["elements"]): # Skip the segment name field 91 | key = element["id"] 92 | if element["data_type"] == "DT": 93 | if len(field) == 8: 94 | value = datetime.datetime.strptime(field, "%Y%m%d") 95 | elif len(field) == 6: 96 | value = datetime.datetime.strptime(field, "%y%m%d") 97 | else: 98 | value = field 99 | elif element["data_type"] == "TM": 100 | if len(field) == 4: 101 | value = datetime.datetime.strptime(field, "%H%M") 102 | elif len(field) == 6: 103 | value = datetime.datetime.strptime(field, "%H%M%S") 104 | elif element["data_type"] == "N0" and field != "": 105 | value = int(field) 106 | elif element["data_type"].startswith("N") and field != "": 107 | value = float(field) / (10**int(element["data_type"][-1])) 108 | elif element["data_type"] == "R" and field != "": 109 | value = float(field) 110 | else: 111 | value = field 112 | to_return[key] = value 113 | 114 | return to_return 115 | 116 | 117 | def parse_repeating_segment(self, edi_segments, segment_format): 118 | """ Parse all instances of this segment, and return any remaining segments with the seg_list """ 119 | seg_list = [] 120 | 121 | while len(edi_segments) > 0: 122 | segment = edi_segments[0] 123 | segment_name = segment.split(self.element_delimiter)[0] 124 | if segment_name != segment_format["id"]: 125 | break 126 | seg_list.append(self.parse_segment(segment, segment_format)) 127 | edi_segments = edi_segments[1:] 128 | 129 | return seg_list, edi_segments 130 | 131 | def parse_loop(self, edi_segments, loop_format): 132 | """ Parse all segments that are part of this loop, and return any remaining segments with the loop_list """ 133 | loop_list = [] 134 | loop_dict = {} 135 | 136 | while len(edi_segments) > 0: 137 | segment = edi_segments[0] 138 | segment_name = segment.split(self.element_delimiter)[0] 139 | segment_obj = None 140 | 141 | # Find corresponding segment/loop format 142 | for seg_format in loop_format["segments"]: 143 | # Check if segment is just a segment, a repeating segment, or part of a loop 144 | if seg_format["id"] == segment_name and seg_format["max_uses"] == 1: 145 | # Found a segment 146 | segment_obj = self.parse_segment(segment, seg_format) 147 | edi_segments = edi_segments[1:] 148 | elif seg_format["id"] == segment_name and seg_format["max_uses"] > 1: 149 | # Found a repeating segment 150 | segment_obj, edi_segments = self.parse_repeating_segment(edi_segments, seg_format) 151 | elif seg_format["id"] == "L_" + segment_name: 152 | # Found a loop 153 | segment_name = seg_format["id"] 154 | segment_obj, edi_segments = self.parse_loop(edi_segments, seg_format) 155 | #print(segment_name, segment_obj) 156 | if segment_obj is None: 157 | # Reached the end of valid segments; return what we have 158 | break 159 | elif segment_name == loop_format["segments"][0]["id"] and loop_dict != {}: 160 | # Beginning a new loop, tie off this one and start fresh 161 | loop_list.append(loop_dict.copy()) 162 | loop_dict = {} 163 | loop_dict[segment_name] = segment_obj 164 | if loop_dict != {}: 165 | loop_list.append(loop_dict.copy()) 166 | return loop_list, edi_segments 167 | -------------------------------------------------------------------------------- /pythonedi/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | PythonEDI 3 | 4 | Generates EDI messages from Python data objects (dicts/lists/etc). 5 | Validates against a provided EDI standard definition (in JSON format). 6 | Provides hints if the validation fails. 7 | """ 8 | 9 | import os 10 | 11 | from .EDIGenerator import EDIGenerator, Debug, supported_formats 12 | from .EDIParser import EDIParser 13 | 14 | def explain(edi_format, section_id=""): 15 | """ Explains the referenced section of the referenced EDI format. 16 | 17 | Try `pythonedi.explain("810", "ITD")` 18 | """ 19 | if edi_format not in supported_formats: 20 | raise ValueError("'{}' is not a supported EDI format. Valid formats include: ({})".format(edi_format, ", ".join(supported_formats.keys()))) 21 | section_id = section_id.upper() 22 | if section_id == "": 23 | Debug.explain(supported_formats[edi_format]) 24 | return 25 | for section in supported_formats[edi_format]: 26 | if section["id"] == section_id: 27 | Debug.explain(section) 28 | return 29 | elif section["type"] == "loop": 30 | for segment in section["segments"]: 31 | if segment["id"] == section_id: 32 | Debug.explain(section) 33 | return 34 | 35 | print("Section '{}' was not found for EDI format '{}'.".format(section_id, edi_format)) 36 | -------------------------------------------------------------------------------- /pythonedi/debug.py: -------------------------------------------------------------------------------- 1 | """ 2 | Debug printer 3 | 4 | Handles logging at different debug levels 5 | """ 6 | 7 | from colorama import Fore, Style, init 8 | init() 9 | 10 | LOOP_TEMPLATE = """ 11 | {tab_level}{HEADER_COLOR}[{id}] {name}{END_COLOR} 12 | {tab_level} * Required? {VALUE_COLOR}{req}{END_COLOR} 13 | {tab_level} * Max repeat: {VALUE_COLOR}{repeat}{END_COLOR} 14 | """ 15 | 16 | SEGMENT_TEMPLATE = """ 17 | {tab_level}{HEADER_COLOR}[{id}] {name}{END_COLOR} 18 | {tab_level} * Required? {VALUE_COLOR}{req}{END_COLOR} 19 | {tab_level} * Max uses: {VALUE_COLOR}{max_uses}{END_COLOR} 20 | {tab_level} * Syntax rules: {VALUE_COLOR}{syntax_rules}{END_COLOR} 21 | {tab_level} * Notes: {VALUE_COLOR}{notes}{END_COLOR} 22 | """ 23 | 24 | ELEMENT_TEMPLATE = """ 25 | {tab_level}{HEADER_COLOR}{index}{name}{END_COLOR} 26 | {tab_level} * Required? {VALUE_COLOR}{req}{END_COLOR} 27 | {tab_level} * Data type: {VALUE_COLOR}{data_type}{END_COLOR} 28 | {tab_level} * Data type options: {VALUE_COLOR}{data_type_ids}{END_COLOR} 29 | {tab_level} * Length (min: {VALUE_COLOR}{length[min]}{END_COLOR}, max: {VALUE_COLOR}{length[max]}{END_COLOR}) 30 | {tab_level} * Notes: {VALUE_COLOR}{notes}{END_COLOR} 31 | """ 32 | 33 | class DebugMaster(object): 34 | """ Auto-instantiated as Debug to provide a single point of contact """ 35 | def __init__(self): 36 | self.level = 3 37 | self.tags = { 38 | "ERROR": "{}[ ERROR ]{} ".format(Fore.RED+Style.BRIGHT, Style.RESET_ALL), 39 | "WARNING": "{}[WARNING]{} ".format(Fore.YELLOW+Style.BRIGHT, Style.RESET_ALL), 40 | "MESSAGE": "{}[MESSAGE]{} ".format(Fore.CYAN+Style.BRIGHT, Style.RESET_ALL) 41 | } 42 | 43 | def log(self, message, level=1): 44 | """ Creates a custom message at the specified level """ 45 | if level <= self.level: 46 | print("\n" + message) 47 | 48 | def log_error(self, message): 49 | """ Creates an error-level log messsage """ 50 | self.log(self.tags["ERROR"] + message, 1) 51 | 52 | def log_warning(self, message): 53 | """ Creates a warning-level log messsage """ 54 | self.log(self.tags["WARNING"] + message, 2) 55 | 56 | def log_message(self, message): 57 | """ Creates a message-level log messsage """ 58 | self.log(self.tags["MESSAGE"] + message, 3) 59 | 60 | def explain(self, structure): 61 | print(self.level) 62 | if self.level <= 1: 63 | return # Only explain if debugging level is 2+ 64 | # Decide which type of structure this is 65 | if type(structure) is list: 66 | for segment in structure: 67 | self.explain_segment(segment) 68 | elif type(structure) is dict and "type" in structure: 69 | if structure["type"] == "segment": 70 | self.explain_segment(structure) 71 | elif structure["type"] == "element": 72 | self.explain_element("", structure) 73 | elif structure["type"] == "loop": 74 | self.explain_loop(structure) 75 | else: 76 | raise TypeError("Expected either a loop, a segment, an element, or a list of segments.") 77 | 78 | def explain_segment(self, segment, tab_level = ""): 79 | if self.level <= 1: 80 | return # Only explain if debugging level is 2+ 81 | print(Fore.CYAN + "\n" + tab_level + "-- [Segment] --" + Fore.RESET) 82 | if segment["type"] == "segment": 83 | # Parse syntax rules into human-readable format 84 | syntax_rules_list = [] 85 | if "syntax" in segment: 86 | for rule in segment["syntax"]: 87 | # Troubleshooting 88 | if "rule" not in rule or "criteria" not in rule: 89 | raise ValueError("Invalid rule definition in segment {}: {}".format(segment["id"], rule)) 90 | if len(rule["criteria"]) < 2: 91 | raise ValueError("Invalid criteria for syntax rule {} in segment {}: Expected two or more values".format(rule["rule"], segment["id"])) 92 | 93 | if rule["rule"] == "ATLEASTONE": 94 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"]]) 95 | syntax_rules_list.append("At least one of {} is required".format(required_elements)) 96 | elif rule["rule"] == "ALLORNONE": 97 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"]]) 98 | syntax_rules_list.append("If one of {} is present, the rest are required".format(required_elements)) 99 | elif rule["rule"] == "IFATLEASTONE": 100 | first_element = "{}{:02d}".format(segment["id"], rule["criteria"][0]) 101 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"][1:]]) 102 | syntax_rules_list.append("If {} is present, at least one of {} are required".format(first_element, required_elements)) 103 | 104 | # Print template 105 | print(SEGMENT_TEMPLATE.format( 106 | tab_level=tab_level, 107 | syntax_rules="; ".join(syntax_rules_list), 108 | HEADER_COLOR=Fore.CYAN+Style.BRIGHT, 109 | VALUE_COLOR=Fore.YELLOW+Style.BRIGHT, 110 | END_COLOR=Fore.RESET+Style.RESET_ALL, 111 | **segment)) 112 | 113 | # Print elements section 114 | print(Fore.CYAN + tab_level + " -- [Elements] --" + Fore.RESET) 115 | for i, element in enumerate(segment["elements"]): 116 | self.explain_element("{}{:02d}: ".format(segment["id"], i+1), element, tab_level + " ") 117 | 118 | # End segment 119 | print(Fore.CYAN + tab_level + "--------------------" + Fore.RESET) 120 | 121 | def explain_element(self, index, element, tab_level = ""): 122 | if self.level <= 1: 123 | return # Only explain if debugging level is 2+ 124 | # Print template 125 | print(ELEMENT_TEMPLATE.format( 126 | tab_level=tab_level, 127 | index=index, 128 | HEADER_COLOR=Fore.GREEN, 129 | VALUE_COLOR=Fore.YELLOW+Style.BRIGHT, 130 | END_COLOR=Fore.RESET+Style.RESET_ALL, 131 | **element)) 132 | 133 | def explain_loop(self, loop, tab_level=""): 134 | if self.level <= 1: 135 | return # Only explain if debugging level is 2+ 136 | print(Fore.RED + "-- [Loop] --" + Style.RESET_ALL) 137 | print(LOOP_TEMPLATE.format( 138 | tab_level=tab_level, 139 | HEADER_COLOR=Fore.RED+Style.BRIGHT, 140 | VALUE_COLOR=Fore.YELLOW+Style.BRIGHT, 141 | END_COLOR=Fore.RESET+Style.RESET_ALL, 142 | **loop)) 143 | 144 | for segment in loop["segments"]: 145 | self.explain_segment(segment, " ") 146 | 147 | print(Fore.RED + "------------" + Style.RESET_ALL) 148 | 149 | Debug = DebugMaster() 150 | -------------------------------------------------------------------------------- /pythonedi/formats/810.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "id": "ISA", "type": "segment", 3 | "name": "Interchange Control Header", 4 | "req": "M", 5 | "max_uses": 1, 6 | "notes": "", 7 | "elements": [ 8 | { "id": "ISA01", "type": "element", 9 | "name": "Authorization Information Qualifier", 10 | "req": "M", 11 | "data_type": "ID", 12 | "data_type_ids": {"00": "(default)"}, 13 | "length": {"min": 2, "max": 2}, 14 | "notes": "Code to identify the type of information in the Authorization Information" 15 | }, 16 | { "id": "ISA02", "type": "element", 17 | "name": "Authorization Information", 18 | "req": "M", 19 | "data_type": "AN", 20 | "data_type_ids": null, 21 | "length": {"min": 10, "max": 10}, 22 | "notes": "Information used for additional identification or authorization of the interchange sender or the data in the interchange; the type of information is set by the Authorization Information Qualifier (I01)" 23 | }, 24 | { "id": "ISA03", "type": "element", 25 | "name": "Security Information Qualifier", 26 | "req": "M", 27 | "data_type": "ID", 28 | "data_type_ids": {"00": "(default)"}, 29 | "length": {"min": 2, "max": 2}, 30 | "notes": "Code to identify the type of information in the Security Information" 31 | }, 32 | { "id": "ISA04", "type": "element", 33 | "name": "Security Information", 34 | "req": "M", 35 | "data_type": "AN", 36 | "data_type_ids": null, 37 | "length": {"min": 10, "max": 10}, 38 | "notes": "This is used for identifying the security information about the interchange sender or the data in the interchange; the type of information is set by the Security Information Qualifier (I03)" 39 | }, 40 | { "id": "ISA05", "type": "element", 41 | "name": "Interchange Sender ID Qualifier", 42 | "req": "M", 43 | "data_type": "ID", 44 | "data_type_ids": {"ZZ": "Mutually Defined"}, 45 | "length": {"min": 2, "max": 2}, 46 | "notes": "Qualifier to designate the system/method of code structure used to designate the sender or receiver ID element being qualified" 47 | }, 48 | { "id": "ISA06", "type": "element", 49 | "name": "Interchange Sender ID", 50 | "req": "M", 51 | "data_type": "AN", 52 | "data_type_ids": null, 53 | "length": {"min": 15, "max": 15}, 54 | "notes": "Identification code published by the sender for other parties to use as the receiver ID to route data to them; the sender always codes this value in the sender ID element" 55 | }, 56 | { "id": "ISA07", "type": "element", 57 | "name": "Interchange Receiver ID Qualifier", 58 | "req": "M", 59 | "data_type": "ID", 60 | "data_type_ids": {"ZZ": "Mutually Defined"}, 61 | "length": {"min": 2, "max": 2}, 62 | "notes": "Qualifier to designate the system/method of code structure used to designate the sender or receiver ID element being qualified" 63 | }, 64 | { "id": "ISA08", "type": "element", 65 | "name": "Interchange Receiver ID", 66 | "req": "M", 67 | "data_type": "AN", 68 | "data_type_ids": null, 69 | "length": {"min": 15, "max": 15}, 70 | "notes": "Identification code published by the receiver of the data; When sending, it is used by the sender as their sending ID, thus other parties sending to them will use this as a receiving ID to route data to them" 71 | }, 72 | { "id": "ISA09", "type": "element", 73 | "name": "Interchange Date", 74 | "req": "M", 75 | "data_type": "DT", 76 | "data_type_ids": null, 77 | "length": {"min": 6, "max": 6}, 78 | "notes": "Date of the interchange" 79 | }, 80 | { "id": "ISA10", "type": "element", 81 | "name": "Interchange Time", 82 | "req": "M", 83 | "data_type": "TM", 84 | "data_type_ids": null, 85 | "length": {"min": 4, "max": 4}, 86 | "notes": "Time of the interchange" 87 | }, 88 | { "id": "ISA11", "type": "element", 89 | "name": "Interchange Control Standards Identifier", 90 | "req": "M", 91 | "data_type": "ID", 92 | "data_type_ids": null, 93 | "length": {"min": 1, "max": 1}, 94 | "notes": "Code to identify the agency responsible for the control standard used by the message that is enclosed by the interchange header and trailer" 95 | }, 96 | { "id": "ISA12", "type": "element", 97 | "name": "Interchange Control Version Number", 98 | "req": "M", 99 | "data_type": "ID", 100 | "data_type_ids": {"U": "(default)"}, 101 | "length": {"min": 5, "max": 5}, 102 | "notes": "This version number covers the interchange control segments" 103 | }, 104 | { "id": "ISA13", "type": "element", 105 | "name": "Interchange Control Number", 106 | "req": "M", 107 | "data_type": "N0", 108 | "data_type_ids": null, 109 | "length": {"min": 9, "max": 9}, 110 | "notes": "A control number assigned by the interchange sender" 111 | }, 112 | { "id": "ISA14", "type": "element", 113 | "name": "Acknowledgment Requested", 114 | "req": "M", 115 | "data_type": "ID", 116 | "data_type_ids": {"0": "Requested"}, 117 | "length": {"min": 1, "max": 1}, 118 | "notes": "Code sent by the sender to request an interchange acknowledgment (TA1)" 119 | }, 120 | { "id": "ISA15", "type": "element", 121 | "name": "Usage Indicator", 122 | "req": "M", 123 | "data_type": "ID", 124 | "data_type_ids": {"T": "Test", "P": "Production", "I": "Information"}, 125 | "length": {"min": 1, "max": 1}, 126 | "notes": "Code to indicate whether data enclosed by this interchange envelope is test, production or information" 127 | }, 128 | { "id": "ISA16", "type": "element", 129 | "name": "Component Element Separator", 130 | "req": "M", 131 | "data_type": "", 132 | "data_type_ids": {"T": "Test", "P": "Production", "I": "Information"}, 133 | "length": {"min": 1, "max": 1}, 134 | "notes": "Type is not applicable; the component element separator is a delimiter and not a data element; this field provides the delimiter used to separate component data elements within a composite data structure; this value must be different than the data element separator and the segment terminator" 135 | } 136 | ] 137 | }, 138 | { "id": "GS", "type": "segment", 139 | "name": "Functional Group Header", 140 | "req": "M", 141 | "max_uses": 1, 142 | "notes": "", 143 | "elements": [ 144 | { "id": "GS01", "type": "element", 145 | "name": "Functional Identifier Code", 146 | "req": "M", 147 | "data_type": "ID", 148 | "data_type_ids": {"IN": "Invoice"}, 149 | "length": {"min": 2, "max": 2}, 150 | "notes": "Code identifying a group of application related transaction sets" 151 | }, 152 | { "id": "GS02", "type": "element", 153 | "name": "Application Sender's Code", 154 | "req": "M", 155 | "data_type": "AN", 156 | "data_type_ids": null, 157 | "length": {"min": 2, "max": 15}, 158 | "notes": "Code identifying party sending transmission; codes agreed to by trading partners" 159 | }, 160 | { "id": "GS03", "type": "element", 161 | "name": "Application Receiver's Code", 162 | "req": "M", 163 | "data_type": "AN", 164 | "data_type_ids": null, 165 | "length": {"min": 2, "max": 15}, 166 | "notes": "Code identifying party receiving transmission. Codes agreed to by trading partners" 167 | }, 168 | { "id": "GS04", "type": "element", 169 | "name": "Date", 170 | "req": "M", 171 | "data_type": "DT", 172 | "data_type_ids": null, 173 | "length": {"min": 8, "max": 8}, 174 | "notes": "Date expressed as CCYYMMDD" 175 | }, 176 | { "id": "GS05", "type": "element", 177 | "name": "Time", 178 | "req": "M", 179 | "data_type": "TM", 180 | "data_type_ids": null, 181 | "length": {"min": 4, "max": 8}, 182 | "notes": "Time expressed in 24-hour clock time as follows: HHMM, or HHMMSS, or HHMMSSD, or HHMMSSDD" 183 | }, 184 | { "id": "GS06", "type": "element", 185 | "name": "Group Control Number", 186 | "req": "M", 187 | "data_type": "N0", 188 | "data_type_ids": null, 189 | "length": {"min": 1, "max": 9}, 190 | "notes": "Assigned number originated and maintained by the sender" 191 | }, 192 | { "id": "GS07", "type": "element", 193 | "name": "Responsible Agency Code", 194 | "req": "M", 195 | "data_type": "ID", 196 | "data_type_ids": {"X": "", "T": ""}, 197 | "length": {"min": 1, "max": 2}, 198 | "notes": "Code used in conjunction with Data Element 480 to identify the issuer of the standard" 199 | }, 200 | { "id": "GS08", "type": "element", 201 | "name": "Version / Release / Industry Identifier Code", 202 | "req": "M", 203 | "data_type": "AN", 204 | "data_type_ids": null, 205 | "length": {"min": 1, "max": 12}, 206 | "notes": "Code indicating the version, release, subrelease, and industry identifier of the EDI standard being used, including the GS and GE segments; if code in DE455 in GS segment is X, then in DE 480 positions 1-3 are the version number; positions 4-6 are the release and subrelease, level of the version; and positions 7-12 are the industry or trade association identifiers (optionally assigned by user); if code in DE455 in GS segment is T, then other formats are allowed" 207 | } 208 | ] 209 | }, 210 | { "id": "ST", "type": "segment", 211 | "name": "Transaction Set Header", 212 | "req": "M", 213 | "max_uses": 1, 214 | "notes": "", 215 | "elements": [ 216 | { "id": "ST01", "type": "element", 217 | "name": "Transaction Set Identifier Code", 218 | "req": "M", 219 | "data_type": "ID", 220 | "data_type_ids": {"810": "Invoice"}, 221 | "length": {"min": 3, "max": 3}, 222 | "notes": "" 223 | }, 224 | { "id": "ST02", "type": "element", 225 | "name": "Transaction Set Control Number", 226 | "req": "M", 227 | "data_type": "AN", 228 | "data_type_ids": null, 229 | "length": {"min": 4, "max": 9}, 230 | "notes": "This should be a unique control # for each transaction set functional group" 231 | } 232 | ] 233 | }, 234 | { "id": "BIG", "type": "segment", 235 | "name": "Beginning Segment for Invoice", 236 | "req": "M", 237 | "max_uses": 1, 238 | "notes": "", 239 | "elements": [ 240 | { "id": "BIG01", "type": "element", 241 | "name": "Invoice Date", 242 | "req": "M", 243 | "data_type": "DT", 244 | "data_type_ids": null, 245 | "length": {"min": 8, "max": 8}, 246 | "notes": "Invoice issue date" 247 | }, 248 | { "id": "BIG02", "type": "element", 249 | "name": "Invoice Number", 250 | "req": "M", 251 | "data_type": "AN", 252 | "data_type_ids": null, 253 | "length": {"min": 1, "max": 22}, 254 | "notes": "Identifying number assigned by supplier" 255 | }, 256 | { "id": "BIG03", "type": "element", 257 | "name": "Purchase Order Date", 258 | "req": "O", 259 | "data_type": "DT", 260 | "data_type_ids": null, 261 | "length": {"min": 8, "max": 8}, 262 | "notes": "Original date (assigned by hospital) of the purchase order" 263 | }, 264 | { "id": "BIG04", "type": "element", 265 | "name": "Purchase Order Number", 266 | "req": "O", 267 | "data_type": "AN", 268 | "data_type_ids": null, 269 | "length": {"min": 1, "max": 22}, 270 | "notes": "Identifying number for purchase order assigned by hospital" 271 | }, 272 | { "id": "BIG05", "type": "element", 273 | "name": "Release Number", 274 | "req": "O", 275 | "data_type": "AN", 276 | "data_type_ids": null, 277 | "length": {"min": 1, "max": 30}, 278 | "notes": "Only used if hospital sent the release # in original PO (element BEG04)" 279 | }, 280 | { "id": "BIG06", "type": "element", 281 | "name": "Change Order Seq. #", 282 | "req": "O", 283 | "data_type": "AN", 284 | "data_type_ids": null, 285 | "length": {"min": 1, "max": 8}, 286 | "notes": "Not used" 287 | }, 288 | { "id": "BIG07", "type": "element", 289 | "name": "Transaction Type Code", 290 | "req": "O", 291 | "data_type": "ID", 292 | "data_type_ids": { 293 | "CN": "Credit Invoice", 294 | "CR": "Credit Memo", 295 | "DI": "Debit Invoice", 296 | "DR": "Debit Memo", 297 | "PR": "Product (or Service)" 298 | }, 299 | "length": {"min": 1, "max": 22}, 300 | "notes": "Identifying number for purchase order assigned by hospital" 301 | }, 302 | { "id": "BIG08", "type": "element", 303 | "name": "Transaction Set Purpose Code", 304 | "req": "O", 305 | "data_type": "ID", 306 | "data_type_ids": { 307 | "00": "Original" 308 | }, 309 | "length": {"min": 2, "max": 2}, 310 | "notes": "Not used" 311 | } 312 | ] 313 | }, 314 | { "id": "NTE", "type": "segment", 315 | "name": "Note/Special Instruction", 316 | "req": "O", 317 | "max_uses": 100, 318 | "notes": "The NTE segment permits free-form information/data which, under ANSI X12 standard implementations, is not machine processable. The use of the NTE segment should therefore be avoided, if at all possible, in an automated environment.", 319 | "elements": [ 320 | { "id": "NTE01", "type": "element", 321 | "name": "Note Reference Code", 322 | "req": "O", 323 | "data_type": "ID", 324 | "data_type_ids": {"GEN": "Entire Transaction Set"}, 325 | "length": {"min": 3, "max": 3}, 326 | "notes": "Code identifying the functional area or purpose for which the note applies" 327 | }, 328 | { "id": "NTE02", "type": "element", 329 | "name": "Description", 330 | "req": "M", 331 | "data_type": "AN", 332 | "data_type_ids": null, 333 | "length": {"min": 1, "max": 80}, 334 | "notes": "A free-form description to clarify the related data elements and their content" 335 | } 336 | ] 337 | }, 338 | { "id": "CUR", "type": "segment", 339 | "name": "Currency", 340 | "req": "O", 341 | "max_uses": 1, 342 | "notes": "If the CUR segment is not used, monetary values are assumed to be expressed in the currency of the country of the transaction originator.", 343 | "elements": [ 344 | { "id": "CUR01", "type": "element", 345 | "name": "Entity Identifier Code", 346 | "req": "M", 347 | "data_type": "ID", 348 | "data_type_ids": {"SE": "Selling Party"}, 349 | "length": {"min": 2, "max": 3}, 350 | "notes": "Code identifying an organizational entity, a physical location, property or an individual" 351 | }, 352 | { "id": "CUR02", "type": "element", 353 | "name": "Currency Code", 354 | "req": "M", 355 | "data_type": "ID", 356 | "data_type_ids": {"USD": "US Dollars", "CAD": "Canadian Dollars"}, 357 | "length": {"min": 3, "max": 3}, 358 | "notes": "Code (Standard ISO) for country in whose currency the charges are specified" 359 | }, 360 | { "id": "CUR03", "type": "element", 361 | "name": "Exchange Rate", 362 | "req": "O", 363 | "data_type": "R", 364 | "data_type_ids": null, 365 | "length": {"min": 4, "max": 10}, 366 | "notes": "Value to be used as a multiplier conversion factor to convert monetary value from one currency to another" 367 | } 368 | ] 369 | }, 370 | { "id": "REF", "type": "segment", 371 | "name": "Reference Identification", 372 | "req": "O", 373 | "max_uses": 12, 374 | "notes": "", 375 | "syntax": [ 376 | {"rule": "ATLEASTONE", "criteria": [2, 3]} 377 | ], 378 | "elements": [ 379 | { "id": "REF01", "type": "element", 380 | "name": "Reference Identification Qualifier", 381 | "req": "M", 382 | "data_type": "ID", 383 | "data_type_ids": { 384 | "AP": "Accounts Receivable", 385 | "BM": "Bill of Lading Number", 386 | "CO": "Customer Order Number", 387 | "CT": "Contract Number", 388 | "LB": "Lock Box", 389 | "RE": "Release Number", 390 | "RY": "Rebate Number", 391 | "SA": "Salesperson", 392 | "SI": "Shipper's Identifying Number", 393 | "VN": "Vendor Order Number", 394 | "ZZ": "Mutually Defined" 395 | }, 396 | "length": {"min": 2, "max": 3}, 397 | "notes": "Code qualifying the Reference Identification" 398 | }, 399 | { "id": "REF02", "type": "element", 400 | "name": "Reference Identification Number", 401 | "req": "O", 402 | "data_type": "AN", 403 | "data_type_ids": null, 404 | "length": {"min": 1, "max": 30}, 405 | "notes": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier" 406 | }, 407 | { "id": "REF03", "type": "element", 408 | "name": "Description", 409 | "req": "O", 410 | "data_type": "AN", 411 | "data_type_ids": null, 412 | "length": {"min": 1, "max": 30}, 413 | "notes": "A free-form description to clarify the related data elements and their content" 414 | } 415 | ] 416 | }, 417 | { "id": "L_N1", "type": "loop", 418 | "name": "Name Loop", 419 | "req": "O", 420 | "repeat": 200, 421 | "segments": [ 422 | { "id": "N1", "type": "segment", 423 | "name": "Name", 424 | "req": "O", 425 | "max_uses": 1, 426 | "notes": "To identify a party by type of organization, name, and code", 427 | "elements": [ 428 | { "id": "N101", "name": "Entity Identifier Code", 429 | "type": "element", 430 | "req": "M", 431 | "data_type": "ID", 432 | "data_type_ids": { 433 | "BT": "Bill-to-Party", 434 | "BY": "Buying Party (Purchaser)", 435 | "CA": "Carrier", 436 | "DU": "Reseller", 437 | "EN": "End User", 438 | "II": "Issuer of Invoice", 439 | "PR": "Payer", 440 | "SE": "Selling Party", 441 | "SO": "Sold To If Different From Bill To", 442 | "ST": "Ship To", 443 | "VN": "Vendor" 444 | }, 445 | "length": {"min": 2, "max": 3}, 446 | "notes": "Code identifying an organizational entity, a physical location, property or an individual" 447 | }, 448 | { "id": "N102", "name": "Name", 449 | "type": "element", 450 | "req": "O", 451 | "data_type": "AN", 452 | "data_type_ids": null, 453 | "length": {"min": 1, "max": 60}, 454 | "notes": "Free-form name" 455 | }, 456 | { "id": "N103", "name": "Identification Code Qualifier", 457 | "type": "element", 458 | "req": "O", 459 | "data_type": "ID", 460 | "data_type_ids": null, 461 | "length": {"min": 1, "max": 2}, 462 | "notes": "Code designating the system/method of code structure used for Identification Code (N104)" 463 | }, 464 | { "id": "N104", "name": "Identification Code", 465 | "type": "element", 466 | "req": "O", 467 | "data_type": "ID", 468 | "data_type_ids": { 469 | "1": "DUNS Number", 470 | "9": "DUNS Number with 4-digit suffix", 471 | "21": "Health Care Industry ID No.", 472 | "91": "Assigned by seller", 473 | "92": "Assigned by Buyer or Agent", 474 | "ZZ": "Mutually Defined" 475 | }, 476 | "length": {"min": 1, "max": 2}, 477 | "notes": "Receiver ID Number" 478 | } 479 | ] 480 | }, 481 | { "id": "N2", "type": "segment", 482 | "name": "Additional Name Information", 483 | "req": "O", 484 | "max_uses": 2, 485 | "notes": "To specify additional names or those longer than 35 characters in length", 486 | "elements": [ 487 | { "id": "N201", "type": "element", 488 | "name": "Name", 489 | "req": "M", 490 | "data_type": "AN", 491 | "data_type_ids": null, 492 | "length": {"min": 1, "max": 60}, 493 | "notes": "Free-form name" 494 | }, 495 | { "id": "N202", "type": "element", 496 | "name": "Name", 497 | "req": "O", 498 | "data_type": "AN", 499 | "data_type_ids": null, 500 | "length": {"min": 1, "max": 60}, 501 | "notes": "Free-form name" 502 | } 503 | ] 504 | }, 505 | { "id": "N3", "type": "segment", 506 | "name": "Address Information", 507 | "req": "O", 508 | "max_uses": 2, 509 | "notes": "To specify the location of the named party", 510 | "elements": [ 511 | { "id": "N301", "name": "Address Information", 512 | "type": "element", 513 | "req": "M", 514 | "data_type": "AN", 515 | "data_type_ids": null, 516 | "length": {"min": 1, "max": 55}, 517 | "notes": "Address Information" 518 | }, 519 | { "id": "N302", "name": "Address Information", 520 | "type": "element", 521 | "req": "O", 522 | "data_type": "AN", 523 | "data_type_ids": null, 524 | "length": {"min": 1, "max": 55}, 525 | "notes": "Address Information" 526 | } 527 | ] 528 | }, 529 | { "id": "N4", "type": "segment", 530 | "name": "Geographic Location", 531 | "req": "O", 532 | "max_uses": 1, 533 | "notes": "To specify the geographic place of the named party", 534 | "elements": [ 535 | { "id": "N401", "type": "element", 536 | "name": "City Name", 537 | "req": "O", 538 | "data_type": "AN", 539 | "data_type_ids": null, 540 | "length": {"min": 2, "max": 30}, 541 | "notes": "Address Information" 542 | }, 543 | { "id": "N402", "type": "element", 544 | "name": "State or Province Code", 545 | "req": "O", 546 | "data_type": "ID", 547 | "data_type_ids": null, 548 | "length": {"min": 2, "max": 2}, 549 | "notes": "Code (Standard State/Province) as defined by appropriate government agency" 550 | }, 551 | { "id": "N403", "type": "element", 552 | "name": "Postal Code", 553 | "req": "O", 554 | "data_type": "ID", 555 | "data_type_ids": null, 556 | "length": {"min": 3, "max": 15}, 557 | "notes": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)" 558 | }, 559 | { "id": "N404", "type": "element", 560 | "name": "Country Code", 561 | "req": "O", 562 | "data_type": "ID", 563 | "data_type_ids": null, 564 | "length": {"min": 2, "max": 3}, 565 | "notes": "Code identifying the country" 566 | } 567 | ] 568 | }, 569 | { "id": "PER", "type": "segment", 570 | "name": "Administrative Communications Contact", 571 | "req": "O", 572 | "max_uses": 3, 573 | "notes": "To identify a person or office to whom administrative communications should be directed", 574 | "elements": [ 575 | { "id": "PER01", "type": "element", 576 | "name": "Contact Function Code", 577 | "req": "M", 578 | "data_type": "ID", 579 | "data_type_ids": {"CN": "General Contact", "RE": "Contact For Problems"}, 580 | "length": {"min": 2, "max": 2}, 581 | "notes": "Code identifying the major duty or responsibility of the person or group named" 582 | }, 583 | { "id": "PER02", "type": "element", 584 | "name": "Name", 585 | "req": "O", 586 | "data_type": "AN", 587 | "data_type_ids": null, 588 | "length": {"min": 1, "max": 60}, 589 | "notes": "Free-form name" 590 | }, 591 | { "id": "PER03", "type": "element", 592 | "name": "Communications Number Type", 593 | "req": "O", 594 | "data_type": "ID", 595 | "data_type_ids": {"TE": "Telephone", "EM": "Email", "FX": "Facsimile"}, 596 | "length": {"min": 2, "max": 2}, 597 | "notes": "Code identifying the communications number type" 598 | }, 599 | { "id": "PER04", "type": "element", 600 | "name": "Communications Number", 601 | "req": "O", 602 | "data_type": "AN", 603 | "data_type_ids": null, 604 | "length": {"min": 1, "max": 80}, 605 | "notes": "Number for communications" 606 | } 607 | ] 608 | } 609 | ] 610 | }, 611 | { "id": "ITD", "type": "segment", 612 | "name": "Terms of Sale/Deferred Terms of Sale", 613 | "req": "O", 614 | "max_uses": 10, 615 | "notes": "To specify terms of sale. In the Header position of the Invoice X12 EDI document, this segment is used to specify terms of the invoice. In the transitional period for the microcomputer industry, from paper to full automated EDI transactions, there may be a perceived need to send text data with the terms. Clearly the goal is to have the entire microcomputer industry participating in EDI. Therefore, if text data is needed to be sent for terms, ITD 12 will contain the free form text. If additional text is needed, additional ITD segments should be used.", 616 | "syntax": [ 617 | {"rule": "IFATLEASTONE", "criteria": [3, 4, 5]}, 618 | {"rule": "IFATLEASTONE", "criteria": [8, 4, 5]}, 619 | {"rule": "IFATLEASTONE", "criteria": [9, 10, 11]} 620 | ], 621 | "elements": [ 622 | { "id": "ITD01", "type": "element", 623 | "name": "Terms Type Code", 624 | "req": "O", 625 | "data_type": "ID", 626 | "data_type_ids": {"14": "Previously agreed upon"}, 627 | "length": {"min": 2, "max": 2}, 628 | "notes": "Code identifying type of payment terms" 629 | }, 630 | { "id": "ITD02", "type": "element", 631 | "name": "Terms Basis Date Code", 632 | "req": "O", 633 | "data_type": "ID", 634 | "data_type_ids": {"3": "Invoice Date"}, 635 | "length": {"min": 1, "max": 2}, 636 | "notes": "Code identifying the beginning of the terms period" 637 | }, 638 | { "id": "ITD03", "type": "element", 639 | "name": "Terms Discount %", 640 | "req": "O", 641 | "data_type": "R", 642 | "data_type_ids": null, 643 | "length": {"min": 1, "max": 6}, 644 | "notes": "Available to hospital if invoice is paid on or before Terms Discount Due Date" 645 | }, 646 | { "id": "ITD04", "type": "element", 647 | "name": "Terms Discount Due Date", 648 | "req": "O", 649 | "data_type": "DT", 650 | "data_type_ids": null, 651 | "length": {"min": 8, "max": 8}, 652 | "notes": "Date payment is due if discount is to be earned (CCYYMMDD)" 653 | }, 654 | { "id": "ITD05", "type": "element", 655 | "name": "Terms Discount Days Due", 656 | "req": "O", 657 | "data_type": "N0", 658 | "data_type_ids": null, 659 | "length": {"min": 1, "max": 3}, 660 | "notes": "Maximum number of days to pass before payment is due" 661 | }, 662 | { "id": "ITD06", "type": "element", 663 | "name": "Terms Net Due Date", 664 | "req": "O", 665 | "data_type": "DT", 666 | "data_type_ids": null, 667 | "length": {"min": 8, "max": 8}, 668 | "notes": "Date when total invoice amount is due" 669 | }, 670 | { "id": "ITD07", "type": "element", 671 | "name": "Terms Net Days", 672 | "req": "O", 673 | "data_type": "N0", 674 | "data_type_ids": null, 675 | "length": {"min": 1, "max": 3}, 676 | "notes": "Payment terms in net days" 677 | }, 678 | { "id": "ITD08", "type": "element", 679 | "name": "Terms Discount Amount", 680 | "req": "O", 681 | "data_type": "N2", 682 | "data_type_ids": null, 683 | "length": {"min": 1, "max": 10}, 684 | "notes": "Total amount of terms discount" 685 | }, 686 | { "id": "ITD09", "type": "element", 687 | "name": "Terms Deferred Due Date", 688 | "req": "O", 689 | "data_type": "DT", 690 | "data_type_ids": null, 691 | "length": {"min": 8, "max": 8}, 692 | "notes": "Date deferred payment or percent of invoice payable is due" 693 | }, 694 | { "id": "ITD10", "type": "element", 695 | "name": "Deferred Amount Due", 696 | "req": "O", 697 | "data_type": "N2", 698 | "data_type_ids": null, 699 | "length": {"min": 1, "max": 10}, 700 | "notes": "Deferred amount due for payment" 701 | }, 702 | { "id": "ITD11", "type": "element", 703 | "name": "% Invoice Payable", 704 | "req": "O", 705 | "data_type": "R", 706 | "data_type_ids": null, 707 | "length": {"min": 1, "max": 5}, 708 | "notes": "Amount of invoice payable expressed in percent" 709 | }, 710 | { "id": "ITD12", "type": "element", 711 | "name": "Description", 712 | "req": "O", 713 | "data_type": "AN", 714 | "data_type_ids": null, 715 | "length": {"min": 1, "max": 80}, 716 | "notes": "Description of terms" 717 | } 718 | ] 719 | }, 720 | { "id": "DTM", "type": "segment", 721 | "name": "Date/Time Reference", 722 | "req": "O", 723 | "max_uses": 10, 724 | "notes": "To identify a date or time", 725 | "elements": [ 726 | { "id": "DTM01", "type": "element", 727 | "name": "Date/Time Qualifier", 728 | "req": "M", 729 | "data_type": "ID", 730 | "data_type_ids": {"002": "Delivery requested", "011": "Shipped", "036": "Expiration Date"}, 731 | "length": {"min": 3, "max": 3}, 732 | "notes": "Code specifying type of date or time, or both date and time" 733 | }, 734 | { "id": "DTM02", "type": "element", 735 | "name": "Date", 736 | "req": "O", 737 | "data_type": "DT", 738 | "data_type_ids": null, 739 | "length": {"min": 8, "max": 8}, 740 | "notes": "Date expressed as CCYYMMDD" 741 | }, 742 | { "id": "DTM03", "type": "element", 743 | "name": "Time", 744 | "req": "O", 745 | "data_type": "TM", 746 | "data_type_ids": null, 747 | "length": {"min": 4, "max": 8}, 748 | "notes": "Time" 749 | } 750 | ] 751 | }, 752 | { "id": "N9", "type": "segment", 753 | "name": "Reference", 754 | "req": "O", 755 | "max_uses": 1, 756 | "notes": "Used with notes", 757 | "elements": [ 758 | { "id": "N901", "type": "element", 759 | "name": "Reference Ident. Qualifier", 760 | "req": "M", 761 | "data_type": "ID", 762 | "data_type_ids": {"ZZ": "Mutually Defined"}, 763 | "length": {"min": 2, "max": 3}, 764 | "notes": "Code specifying type of date or time, or both date and time" 765 | }, 766 | { "id": "N902", "type": "element", 767 | "name": "Reference Identification", 768 | "req": "O", 769 | "data_type": "AN", 770 | "data_type_ids": null, 771 | "length": {"min": 1, "max": 30}, 772 | "notes": "MSG to Follow" 773 | }, 774 | { "id": "N903", "type": "element", 775 | "name": "Other", 776 | "req": "O", 777 | "data_type": "AN", 778 | "data_type_ids": null, 779 | "length": {"min": 1, "max": 80}, 780 | "notes": "" 781 | } 782 | ] 783 | }, 784 | { "id": "MSG", "type": "segment", 785 | "name": "Text Message", 786 | "req": "O", 787 | "max_uses": 10, 788 | "notes": "Free-form text", 789 | "elements": [ 790 | { "id": "MSG01", "type": "element", 791 | "name": "Message Text", 792 | "req": "M", 793 | "data_type": "AN", 794 | "data_type_ids": null, 795 | "length": {"min": 1, "max": 264}, 796 | "notes": "Free-form text" 797 | } 798 | ] 799 | }, 800 | { "id": "L_IT1", "type": "loop", 801 | "name": "Baseline Item Data Loop", 802 | "req": "O", 803 | "repeat": 200000, 804 | "segments": [ 805 | { "id": "IT1", "type": "segment", 806 | "name": "Baseline Item Data (Invoice)", 807 | "req": "M", 808 | "max_uses": 1, 809 | "notes": "To specify the basic and most frequently used line item data for the invoice and related transactions", 810 | "syntax": [ 811 | {"rule": "ALLORNONE", "criteria": [2, 3, 4]}, 812 | {"rule": "ALLORNONE", "criteria": [6, 7]}, 813 | {"rule": "ALLORNONE", "criteria": [8, 9]}, 814 | {"rule": "ALLORNONE", "criteria": [10, 11]}, 815 | {"rule": "ALLORNONE", "criteria": [12, 13]}, 816 | {"rule": "ALLORNONE", "criteria": [14, 15]}, 817 | {"rule": "ALLORNONE", "criteria": [16, 17]}, 818 | {"rule": "ALLORNONE", "criteria": [18, 19]}, 819 | {"rule": "ALLORNONE", "criteria": [20, 21]}, 820 | {"rule": "ALLORNONE", "criteria": [22, 23]}, 821 | {"rule": "ALLORNONE", "criteria": [24, 25]} 822 | ], 823 | "elements": [ 824 | { "id": "IT101", "type": "element", 825 | "name": "Assigned Identification", 826 | "req": "O", 827 | "data_type": "AN", 828 | "data_type_ids": null, 829 | "length": {"min": 1, "max": 20}, 830 | "notes": "Alphanumeric characters assigned for differentiation within a transaction set. May be original line number from PO" 831 | }, 832 | { "id": "IT102", "type": "element", 833 | "name": "Quantity Invoiced", 834 | "req": "O", 835 | "data_type": "R", 836 | "data_type_ids": null, 837 | "length": {"min": 1, "max": 10}, 838 | "notes": "Date expressed as CCYYMMDD" 839 | }, 840 | { "id": "IT103", "type": "element", 841 | "name": "Unit or Basis for Measurement Code", 842 | "req": "O", 843 | "data_type": "ID", 844 | "data_type_ids": {"EA": "Each"}, 845 | "length": {"min": 2, "max": 2}, 846 | "notes": "Code specifying the units in which a value is being expressed, or manner in which a measurement has been taken" 847 | }, 848 | { "id": "IT104", "type": "element", 849 | "name": "Unit Price", 850 | "req": "O", 851 | "data_type": "R", 852 | "data_type_ids": null, 853 | "length": {"min": 1, "max": 17}, 854 | "notes": "Price per unit of product, service, commodity, etc." 855 | }, 856 | { "id": "IT105", "type": "element", 857 | "name": "Basis of Unit Price Code", 858 | "req": "O", 859 | "data_type": "ID", 860 | "data_type_ids": {"CP": "Current Price (Subject to Change)", "NC": "No Cost"}, 861 | "length": {"min": 2, "max": 2}, 862 | "notes": "Code identifying the type of unit price for an item" 863 | }, 864 | { "id": "IT106", "type": "element", 865 | "name": "Product/Service ID Qualifier", 866 | "req": "O", 867 | "data_type": "ID", 868 | "data_type_ids": {"VP": "Vendor's (Seller's) Part Number", "MG": "Manufacturer ID"}, 869 | "length": {"min": 2, "max": 2}, 870 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID" 871 | }, 872 | { "id": "IT107", "type": "element", 873 | "name": "Product/Service ID", 874 | "req": "O", 875 | "data_type": "AN", 876 | "data_type_ids": null, 877 | "length": {"min": 1, "max": 48}, 878 | "notes": "Identifying number for a product or service" 879 | }, 880 | { "id": "IT108", "type": "element", 881 | "name": "Product/Service ID Qualifier", 882 | "req": "O", 883 | "data_type": "ID", 884 | "data_type_ids": {"BP": "Buyer's Part Number"}, 885 | "length": {"min": 2, "max": 2}, 886 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID" 887 | }, 888 | { "id": "IT109", "type": "element", 889 | "name": "Product/Service ID", 890 | "req": "O", 891 | "data_type": "AN", 892 | "data_type_ids": null, 893 | "length": {"min": 1, "max": 48}, 894 | "notes": "Identifying number for a product or service" 895 | }, 896 | { "id": "IT110", "type": "element", 897 | "name": "Product/Service ID Qualifier", 898 | "req": "O", 899 | "data_type": "ID", 900 | "data_type_ids": {"UP": "U.P.C. Consumer Package Code (1-5-5-1)"}, 901 | "length": {"min": 2, "max": 2}, 902 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID" 903 | }, 904 | { "id": "IT111", "type": "element", 905 | "name": "Product/Service ID", 906 | "req": "O", 907 | "data_type": "AN", 908 | "data_type_ids": null, 909 | "length": {"min": 1, "max": 48}, 910 | "notes": "Identifying number for a product or service" 911 | } 912 | ] 913 | }, 914 | { "id": "TXI", "type": "segment", 915 | "name": "Tax Information", 916 | "req": "O", 917 | "max_uses": 1, 918 | "notes": "To specify tax information", 919 | "syntax": [ 920 | {"rule": "ATLEASTONE", "criteria": [2, 3, 6]}, 921 | {"rule": "ALLORNONE", "criteria": [4, 5]}, 922 | {"rule": "IFATLEASTONE", "criteria": [8, 3]} 923 | ], 924 | "elements": [ 925 | { "id": "TXI01", "type": "element", 926 | "name": "Tax Type Code", 927 | "req": "M", 928 | "data_type": "ID", 929 | "data_type_ids": {"ST": "State Sales Tax"}, 930 | "length": {"min": 2, "max": 2}, 931 | "notes": "Amount before terms discount" 932 | }, 933 | { "id": "TXI02", "type": "element", 934 | "name": "Monetary Amount", 935 | "req": "O", 936 | "data_type": "R", 937 | "data_type_ids": null, 938 | "length": {"min": 1, "max": 18}, 939 | "notes": "Monetary amount" 940 | }, 941 | { "id": "TXI03", "type": "element", 942 | "name": "Percent", 943 | "req": "O", 944 | "data_type": "R", 945 | "data_type_ids": null, 946 | "length": {"min": 1, "max": 10}, 947 | "notes": "Percentage expressed as a decimal" 948 | }, 949 | { "id": "TXI04", "type": "element", 950 | "name": "Tax Jurisdiction Code Qualifier", 951 | "req": "O", 952 | "data_type": "ID", 953 | "data_type_ids": {"CD": "Customer Defined", "VD": "Vendor Defined"}, 954 | "length": {"min": 2, "max": 2}, 955 | "notes": "Code identifying the source of the data used in tax jurisdiction code" 956 | }, 957 | { "id": "TXI05", "type": "element", 958 | "name": "Tax Jurisdiction Code", 959 | "req": "O", 960 | "data_type": "AN", 961 | "data_type_ids": null, 962 | "length": {"min": 1, "max": 10}, 963 | "notes": "Code identifying the taxing jurisdiction" 964 | }, 965 | { "id": "TXI06", "type": "element", 966 | "name": "Tax Exempt Code", 967 | "req": "O", 968 | "data_type": "ID", 969 | "data_type_ids": { 970 | "0": "Exempt (for Export)", 971 | "1": "Yes (Tax Exempt)", 972 | "2": "No (Not Tax Exempt)", 973 | "3": "Exempt (For Resale)", 974 | "4": "Not Exempt/For Resale", 975 | "5": "Exempt (Not For Resale)", 976 | "6": "Not Exempt, Not For Resale", 977 | "7": "Direct Pay ID", 978 | "8": "Exempt (Sale to U.S. Government)", 979 | "9": "Exempt (Per State Law", 980 | "A": "Labor Taxable, Material Exempt", 981 | "B": "Material Taxable, Labor Exempt", 982 | "C": "Not Taxable", 983 | "V": "Exempt from State Property Tax", 984 | "W": "Other Property Tax Exemption", 985 | "X": "Exempt - Letter on file" 986 | }, 987 | "length": {"min": 1, "max": 1}, 988 | "notes": "Code identifying exemption status from sales and use tax" 989 | }, 990 | { "id": "TXI07", "type": "element", 991 | "name": "Relationship Code", 992 | "req": "O", 993 | "data_type": "ID", 994 | "data_type_ids": null, 995 | "length": {"min": 1, "max": 1}, 996 | "notes": "Code indicating the relationship between entities" 997 | }, 998 | { "id": "TXI08", "type": "element", 999 | "name": "Dollar Basis for Percent", 1000 | "req": "O", 1001 | "data_type": "R", 1002 | "data_type_ids": null, 1003 | "length": {"min": 1, "max": 9}, 1004 | "notes": "Dollar basis to be used in the percent calculation of the allowance, charge, or tax" 1005 | }, 1006 | { "id": "TXI09", "type": "element", 1007 | "name": "Tax Identification Number", 1008 | "req": "O", 1009 | "data_type": "AN", 1010 | "data_type_ids": null, 1011 | "length": {"min": 1, "max": 20}, 1012 | "notes": "Number assigned to a purchaser (buyer, orderer) by a taxing jurisdiction (state, county, etc.); often called a tax exemption number or certificat number" 1013 | }, 1014 | { "id": "TXI10", "type": "element", 1015 | "name": "Assigned Identification", 1016 | "req": "O", 1017 | "data_type": "AN", 1018 | "data_type_ids": null, 1019 | "length": {"min": 1, "max": 20}, 1020 | "notes": "Alphanumeric characters assigned for differentiation within a transaction set" 1021 | } 1022 | ] 1023 | }, 1024 | { "id": "L_PID", "type": "loop", 1025 | "name": "Product/Item Description Loop", 1026 | "req": "O", 1027 | "repeat": 1000, 1028 | "segments": [ 1029 | { "id": "PID", "type": "segment", 1030 | "name": "Product/Item Description", 1031 | "req": "O", 1032 | "max_uses": 1, 1033 | "notes": "To describe a product or process in coded or free-form format", 1034 | "syntax": [ 1035 | {"rule": "IFATLEASTONE", "criteria": [4, 3]}, 1036 | {"rule": "ATLEASTONE", "criteria": [4, 5]}, 1037 | {"rule": "IFATLEASTONE", "criteria": [7, 3]}, 1038 | {"rule": "IFATLEASTONE", "criteria": [8, 4]}, 1039 | {"rule": "IFATLEASTONE", "criteria": [9, 5]} 1040 | ], 1041 | "elements": [ 1042 | { "id": "PID01", "type": "element", 1043 | "name": "Item Description Type", 1044 | "req": "M", 1045 | "data_type": "ID", 1046 | "data_type_ids": {"X": "Mutually Defined", "F": "Freeform"}, 1047 | "length": {"min": 1, "max": 1}, 1048 | "notes": "Code indicating the format of a description" 1049 | }, 1050 | { "id": "PID02", "type": "element", 1051 | "name": "Product/Process Characteristic Code", 1052 | "req": "O", 1053 | "data_type": "ID", 1054 | "data_type_ids": null, 1055 | "length": {"min": 2, "max": 3}, 1056 | "notes": "Not used" 1057 | }, 1058 | { "id": "PID03", "type": "element", 1059 | "name": "Association Qualifier Code", 1060 | "req": "O", 1061 | "data_type": "ID", 1062 | "data_type_ids": null, 1063 | "length": {"min": 2, "max": 2}, 1064 | "notes": "Not used" 1065 | }, 1066 | { "id": "PID04", "type": "element", 1067 | "name": "Product Description Code", 1068 | "req": "O", 1069 | "data_type": "ID", 1070 | "data_type_ids": null, 1071 | "length": {"min": 1, "max": 12}, 1072 | "notes": "Not used" 1073 | }, 1074 | { "id": "PID05", "type": "element", 1075 | "name": "Description", 1076 | "req": "O", 1077 | "data_type": "AN", 1078 | "data_type_ids": null, 1079 | "length": {"min": 1, "max": 80}, 1080 | "notes": "A free-form description to clarify the related data elements and their content" 1081 | } 1082 | ] 1083 | } 1084 | ] 1085 | }, 1086 | { "id": "REF", "type": "segment", 1087 | "name": "Reference Information", 1088 | "req": "O", 1089 | "max_uses": 10, 1090 | "notes": "To specify other information", 1091 | "syntax": [], 1092 | "elements": [ 1093 | { "id": "REF01", "type": "element", 1094 | "name": "Reference Code Type", 1095 | "req": "M", 1096 | "data_type": "ID", 1097 | "data_type_ids": {}, 1098 | "length": {"min": 2, "max": 2}, 1099 | "notes": "" 1100 | }, 1101 | { "id": "REF02", "type": "element", 1102 | "name": "Reference Code Value", 1103 | "req": "O", 1104 | "data_type": "AN", 1105 | "data_type_ids": null, 1106 | "length": {"min": 1, "max": 80}, 1107 | "notes": "" 1108 | } 1109 | ] 1110 | }, 1111 | { "id": "DTM", "type": "segment", 1112 | "name": "Date/Time Reference", 1113 | "req": "O", 1114 | "max_uses": 10, 1115 | "notes": "To identify a person or office to whom administrative communications should be directed", 1116 | "elements": [ 1117 | { "id": "DTM01", "type": "element", 1118 | "name": "Date/Time Qualifier", 1119 | "req": "M", 1120 | "data_type": "ID", 1121 | "data_type_ids": {"002": "Delivery requested", "011": "Shipped", "036": "Expiration Date"}, 1122 | "length": {"min": 3, "max": 3}, 1123 | "notes": "Code specifying type of date or time, or both date and time" 1124 | }, 1125 | { "id": "DTM02", "type": "element", 1126 | "name": "Date", 1127 | "req": "O", 1128 | "data_type": "DT", 1129 | "data_type_ids": null, 1130 | "length": {"min": 8, "max": 8}, 1131 | "notes": "Date expressed as CCYYMMDD" 1132 | }, 1133 | { "id": "DTM03", "type": "element", 1134 | "name": "Time", 1135 | "req": "O", 1136 | "data_type": "TM", 1137 | "data_type_ids": null, 1138 | "length": {"min": 4, "max": 8}, 1139 | "notes": "Time" 1140 | } 1141 | ] 1142 | } 1143 | ] 1144 | }, 1145 | { "id": "TDS", "type": "segment", 1146 | "name": "Total Monetary Value Summary", 1147 | "req": "M", 1148 | "max_uses": 1, 1149 | "notes": "To specify the total invoice discounts and amounts.", 1150 | "elements": [ 1151 | { "id": "TDS01", "type": "element", 1152 | "name": "Total Invoice Amount", 1153 | "req": "M", 1154 | "data_type": "N2", 1155 | "data_type_ids": null, 1156 | "length": {"min": 1, "max": 15}, 1157 | "notes": "Amount before terms discount" 1158 | }, 1159 | { "id": "TDS02", "type": "element", 1160 | "name": "Amt. Subj. to Terms Discount", 1161 | "req": "O", 1162 | "data_type": "N2", 1163 | "data_type_ids": null, 1164 | "length": {"min": 1, "max": 15}, 1165 | "notes": "Amount upon which the terms discount amount is calculated" 1166 | }, 1167 | { "id": "TDS03", "type": "element", 1168 | "name": "Discounted Amount Due", 1169 | "req": "O", 1170 | "data_type": "N2", 1171 | "data_type_ids": null, 1172 | "length": {"min": 1, "max": 15}, 1173 | "notes": "Amount of invoice due if paid by terms discount due date" 1174 | }, 1175 | { "id": "TDS04", "type": "element", 1176 | "name": "Terms Discount Amount", 1177 | "req": "O", 1178 | "data_type": "N2", 1179 | "data_type_ids": null, 1180 | "length": {"min": 1, "max": 15}, 1181 | "notes": "Total amount of terms discount" 1182 | } 1183 | ] 1184 | }, 1185 | { "id": "TXI", "type": "segment", 1186 | "name": "Tax Information", 1187 | "req": "O", 1188 | "max_uses": 10, 1189 | "notes": "To specify tax information", 1190 | "syntax": [ 1191 | {"rule": "ATLEASTONE", "criteria": [2, 3, 6]}, 1192 | {"rule": "ALLORNONE", "criteria": [4, 5]}, 1193 | {"rule": "IFATLEASTONE", "criteria": [8, 3]} 1194 | ], 1195 | "elements": [ 1196 | { "id": "TXI01", "type": "element", 1197 | "name": "Tax Type Code", 1198 | "req": "M", 1199 | "data_type": "ID", 1200 | "data_type_ids": {"ST": "State Sales Tax"}, 1201 | "length": {"min": 2, "max": 2}, 1202 | "notes": "Amount before terms discount" 1203 | }, 1204 | { "id": "TXI02", "type": "element", 1205 | "name": "Monetary Amount", 1206 | "req": "O", 1207 | "data_type": "R", 1208 | "data_type_ids": null, 1209 | "length": {"min": 1, "max": 18}, 1210 | "notes": "Monetary amount" 1211 | }, 1212 | { "id": "TXI03", "type": "element", 1213 | "name": "Percent", 1214 | "req": "O", 1215 | "data_type": "R", 1216 | "data_type_ids": null, 1217 | "length": {"min": 1, "max": 10}, 1218 | "notes": "Percentage expressed as a decimal" 1219 | }, 1220 | { "id": "TXI04", "type": "element", 1221 | "name": "Tax Jurisdiction Code Qualifier", 1222 | "req": "O", 1223 | "data_type": "ID", 1224 | "data_type_ids": {"CD": "Customer Defined", "VD": "Vendor Defined"}, 1225 | "length": {"min": 2, "max": 2}, 1226 | "notes": "Code identifying the source of the data used in tax jurisdiction code" 1227 | }, 1228 | { "id": "TXI05", "type": "element", 1229 | "name": "Tax Jurisdiction Code", 1230 | "req": "O", 1231 | "data_type": "AN", 1232 | "data_type_ids": null, 1233 | "length": {"min": 1, "max": 10}, 1234 | "notes": "Code identifying the taxing jurisdiction" 1235 | }, 1236 | { "id": "TXI06", "type": "element", 1237 | "name": "Tax Exempt Code", 1238 | "req": "O", 1239 | "data_type": "ID", 1240 | "data_type_ids": { 1241 | "0": "Exempt (for Export)", 1242 | "1": "Yes (Tax Exempt)", 1243 | "2": "No (Not Tax Exempt)", 1244 | "3": "Exempt (For Resale)", 1245 | "4": "Not Exempt/For Resale", 1246 | "5": "Exempt (Not For Resale)", 1247 | "6": "Not Exempt, Not For Resale", 1248 | "7": "Direct Pay ID", 1249 | "8": "Exempt (Sale to U.S. Government)", 1250 | "9": "Exempt (Per State Law", 1251 | "A": "Labor Taxable, Material Exempt", 1252 | "B": "Material Taxable, Labor Exempt", 1253 | "C": "Not Taxable", 1254 | "V": "Exempt from State Property Tax", 1255 | "W": "Other Property Tax Exemption", 1256 | "X": "Exempt - Letter on file" 1257 | }, 1258 | "length": {"min": 1, "max": 1}, 1259 | "notes": "Code identifying exemption status from sales and use tax" 1260 | }, 1261 | { "id": "TXI07", "type": "element", 1262 | "name": "Relationship Code", 1263 | "req": "O", 1264 | "data_type": "ID", 1265 | "data_type_ids": null, 1266 | "length": {"min": 1, "max": 1}, 1267 | "notes": "Code indicating the relationship between entities" 1268 | }, 1269 | { "id": "TXI08", "type": "element", 1270 | "name": "Dollar Basis for Percent", 1271 | "req": "O", 1272 | "data_type": "R", 1273 | "data_type_ids": null, 1274 | "length": {"min": 1, "max": 9}, 1275 | "notes": "Dollar basis to be used in the percent calculation of the allowance, charge, or tax" 1276 | }, 1277 | { "id": "TXI09", "type": "element", 1278 | "name": "Tax Identification Number", 1279 | "req": "O", 1280 | "data_type": "AN", 1281 | "data_type_ids": null, 1282 | "length": {"min": 1, "max": 20}, 1283 | "notes": "Number assigned to a purchaser (buyer, orderer) by a taxing jurisdiction (state, county, etc.); often called a tax exemption number or certificat number" 1284 | }, 1285 | { "id": "TXI10", "type": "element", 1286 | "name": "Assigned Identification", 1287 | "req": "O", 1288 | "data_type": "AN", 1289 | "data_type_ids": null, 1290 | "length": {"min": 1, "max": 20}, 1291 | "notes": "Alphanumeric characters assigned for differentiation within a transaction set" 1292 | } 1293 | ] 1294 | }, 1295 | { "id": "L_SAC", "type": "loop", 1296 | "name": "Service, Promotion, Allowance, or Charge Information Loop", 1297 | "req": "O", 1298 | "repeat": 25, 1299 | "segments": [ 1300 | { "id": "SAC", "type": "segment", 1301 | "name": "Service, Promotion, Allowance, or Charge Information", 1302 | "req": "O", 1303 | "max_uses": 1, 1304 | "notes": "To request or identify a service, promotion, allowance, or charge; to specify the amount or percentage for the service, promotion, allowance, or charge", 1305 | "syntax": [ 1306 | {"rule": "ATLEASTONE", "criteria": [2, 3]}, 1307 | {"rule": "ALLORNONE", "criteria": [3, 4]}, 1308 | {"rule": "ALLORNONE", "criteria": [6, 7]}, 1309 | {"rule": "ALLORNONE", "criteria": [9, 10]}, 1310 | {"rule": "IFATLEASTONE", "criteria": [11, 10]}, 1311 | {"rule": "IFATLEASTONE", "criteria": [13, 2, 4]}, 1312 | {"rule": "IFATLEASTONE", "criteria": [14, 13]}, 1313 | {"rule": "IFATLEASTONE", "criteria": [16, 15]} 1314 | ], 1315 | "elements": [ 1316 | { "id": "SAC01", "type": "element", 1317 | "name": "Allowance or Charge Indicator", 1318 | "req": "M", 1319 | "data_type": "ID", 1320 | "data_type_ids": {"C": "Charge"}, 1321 | "length": {"min": 1, "max": 1}, 1322 | "notes": "Code which indicates an allowance or charge for the service specified" 1323 | }, 1324 | { "id": "SAC02", "type": "element", 1325 | "name": "Service, Promotion, Allowance, or Charge Code", 1326 | "req": "O", 1327 | "data_type": "ID", 1328 | "data_type_ids": {"D240": "Freight"}, 1329 | "length": {"min": 4, "max": 4}, 1330 | "notes": "Code identifying the service, promotion, allowance, or charge" 1331 | }, 1332 | { "id": "SAC03", "type": "element", 1333 | "name": "Agency Qualifier Code", 1334 | "req": "O", 1335 | "data_type": "ID", 1336 | "data_type_ids": null, 1337 | "length": {"min": 2, "max": 2}, 1338 | "notes": "Code identifying the agency assigning the code values" 1339 | }, 1340 | { "id": "SAC04", "type": "element", 1341 | "name": "Agency Service, Promotion, Allowance, or Charge Code", 1342 | "req": "O", 1343 | "data_type": "AN", 1344 | "data_type_ids": null, 1345 | "length": {"min": 1, "max": 10}, 1346 | "notes": "Agency maintained code identifying the service, promotion, allowance, or charge" 1347 | }, 1348 | { "id": "SAC05", "type": "element", 1349 | "name": "Amount", 1350 | "req": "O", 1351 | "data_type": "N2", 1352 | "data_type_ids": null, 1353 | "length": {"min": 1, "max": 15}, 1354 | "notes": "Monetary amount" 1355 | }, 1356 | { "id": "SAC06", "type": "element", 1357 | "name": "Allowance/Charge Percent Qualifier", 1358 | "req": "O", 1359 | "data_type": "ID", 1360 | "data_type_ids": null, 1361 | "length": {"min": 1, "max": 1}, 1362 | "notes": "Code indicating on what basis allowance or charge percent is calculated" 1363 | }, 1364 | { "id": "SAC07", "type": "element", 1365 | "name": "Percent", 1366 | "req": "O", 1367 | "data_type": "R", 1368 | "data_type_ids": null, 1369 | "length": {"min": 1, "max": 6}, 1370 | "notes": "Percent expressed as a percent" 1371 | }, 1372 | { "id": "SAC08", "type": "element", 1373 | "name": "Rate", 1374 | "req": "O", 1375 | "data_type": "R", 1376 | "data_type_ids": null, 1377 | "length": {"min": 1, "max": 9}, 1378 | "notes": "Rate expressed in the standard monetary denomination for the currency specified" 1379 | }, 1380 | { "id": "SAC09", "type": "element", 1381 | "name": "Unit or Basis for Measurement Code", 1382 | "req": "O", 1383 | "data_type": "ID", 1384 | "data_type_ids": null, 1385 | "length": {"min": 2, "max": 2}, 1386 | "notes": "Code specifying the units in which a value is being expressed, or manner in which a measurement has been taken" 1387 | }, 1388 | { "id": "SAC10", "type": "element", 1389 | "name": "Quantity", 1390 | "req": "O", 1391 | "data_type": "R", 1392 | "data_type_ids": null, 1393 | "length": {"min": 1, "max": 15}, 1394 | "notes": "Numeric value of quantity" 1395 | }, 1396 | { "id": "SAC11", "type": "element", 1397 | "name": "Quantity", 1398 | "req": "O", 1399 | "data_type": "R", 1400 | "data_type_ids": null, 1401 | "length": {"min": 1, "max": 15}, 1402 | "notes": "Numeric value of quantity" 1403 | }, 1404 | { "id": "SAC12", "type": "element", 1405 | "name": "Allowance or Charge Method of Handling Code", 1406 | "req": "O", 1407 | "data_type": "ID", 1408 | "data_type_ids": null, 1409 | "length": {"min": 2, "max": 2}, 1410 | "notes": "Code indicating method of handling for an allowance or charge" 1411 | }, 1412 | { "id": "SAC13", "type": "element", 1413 | "name": "Reference Identification", 1414 | "req": "O", 1415 | "data_type": "AN", 1416 | "data_type_ids": null, 1417 | "length": {"min": 1, "max": 30}, 1418 | "notes": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier" 1419 | }, 1420 | { "id": "SAC14", "type": "element", 1421 | "name": "Option Number", 1422 | "req": "O", 1423 | "data_type": "AN", 1424 | "data_type_ids": null, 1425 | "length": {"min": 1, "max": 20}, 1426 | "notes": "A unique number identifying available promotion or allowance options when more than one is offered" 1427 | }, 1428 | { "id": "SAC15", "type": "element", 1429 | "name": "Description", 1430 | "req": "O", 1431 | "data_type": "AN", 1432 | "data_type_ids": null, 1433 | "length": {"min": 1, "max": 80}, 1434 | "notes": "A free-form description to clarify the related data elements and their content" 1435 | } 1436 | ] 1437 | }, 1438 | { "id": "TXI", "type": "segment", 1439 | "name": "Tax Information", 1440 | "req": "O", 1441 | "max_uses": 1, 1442 | "notes": "To specify tax information", 1443 | "syntax": [ 1444 | {"rule": "ATLEASTONE", "criteria": [2, 3, 6]}, 1445 | {"rule": "ALLORNONE", "criteria": [4, 5]}, 1446 | {"rule": "IFATLEASTONE", "criteria": [8, 3]} 1447 | ], 1448 | "elements": [ 1449 | { "id": "TXI01", "type": "element", 1450 | "name": "Tax Type Code", 1451 | "req": "M", 1452 | "data_type": "ID", 1453 | "data_type_ids": {"ST": "State Sales Tax"}, 1454 | "length": {"min": 2, "max": 2}, 1455 | "notes": "Amount before terms discount" 1456 | }, 1457 | { "id": "TXI02", "type": "element", 1458 | "name": "Monetary Amount", 1459 | "req": "O", 1460 | "data_type": "R", 1461 | "data_type_ids": null, 1462 | "length": {"min": 1, "max": 18}, 1463 | "notes": "Monetary amount" 1464 | }, 1465 | { "id": "TXI03", "type": "element", 1466 | "name": "Percent", 1467 | "req": "O", 1468 | "data_type": "R", 1469 | "data_type_ids": null, 1470 | "length": {"min": 1, "max": 10}, 1471 | "notes": "Percentage expressed as a decimal" 1472 | }, 1473 | { "id": "TXI04", "type": "element", 1474 | "name": "Tax Jurisdiction Code Qualifier", 1475 | "req": "O", 1476 | "data_type": "ID", 1477 | "data_type_ids": {"CD": "Customer Defined", "VD": "Vendor Defined"}, 1478 | "length": {"min": 2, "max": 2}, 1479 | "notes": "Code identifying the source of the data used in tax jurisdiction code" 1480 | }, 1481 | { "id": "TXI05", "type": "element", 1482 | "name": "Tax Jurisdiction Code", 1483 | "req": "O", 1484 | "data_type": "AN", 1485 | "data_type_ids": null, 1486 | "length": {"min": 1, "max": 10}, 1487 | "notes": "Code identifying the taxing jurisdiction" 1488 | }, 1489 | { "id": "TXI06", "type": "element", 1490 | "name": "Tax Exempt Code", 1491 | "req": "O", 1492 | "data_type": "ID", 1493 | "data_type_ids": { 1494 | "0": "Exempt (for Export)", 1495 | "1": "Yes (Tax Exempt)", 1496 | "2": "No (Not Tax Exempt)", 1497 | "3": "Exempt (For Resale)", 1498 | "4": "Not Exempt/For Resale", 1499 | "5": "Exempt (Not For Resale)", 1500 | "6": "Not Exempt, Not For Resale", 1501 | "7": "Direct Pay ID", 1502 | "8": "Exempt (Sale to U.S. Government)", 1503 | "9": "Exempt (Per State Law", 1504 | "A": "Labor Taxable, Material Exempt", 1505 | "B": "Material Taxable, Labor Exempt", 1506 | "C": "Not Taxable", 1507 | "V": "Exempt from State Property Tax", 1508 | "W": "Other Property Tax Exemption", 1509 | "X": "Exempt - Letter on file" 1510 | }, 1511 | "length": {"min": 1, "max": 1}, 1512 | "notes": "Code identifying exemption status from sales and use tax" 1513 | }, 1514 | { "id": "TXI07", "type": "element", 1515 | "name": "Relationship Code", 1516 | "req": "O", 1517 | "data_type": "ID", 1518 | "data_type_ids": null, 1519 | "length": {"min": 1, "max": 1}, 1520 | "notes": "Code indicating the relationship between entities" 1521 | }, 1522 | { "id": "TXI08", "type": "element", 1523 | "name": "Dollar Basis for Percent", 1524 | "req": "O", 1525 | "data_type": "R", 1526 | "data_type_ids": null, 1527 | "length": {"min": 1, "max": 9}, 1528 | "notes": "Dollar basis to be used in the percent calculation of the allowance, charge, or tax" 1529 | }, 1530 | { "id": "TXI09", "type": "element", 1531 | "name": "Tax Identification Number", 1532 | "req": "O", 1533 | "data_type": "AN", 1534 | "data_type_ids": null, 1535 | "length": {"min": 1, "max": 20}, 1536 | "notes": "Number assigned to a purchaser (buyer, orderer) by a taxing jurisdiction (state, county, etc.); often called a tax exemption number or certificat number" 1537 | }, 1538 | { "id": "TXI10", "type": "element", 1539 | "name": "Assigned Identification", 1540 | "req": "O", 1541 | "data_type": "AN", 1542 | "data_type_ids": null, 1543 | "length": {"min": 1, "max": 20}, 1544 | "notes": "Alphanumeric characters assigned for differentiation within a transaction set" 1545 | } 1546 | ] 1547 | } 1548 | ] 1549 | }, 1550 | { "id": "CTT", "type": "segment", 1551 | "name": "Transaction Totals", 1552 | "req": "O", 1553 | "max_uses": 1, 1554 | "notes": "To transmit a hash total for a specific element in the transaction set", 1555 | "syntax": [ 1556 | {"rule": "ALLORNONE", "criteria": [3, 4]}, 1557 | {"rule": "ALLORNONE", "criteria": [5, 6]} 1558 | ], 1559 | "elements": [ 1560 | { "id": "CTT01", "type": "element", 1561 | "name": "Number of Line Items", 1562 | "req": "M", 1563 | "data_type": "N0", 1564 | "data_type_ids": null, 1565 | "length": {"min": 1, "max": 6}, 1566 | "notes": "Total number of line items in the transaction set" 1567 | }, 1568 | { "id": "CTT02", "type": "element", 1569 | "name": "Hash totals", 1570 | "req": "O", 1571 | "data_type": "R", 1572 | "data_type_ids": null, 1573 | "length": {"min": 1, "max": 10}, 1574 | "notes": "Total of the number of units invoiced (sum of element IT102)" 1575 | } 1576 | ] 1577 | }, 1578 | { "id": "SE", "type": "segment", 1579 | "name": "Transaction Set Trailer", 1580 | "req": "M", 1581 | "max_uses": 1, 1582 | "notes": "To indicate the end of the transaction set and provide the count of the transmitted segments (including the beginning (ST) and ending (SE) segments)", 1583 | "elements": [ 1584 | { "id": "SE01", "type": "element", 1585 | "name": "Number of Included Segments", 1586 | "req": "M", 1587 | "data_type": "N0", 1588 | "data_type_ids": null, 1589 | "length": {"min": 1, "max": 10}, 1590 | "notes": "Total number of segments included in a transaction set including ST and SE segments" 1591 | }, 1592 | { "id": "SE02", "type": "element", 1593 | "name": "Transaction Set Control Number", 1594 | "req": "M", 1595 | "data_type": "AN", 1596 | "data_type_ids": null, 1597 | "length": {"min": 4, "max": 9}, 1598 | "notes": "Identifying control number that must be unique within the transaction set functional group assigned by the originator for a transaction set. Must match the control # in ST02" 1599 | } 1600 | ] 1601 | }, 1602 | { "id": "GE", "type": "segment", 1603 | "name": "Functional Group Trailer", 1604 | "req": "M", 1605 | "max_uses": 1, 1606 | "notes": "To indicate the end of a functional group and to provide control information", 1607 | "elements": [ 1608 | { "id": "GE01", "type": "element", 1609 | "name": "Number of Transaction Sets Included", 1610 | "req": "M", 1611 | "data_type": "N0", 1612 | "data_type_ids": null, 1613 | "length": {"min": 1, "max": 6}, 1614 | "notes": "Total number of transaction sets included in the functional group or interchange (transmission) group terminated by the trailer containing this data element" 1615 | }, 1616 | { "id": "GE02", "type": "element", 1617 | "name": "Group Control Number", 1618 | "req": "M", 1619 | "data_type": "N0", 1620 | "data_type_ids": null, 1621 | "length": {"min": 1, "max": 9}, 1622 | "notes": "Assigned number originated and maintained by the sender" 1623 | } 1624 | ] 1625 | }, 1626 | { "id": "IEA", "type": "segment", 1627 | "name": "Interchange Control Trailer", 1628 | "req": "M", 1629 | "max_uses": 1, 1630 | "notes": "To define the end of an interchange of zero or more functional groups and interchange-related control segments", 1631 | "elements": [ 1632 | { "id": "IEA01", "type": "element", 1633 | "name": "Number of Included Functional Groups", 1634 | "req": "M", 1635 | "data_type": "N0", 1636 | "data_type_ids": null, 1637 | "length": {"min": 1, "max": 5}, 1638 | "notes": "A count of the number of functional groups included in an interchange" 1639 | }, 1640 | { "id": "IEA02", "type": "element", 1641 | "name": "Interchange Control Number", 1642 | "req": "M", 1643 | "data_type": "N0", 1644 | "data_type_ids": null, 1645 | "length": {"min": 9, "max": 9}, 1646 | "notes": "A control number assigned by the interchange sender" 1647 | } 1648 | ] 1649 | } 1650 | 1651 | 1652 | ] -------------------------------------------------------------------------------- /pythonedi/formats/850.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "ISA", 4 | "type": "segment", 5 | "name": "Interchange Control Header", 6 | "req": "M", 7 | "max_uses": 1, 8 | "notes": "", 9 | "elements": [ 10 | { 11 | "id": "ISA01", 12 | "type": "element", 13 | "name": "Authorization Information Qualifier", 14 | "req": "M", 15 | "data_type": "ID", 16 | "data_type_ids": { 17 | "00": "(default)" 18 | }, 19 | "length": { 20 | "min": 2, 21 | "max": 2 22 | }, 23 | "notes": "Code to identify the type of information in the Authorization Information" 24 | }, 25 | { 26 | "id": "ISA02", 27 | "type": "element", 28 | "name": "Authorization Information", 29 | "req": "M", 30 | "data_type": "AN", 31 | "data_type_ids": null, 32 | "length": { 33 | "min": 10, 34 | "max": 10 35 | }, 36 | "notes": "Information used for additional identification or authorization of the interchange sender or the data in the interchange; the type of information is set by the Authorization Information Qualifier (I01)" 37 | }, 38 | { 39 | "id": "ISA03", 40 | "type": "element", 41 | "name": "Security Information Qualifier", 42 | "req": "M", 43 | "data_type": "ID", 44 | "data_type_ids": { 45 | "00": "(default)" 46 | }, 47 | "length": { 48 | "min": 2, 49 | "max": 2 50 | }, 51 | "notes": "Code to identify the type of information in the Security Information" 52 | }, 53 | { 54 | "id": "ISA04", 55 | "type": "element", 56 | "name": "Security Information", 57 | "req": "M", 58 | "data_type": "AN", 59 | "data_type_ids": null, 60 | "length": { 61 | "min": 10, 62 | "max": 10 63 | }, 64 | "notes": "This is used for identifying the security information about the interchange sender or the data in the interchange; the type of information is set by the Security Information Qualifier (I03)" 65 | }, 66 | { 67 | "id": "ISA05", 68 | "type": "element", 69 | "name": "Interchange Sender ID Qualifier", 70 | "req": "M", 71 | "data_type": "ID", 72 | "data_type_ids": { 73 | "ZZ": "Mutually Defined" 74 | }, 75 | "length": { 76 | "min": 2, 77 | "max": 2 78 | }, 79 | "notes": "Qualifier to designate the system/method of code structure used to designate the sender or receiver ID element being qualified" 80 | }, 81 | { 82 | "id": "ISA06", 83 | "type": "element", 84 | "name": "Interchange Sender ID", 85 | "req": "M", 86 | "data_type": "AN", 87 | "data_type_ids": null, 88 | "length": { 89 | "min": 15, 90 | "max": 15 91 | }, 92 | "notes": "Identification code published by the sender for other parties to use as the receiver ID to route data to them; the sender always codes this value in the sender ID element" 93 | }, 94 | { 95 | "id": "ISA07", 96 | "type": "element", 97 | "name": "Interchange Receiver ID Qualifier", 98 | "req": "M", 99 | "data_type": "ID", 100 | "data_type_ids": { 101 | "ZZ": "Mutually Defined" 102 | }, 103 | "length": { 104 | "min": 2, 105 | "max": 2 106 | }, 107 | "notes": "Qualifier to designate the system/method of code structure used to designate the sender or receiver ID element being qualified" 108 | }, 109 | { 110 | "id": "ISA08", 111 | "type": "element", 112 | "name": "Interchange Receiver ID", 113 | "req": "M", 114 | "data_type": "AN", 115 | "data_type_ids": null, 116 | "length": { 117 | "min": 15, 118 | "max": 15 119 | }, 120 | "notes": "Identification code published by the receiver of the data; When sending, it is used by the sender as their sending ID, thus other parties sending to them will use this as a receiving ID to route data to them" 121 | }, 122 | { 123 | "id": "ISA09", 124 | "type": "element", 125 | "name": "Interchange Date", 126 | "req": "M", 127 | "data_type": "DT", 128 | "data_type_ids": null, 129 | "length": { 130 | "min": 6, 131 | "max": 6 132 | }, 133 | "notes": "Date of the interchange" 134 | }, 135 | { 136 | "id": "ISA10", 137 | "type": "element", 138 | "name": "Interchange Time", 139 | "req": "M", 140 | "data_type": "TM", 141 | "data_type_ids": null, 142 | "length": { 143 | "min": 4, 144 | "max": 4 145 | }, 146 | "notes": "Time of the interchange" 147 | }, 148 | { 149 | "id": "ISA11", 150 | "type": "element", 151 | "name": "Interchange Control Standards Identifier", 152 | "req": "M", 153 | "data_type": "ID", 154 | "data_type_ids": null, 155 | "length": { 156 | "min": 1, 157 | "max": 1 158 | }, 159 | "notes": "Code to identify the agency responsible for the control standard used by the message that is enclosed by the interchange header and trailer" 160 | }, 161 | { 162 | "id": "ISA12", 163 | "type": "element", 164 | "name": "Interchange Control Version Number", 165 | "req": "M", 166 | "data_type": "ID", 167 | "data_type_ids": { 168 | "U": "(default)" 169 | }, 170 | "length": { 171 | "min": 5, 172 | "max": 5 173 | }, 174 | "notes": "This version number covers the interchange control segments" 175 | }, 176 | { 177 | "id": "ISA13", 178 | "type": "element", 179 | "name": "Interchange Control Number", 180 | "req": "M", 181 | "data_type": "N0", 182 | "data_type_ids": null, 183 | "length": { 184 | "min": 9, 185 | "max": 9 186 | }, 187 | "notes": "A control number assigned by the interchange sender" 188 | }, 189 | { 190 | "id": "ISA14", 191 | "type": "element", 192 | "name": "Acknowledgment Requested", 193 | "req": "M", 194 | "data_type": "ID", 195 | "data_type_ids": { 196 | "0": "Requested" 197 | }, 198 | "length": { 199 | "min": 1, 200 | "max": 1 201 | }, 202 | "notes": "Code sent by the sender to request an interchange acknowledgment (TA1)" 203 | }, 204 | { 205 | "id": "ISA15", 206 | "type": "element", 207 | "name": "Usage Indicator", 208 | "req": "M", 209 | "data_type": "ID", 210 | "data_type_ids": { 211 | "T": "Test", 212 | "P": "Production", 213 | "I": "Information" 214 | }, 215 | "length": { 216 | "min": 1, 217 | "max": 1 218 | }, 219 | "notes": "Code to indicate whether data enclosed by this interchange envelope is test, production or information" 220 | }, 221 | { 222 | "id": "ISA16", 223 | "type": "element", 224 | "name": "Component Element Separator", 225 | "req": "M", 226 | "data_type": "", 227 | "data_type_ids": { 228 | "T": "Test", 229 | "P": "Production", 230 | "I": "Information" 231 | }, 232 | "length": { 233 | "min": 1, 234 | "max": 1 235 | }, 236 | "notes": "Type is not applicable; the component element separator is a delimiter and not a data element; this field provides the delimiter used to separate component data elements within a composite data structure; this value must be different than the data element separator and the segment terminator" 237 | } 238 | ] 239 | }, 240 | { 241 | "id": "GS", 242 | "type": "segment", 243 | "name": "Functional Group Header", 244 | "req": "M", 245 | "max_uses": 1, 246 | "notes": "", 247 | "elements": [ 248 | { 249 | "id": "GS01", 250 | "type": "element", 251 | "name": "Functional Identifier Code", 252 | "req": "M", 253 | "data_type": "ID", 254 | "data_type_ids": { 255 | "IN": "Invoice" 256 | }, 257 | "length": { 258 | "min": 2, 259 | "max": 2 260 | }, 261 | "notes": "Code identifying a group of application related transaction sets" 262 | }, 263 | { 264 | "id": "GS02", 265 | "type": "element", 266 | "name": "Application Sender's Code", 267 | "req": "M", 268 | "data_type": "AN", 269 | "data_type_ids": null, 270 | "length": { 271 | "min": 2, 272 | "max": 15 273 | }, 274 | "notes": "Code identifying party sending transmission; codes agreed to by trading partners" 275 | }, 276 | { 277 | "id": "GS03", 278 | "type": "element", 279 | "name": "Application Receiver's Code", 280 | "req": "M", 281 | "data_type": "AN", 282 | "data_type_ids": null, 283 | "length": { 284 | "min": 2, 285 | "max": 15 286 | }, 287 | "notes": "Code identifying party receiving transmission. Codes agreed to by trading partners" 288 | }, 289 | { 290 | "id": "GS04", 291 | "type": "element", 292 | "name": "Date", 293 | "req": "M", 294 | "data_type": "DT", 295 | "data_type_ids": null, 296 | "length": { 297 | "min": 8, 298 | "max": 8 299 | }, 300 | "notes": "Date expressed as CCYYMMDD" 301 | }, 302 | { 303 | "id": "GS05", 304 | "type": "element", 305 | "name": "Time", 306 | "req": "M", 307 | "data_type": "TM", 308 | "data_type_ids": null, 309 | "length": { 310 | "min": 4, 311 | "max": 8 312 | }, 313 | "notes": "Time expressed in 24-hour clock time as follows: HHMM, or HHMMSS, or HHMMSSD, or HHMMSSDD" 314 | }, 315 | { 316 | "id": "GS06", 317 | "type": "element", 318 | "name": "Group Control Number", 319 | "req": "M", 320 | "data_type": "N0", 321 | "data_type_ids": null, 322 | "length": { 323 | "min": 1, 324 | "max": 9 325 | }, 326 | "notes": "Assigned number originated and maintained by the sender" 327 | }, 328 | { 329 | "id": "GS07", 330 | "type": "element", 331 | "name": "Responsible Agency Code", 332 | "req": "M", 333 | "data_type": "ID", 334 | "data_type_ids": { 335 | "X": "", 336 | "T": "" 337 | }, 338 | "length": { 339 | "min": 1, 340 | "max": 2 341 | }, 342 | "notes": "Code used in conjunction with Data Element 480 to identify the issuer of the standard" 343 | }, 344 | { 345 | "id": "GS08", 346 | "type": "element", 347 | "name": "Version / Release / Industry Identifier Code", 348 | "req": "M", 349 | "data_type": "AN", 350 | "data_type_ids": null, 351 | "length": { 352 | "min": 1, 353 | "max": 12 354 | }, 355 | "notes": "Code indicating the version, release, subrelease, and industry identifier of the EDI standard being used, including the GS and GE segments; if code in DE455 in GS segment is X, then in DE 480 positions 1-3 are the version number; positions 4-6 are the release and subrelease, level of the version; and positions 7-12 are the industry or trade association identifiers (optionally assigned by user); if code in DE455 in GS segment is T, then other formats are allowed" 356 | } 357 | ] 358 | }, 359 | { 360 | "id": "ST", 361 | "type": "segment", 362 | "name": "Transaction Set Header", 363 | "req": "M", 364 | "max_uses": 1, 365 | "notes": "To indicate the start of a transaction set and to assign a control number", 366 | "elements": [ 367 | { 368 | "id": "ST01", 369 | "type": "element", 370 | "name": "Transaction Set Identifier Code", 371 | "req": "M", 372 | "data_type": "ID", 373 | "data_type_ids": { 374 | "850": "Purchase Order" 375 | }, 376 | "length": { 377 | "min": 3, 378 | "max": 3 379 | }, 380 | "notes": "Code identifying a Transaction Set" 381 | }, 382 | { 383 | "id": "ST02", 384 | "type": "element", 385 | "name": "Transaction Set Control Number", 386 | "req": "M", 387 | "data_type": "AN", 388 | "data_type_ids": null, 389 | "length": { 390 | "min": 4, 391 | "max": 9 392 | }, 393 | "notes": "Identifying control number that must be unique within the transaction set functional group assigned by the originator for a transaction set" 394 | } 395 | ] 396 | }, 397 | { 398 | "id": "BEG", 399 | "type": "segment", 400 | "name": "Beginning Segment for Purchase Order", 401 | "req": "M", 402 | "max_uses": 1, 403 | "notes": "", 404 | "elements": [ 405 | { 406 | "id": "BEG01", 407 | "type": "element", 408 | "name": "Transaction Set Purpose Code", 409 | "req": "M", 410 | "data_type": "ID", 411 | "data_type_ids": { 412 | "00": "Original" 413 | }, 414 | "length": { 415 | "min": 2, 416 | "max": 2 417 | }, 418 | "notes": "Code identifying purpose of transaction set" 419 | }, 420 | { 421 | "id": "BEG02", 422 | "type": "element", 423 | "name": "Transaction Order Type Code", 424 | "req": "M", 425 | "data_type": "ID", 426 | "data_type_ids": { 427 | "SA": "Stand-alone Order" 428 | }, 429 | "length": { 430 | "min": 2, 431 | "max": 2 432 | }, 433 | "notes": "Code identifying the type of Purchase Order" 434 | }, 435 | { 436 | "id": "BEG03", 437 | "type": "element", 438 | "name": "Purchase Order Number", 439 | "req": "M", 440 | "data_type": "AN", 441 | "data_type_ids": null, 442 | "length": { 443 | "min": 1, 444 | "max": 22 445 | }, 446 | "notes": "Identifying numer for Purchase Order assigned by the orderer/purchaser" 447 | }, 448 | { 449 | "id": "BEG04", 450 | "type": "element", 451 | "name": "Release Number", 452 | "req": "O", 453 | "data_type": "AN", 454 | "data_type_ids": null, 455 | "length": { 456 | "min": 1, 457 | "max": 30 458 | }, 459 | "notes": "Number identifying a release against a Purchase Order previously placed by the parties involved in the transaction" 460 | }, 461 | { 462 | "id": "BEG05", 463 | "type": "element", 464 | "name": "Date", 465 | "req": "M", 466 | "data_type": "DT", 467 | "data_type_ids": null, 468 | "length": { 469 | "min": 8, 470 | "max": 8 471 | }, 472 | "notes": "Date expressed as CCYYMMDD where CC represents the first two digits of the calendar year" 473 | } 474 | ] 475 | }, 476 | { 477 | "id": "REF", 478 | "type": "segment", 479 | "name": "Reference Information", 480 | "req": "O", 481 | "max_uses": 1, 482 | "notes": "To specify identifying information", 483 | "elements": [ 484 | { 485 | "id": "REF01", 486 | "type": "element", 487 | "name": "Reference Identification Qualifier", 488 | "req": "M", 489 | "data_type": "ID", 490 | "data_type_ids": { 491 | "DP": "Department Number" 492 | }, 493 | "length": { 494 | "min": 2, 495 | "max": 3 496 | }, 497 | "notes": "Code identifying the Reference Identification" 498 | }, 499 | { 500 | "id": "REF02", 501 | "type": "element", 502 | "name": "Reference Identification", 503 | "req": "O", 504 | "data_type": "AN", 505 | "data_type_ids": null, 506 | "length": { 507 | "min": 1, 508 | "max": 80 509 | }, 510 | "notes": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier" 511 | } 512 | ] 513 | }, 514 | { 515 | "id": "DTM", 516 | "type": "segment", 517 | "name": "Date/Time Reference", 518 | "req": "O", 519 | "max_uses": 10, 520 | "notes": "To specify pertinent dates and times", 521 | "elements": [ 522 | { 523 | "id": "DTM01", 524 | "type": "element", 525 | "name": "Date/Time Qualifier", 526 | "req": "M", 527 | "data_type": "ID", 528 | "data_type_ids": { 529 | "001": "Cancel After", 530 | "011": "Shipped" 531 | }, 532 | "length": { 533 | "min": 3, 534 | "max": 3 535 | }, 536 | "notes": "Code to identify the type of information in the Authorization Information" 537 | }, 538 | { 539 | "id": "DTM02", 540 | "type": "element", 541 | "name": "Date", 542 | "req": "O", 543 | "data_type": "DT", 544 | "data_type_ids": { 545 | "001": "Cancel After", 546 | "011": "Shipped" 547 | }, 548 | "length": { 549 | "min": 3, 550 | "max": 3 551 | }, 552 | "notes": "Date expressed as CCYYMMDD where CC represents the first two digits of the calendar year" 553 | } 554 | ] 555 | }, 556 | { 557 | "id": "L_N1", 558 | "type": "loop", 559 | "name": "Name Loop", 560 | "req": "O", 561 | "repeat": 200, 562 | "segments": [ 563 | { 564 | "id": "N1", 565 | "type": "segment", 566 | "name": "Party Identification", 567 | "req": "M", 568 | "max_uses": 1, 569 | "notes": "To identify a party by type of organization, name, and code", 570 | "elements": [ 571 | { 572 | "id": "N101", 573 | "name": "Entity Identifier Code", 574 | "type": "element", 575 | "req": "M", 576 | "data_type": "ID", 577 | "data_type_ids": { 578 | "SU": "Supplier/Manufacturer", 579 | "ST": "Ship To" 580 | }, 581 | "length": { 582 | "min": 2, 583 | "max": 3 584 | }, 585 | "notes": "Code identifying an organizational entity, a physical location, property or an individual" 586 | }, 587 | { 588 | "id": "N102", 589 | "name": "Name", 590 | "type": "element", 591 | "req": "O", 592 | "data_type": "AN", 593 | "data_type_ids": null, 594 | "length": { 595 | "min": 1, 596 | "max": 60 597 | }, 598 | "notes": "Free-form name" 599 | }, 600 | { 601 | "id": "N103", 602 | "name": "Identification Code Qualifier", 603 | "type": "element", 604 | "req": "O", 605 | "data_type": "ID", 606 | "data_type_ids": { 607 | "92": "Assigned by Buyer or Buyer's Agent" 608 | }, 609 | "length": { 610 | "min": 1, 611 | "max": 2 612 | }, 613 | "notes": "Code designating the system/method of code structure used for Identification Code (67)" 614 | }, 615 | { 616 | "id": "N104", 617 | "name": "Identification Code", 618 | "type": "element", 619 | "req": "O", 620 | "data_type": "AN", 621 | "data_type_ids": null, 622 | "length": { 623 | "min": 2, 624 | "max": 80 625 | }, 626 | "notes": "Code identifying a party or other code" 627 | } 628 | ] 629 | } 630 | ] 631 | }, 632 | { 633 | "id": "L_PO1", 634 | "type": "loop", 635 | "name": "PO1 Loop", 636 | "req": "O", 637 | "repeat": 200, 638 | "segments": [ 639 | { 640 | "id": "PO1", 641 | "type": "segment", 642 | "name": "Baseline Item Data", 643 | "req": "M", 644 | "max_uses": 1, 645 | "notes": "To specify basic and most frequently used line item data", 646 | "elements": [ 647 | { 648 | "id": "PO101", 649 | "name": "Assigned Identification", 650 | "type": "element", 651 | "req": "O", 652 | "data_type": "AN", 653 | "data_type_ids": null, 654 | "length": { 655 | "min": 1, 656 | "max": 20 657 | }, 658 | "notes": "Alphanumeric characters assigned for differentiation within a transaction set" 659 | }, 660 | { 661 | "id": "PO102", 662 | "name": "Quantity", 663 | "type": "element", 664 | "req": "O", 665 | "data_type": "R", 666 | "data_type_ids": null, 667 | "length": { 668 | "min": 1, 669 | "max": 15 670 | }, 671 | "notes": "Numeric value of quantity" 672 | }, 673 | { 674 | "id": "PO103", 675 | "name": "Unit or Basis for Measurement Code", 676 | "type": "element", 677 | "req": "O", 678 | "data_type": "ID", 679 | "data_type_ids": { 680 | "EA": "Each" 681 | }, 682 | "length": { 683 | "min": 2, 684 | "max": 2 685 | }, 686 | "notes": "Code specifying the units in which a value is being expressed, or manner in which a measurement has been taken" 687 | }, 688 | { 689 | "id": "PO104", 690 | "name": "Unit Price", 691 | "type": "element", 692 | "req": "O", 693 | "data_type": "R", 694 | "data_type_ids": null, 695 | "length": { 696 | "min": 1, 697 | "max": 17 698 | }, 699 | "notes": "Price per unit of product, service, commodity, etc." 700 | }, 701 | { 702 | "id": "PO105", 703 | "name": "Basis of Unit Price Code", 704 | "type": "element", 705 | "req": "O", 706 | "data_type": "ID", 707 | "data_type_ids": { 708 | "CA": "Catalog" 709 | }, 710 | "length": { 711 | "min": 2, 712 | "max": 2 713 | }, 714 | "notes": "Code identifying the type of unit price for an item" 715 | }, 716 | { 717 | "id": "PO106", 718 | "name": "Product/Service ID Qualifier", 719 | "type": "element", 720 | "req": "O", 721 | "data_type": "ID", 722 | "data_type_ids": { 723 | "UP": "GTIN-12" 724 | }, 725 | "length": { 726 | "min": 2, 727 | "max": 2 728 | }, 729 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service" 730 | }, 731 | { 732 | "id": "PO107", 733 | "name": "Product/Service ID", 734 | "type": "element", 735 | "req": "O", 736 | "data_type": "AN", 737 | "data_type_ids": null, 738 | "length": { 739 | "min": 1, 740 | "max": 80 741 | }, 742 | "notes": "Identifying number for a product or service" 743 | }, 744 | { 745 | "id": "PO108", 746 | "name": "Product/Service ID Qualifier", 747 | "type": "element", 748 | "req": "O", 749 | "data_type": "ID", 750 | "data_type_ids": { 751 | "SK": "Stock Keeping Unit (SKU)" 752 | }, 753 | "length": { 754 | "min": 2, 755 | "max": 2 756 | }, 757 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 758 | }, 759 | { 760 | "id": "PO109", 761 | "name": "Product/Service ID", 762 | "type": "element", 763 | "req": "O", 764 | "data_type": "AN", 765 | "data_type_ids": null, 766 | "length": { 767 | "min": 1, 768 | "max": 80 769 | }, 770 | "notes": "Identifying number for a product or service" 771 | }, 772 | { 773 | "id": "PO110", 774 | "name": "Product/Service ID Qualifier", 775 | "type": "element", 776 | "req": "O", 777 | "data_type": "ID", 778 | "data_type_ids": { 779 | "IZ": "Buyer's Size Code" 780 | }, 781 | "length": { 782 | "min": 2, 783 | "max": 2 784 | }, 785 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 786 | }, 787 | { 788 | "id": "PO111", 789 | "name": "Product/Service ID", 790 | "type": "element", 791 | "req": "O", 792 | "data_type": "AN", 793 | "data_type_ids": null, 794 | "length": { 795 | "min": 1, 796 | "max": 80 797 | }, 798 | "notes": "Identifying number for a product or service" 799 | }, 800 | { 801 | "id": "PO112", 802 | "name": "Product/Service ID Qualifier", 803 | "type": "element", 804 | "req": "O", 805 | "data_type": "ID", 806 | "data_type_ids": { 807 | "CL": "Color" 808 | }, 809 | "length": { 810 | "min": 2, 811 | "max": 2 812 | }, 813 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 814 | }, 815 | { 816 | "id": "PO113", 817 | "name": "Product/Service ID", 818 | "type": "element", 819 | "req": "O", 820 | "data_type": "AN", 821 | "data_type_ids": null, 822 | "length": { 823 | "min": 1, 824 | "max": 80 825 | }, 826 | "notes": "Identifying number for a product or service" 827 | }, 828 | { 829 | "id": "PO114", 830 | "name": "Product/Service ID Qualifier", 831 | "type": "element", 832 | "req": "O", 833 | "data_type": "ID", 834 | "data_type_ids": { 835 | "ST": "Style Number" 836 | }, 837 | "length": { 838 | "min": 2, 839 | "max": 2 840 | }, 841 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 842 | }, 843 | { 844 | "id": "PO115", 845 | "name": "Product/Service ID", 846 | "type": "element", 847 | "req": "O", 848 | "data_type": "AN", 849 | "data_type_ids": null, 850 | "length": { 851 | "min": 1, 852 | "max": 80 853 | }, 854 | "notes": "Identifying number for a product or service" 855 | }, 856 | { 857 | "id": "PO116", 858 | "name": "Product/Service ID Qualifier", 859 | "type": "element", 860 | "req": "O", 861 | "data_type": "ID", 862 | "data_type_ids": { 863 | "BC": "Supplier Brand Code" 864 | }, 865 | "length": { 866 | "min": 2, 867 | "max": 2 868 | }, 869 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 870 | }, 871 | { 872 | "id": "PO117", 873 | "name": "Product/Service ID", 874 | "type": "element", 875 | "req": "O", 876 | "data_type": "AN", 877 | "data_type_ids": null, 878 | "length": { 879 | "min": 1, 880 | "max": 80 881 | }, 882 | "notes": "Identifying number for a product or service" 883 | }, 884 | { 885 | "id": "PO118", 886 | "name": "Product/Service ID Qualifier", 887 | "type": "element", 888 | "req": "O", 889 | "data_type": "ID", 890 | "data_type_ids": { 891 | "BL": "Brand/Label" 892 | }, 893 | "length": { 894 | "min": 2, 895 | "max": 2 896 | }, 897 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 898 | }, 899 | { 900 | "id": "PO119", 901 | "name": "Product/Service ID", 902 | "type": "element", 903 | "req": "O", 904 | "data_type": "AN", 905 | "data_type_ids": null, 906 | "length": { 907 | "min": 1, 908 | "max": 80 909 | }, 910 | "notes": "Identifying number for a product or service" 911 | }, 912 | { 913 | "id": "PO120", 914 | "name": "Product/Service ID Qualifier", 915 | "type": "element", 916 | "req": "O", 917 | "data_type": "ID", 918 | "data_type_ids": { 919 | "IZ": "Buyer's Size Code" 920 | }, 921 | "length": { 922 | "min": 2, 923 | "max": 2 924 | }, 925 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 926 | }, 927 | { 928 | "id": "PO121", 929 | "name": "Product/Service ID", 930 | "type": "element", 931 | "req": "O", 932 | "data_type": "AN", 933 | "data_type_ids": null, 934 | "length": { 935 | "min": 1, 936 | "max": 80 937 | }, 938 | "notes": "Identifying number for a product or service" 939 | }, 940 | { 941 | "id": "PO122", 942 | "name": "Product/Service ID Qualifier", 943 | "type": "element", 944 | "req": "O", 945 | "data_type": "ID", 946 | "data_type_ids": { 947 | "IZ": "Buyer's Size Code" 948 | }, 949 | "length": { 950 | "min": 2, 951 | "max": 2 952 | }, 953 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 954 | }, 955 | { 956 | "id": "PO123", 957 | "name": "Product/Service ID", 958 | "type": "element", 959 | "req": "O", 960 | "data_type": "AN", 961 | "data_type_ids": null, 962 | "length": { 963 | "min": 1, 964 | "max": 80 965 | }, 966 | "notes": "Identifying number for a product or service" 967 | }, 968 | { 969 | "id": "PO124", 970 | "name": "Product/Service ID Qualifier", 971 | "type": "element", 972 | "req": "O", 973 | "data_type": "ID", 974 | "data_type_ids": { 975 | "IZ": "Buyer's Size Code" 976 | }, 977 | "length": { 978 | "min": 2, 979 | "max": 2 980 | }, 981 | "notes": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)" 982 | }, 983 | { 984 | "id": "PO125", 985 | "name": "Product/Service ID", 986 | "type": "element", 987 | "req": "O", 988 | "data_type": "AN", 989 | "data_type_ids": null, 990 | "length": { 991 | "min": 1, 992 | "max": 80 993 | }, 994 | "notes": "Identifying number for a product or service" 995 | } 996 | ] 997 | }, 998 | { 999 | "id": "L_CTP", 1000 | "type": "loop", 1001 | "name": "CTP Loop", 1002 | "req": "O", 1003 | "repeat": 200, 1004 | "segments": [ 1005 | { 1006 | "id": "CTP", 1007 | "type": "segment", 1008 | "name": "Pricing Information", 1009 | "req": "M", 1010 | "max_uses": 1, 1011 | "notes": "To specify pricing information", 1012 | "elements": [ 1013 | { 1014 | "id": "CTP01", 1015 | "name": "Class of Trade Code", 1016 | "type": "element", 1017 | "req": "O", 1018 | "data_type": "ID", 1019 | "data_type_ids": { 1020 | "TR": "General Trade" 1021 | }, 1022 | "length": { 1023 | "min": 2, 1024 | "max": 2 1025 | }, 1026 | "notes": "Code indicating class of trade" 1027 | }, 1028 | { 1029 | "id": "CTP02", 1030 | "name": "Price Identifier Code", 1031 | "type": "element", 1032 | "req": "O", 1033 | "data_type": "ID", 1034 | "data_type_ids": { 1035 | "RTL": "Retail" 1036 | }, 1037 | "length": { 1038 | "min": 3, 1039 | "max": 3 1040 | }, 1041 | "notes": "Code identifying pricing specification" 1042 | }, 1043 | { 1044 | "id": "CTP03", 1045 | "name": "Unit Price", 1046 | "type": "element", 1047 | "req": "O", 1048 | "data_type": "R", 1049 | "data_type_ids": null, 1050 | "length": { 1051 | "min": 1, 1052 | "max": 17 1053 | }, 1054 | "notes": "Price per unit of product, service, commodity, etc." 1055 | } 1056 | ] 1057 | } 1058 | ] 1059 | }, 1060 | { 1061 | "id": "SDQ", 1062 | "type": "segment", 1063 | "name": "Destination Quantity", 1064 | "req": "O", 1065 | "max_uses": 200, 1066 | "notes": "To specify destination and quantity detail", 1067 | "elements": [ 1068 | { 1069 | "id": "SDQ01", 1070 | "type": "element", 1071 | "name": "Unit or Basis for Measurement Code", 1072 | "req": "M", 1073 | "data_type": "ID", 1074 | "data_type_ids": { 1075 | "UN": "Unit" 1076 | }, 1077 | "length": { 1078 | "min": 2, 1079 | "max": 2 1080 | }, 1081 | "notes": "Code specifying the units in which a value is being expressed, or manner in which a measurement has been taken" 1082 | }, 1083 | { 1084 | "id": "SDQ02", 1085 | "type": "element", 1086 | "name": "Identification Code Qualifier", 1087 | "req": "O", 1088 | "data_type": "ID", 1089 | "data_type_ids": { 1090 | "92": "Assigned by Buyer or Buyer's Agent" 1091 | }, 1092 | "length": { 1093 | "min": 1, 1094 | "max": 2 1095 | }, 1096 | "notes": "Code specifying the system/method of code structure used for Identification Code (67)" 1097 | }, 1098 | { 1099 | "id": "SDQ03", 1100 | "type": "element", 1101 | "name": "Identification Code", 1102 | "req": "M", 1103 | "data_type": "AN", 1104 | "data_type_ids": null, 1105 | "length": { 1106 | "min": 2, 1107 | "max": 80 1108 | }, 1109 | "notes": "Code identifying a party or other code" 1110 | }, 1111 | { 1112 | "id": "SDQ04", 1113 | "type": "element", 1114 | "name": "Quantity", 1115 | "req": "M", 1116 | "data_type": "R", 1117 | "data_type_ids": null, 1118 | "length": { 1119 | "min": 1, 1120 | "max": 15 1121 | }, 1122 | "notes": "Numeric value of quantity" 1123 | }, 1124 | { 1125 | "id": "SDQ05", 1126 | "type": "element", 1127 | "name": "Identification Code", 1128 | "req": "O", 1129 | "data_type": "AN", 1130 | "data_type_ids": null, 1131 | "length": { 1132 | "min": 2, 1133 | "max": 80 1134 | }, 1135 | "notes": "Code identifying a party or other code" 1136 | }, 1137 | { 1138 | "id": "SDQ06", 1139 | "type": "element", 1140 | "name": "Quantity", 1141 | "req": "O", 1142 | "data_type": "R", 1143 | "data_type_ids": null, 1144 | "length": { 1145 | "min": 1, 1146 | "max": 15 1147 | }, 1148 | "notes": "Numeric value of quantity" 1149 | }, 1150 | { 1151 | "id": "SDQ07", 1152 | "type": "element", 1153 | "name": "Identification Code", 1154 | "req": "O", 1155 | "data_type": "AN", 1156 | "data_type_ids": null, 1157 | "length": { 1158 | "min": 2, 1159 | "max": 80 1160 | }, 1161 | "notes": "Code identifying a party or other code" 1162 | }, 1163 | { 1164 | "id": "SDQ08", 1165 | "type": "element", 1166 | "name": "Quantity", 1167 | "req": "O", 1168 | "data_type": "R", 1169 | "data_type_ids": null, 1170 | "length": { 1171 | "min": 1, 1172 | "max": 15 1173 | }, 1174 | "notes": "Numeric value of quantity" 1175 | }, 1176 | { 1177 | "id": "SDQ09", 1178 | "type": "element", 1179 | "name": "Identification Code", 1180 | "req": "O", 1181 | "data_type": "AN", 1182 | "data_type_ids": null, 1183 | "length": { 1184 | "min": 2, 1185 | "max": 80 1186 | }, 1187 | "notes": "Code identifying a party or other code" 1188 | }, 1189 | { 1190 | "id": "SDQ10", 1191 | "type": "element", 1192 | "name": "Quantity", 1193 | "req": "O", 1194 | "data_type": "R", 1195 | "data_type_ids": null, 1196 | "length": { 1197 | "min": 1, 1198 | "max": 15 1199 | }, 1200 | "notes": "Numeric value of quantity" 1201 | }, 1202 | { 1203 | "id": "SDQ11", 1204 | "type": "element", 1205 | "name": "Identification Code", 1206 | "req": "O", 1207 | "data_type": "AN", 1208 | "data_type_ids": null, 1209 | "length": { 1210 | "min": 2, 1211 | "max": 80 1212 | }, 1213 | "notes": "Code identifying a party or other code" 1214 | }, 1215 | { 1216 | "id": "SDQ12", 1217 | "type": "element", 1218 | "name": "Quantity", 1219 | "req": "O", 1220 | "data_type": "R", 1221 | "data_type_ids": null, 1222 | "length": { 1223 | "min": 1, 1224 | "max": 15 1225 | }, 1226 | "notes": "Numeric value of quantity" 1227 | }, 1228 | { 1229 | "id": "SDQ13", 1230 | "type": "element", 1231 | "name": "Identification Code", 1232 | "req": "O", 1233 | "data_type": "AN", 1234 | "data_type_ids": null, 1235 | "length": { 1236 | "min": 2, 1237 | "max": 80 1238 | }, 1239 | "notes": "Code identifying a party or other code" 1240 | }, 1241 | { 1242 | "id": "SDQ14", 1243 | "type": "element", 1244 | "name": "Quantity", 1245 | "req": "O", 1246 | "data_type": "R", 1247 | "data_type_ids": null, 1248 | "length": { 1249 | "min": 1, 1250 | "max": 15 1251 | }, 1252 | "notes": "Numeric value of quantity" 1253 | }, 1254 | { 1255 | "id": "SDQ15", 1256 | "type": "element", 1257 | "name": "Identification Code", 1258 | "req": "O", 1259 | "data_type": "AN", 1260 | "data_type_ids": null, 1261 | "length": { 1262 | "min": 2, 1263 | "max": 80 1264 | }, 1265 | "notes": "Code identifying a party or other code" 1266 | }, 1267 | { 1268 | "id": "SDQ16", 1269 | "type": "element", 1270 | "name": "Quantity", 1271 | "req": "O", 1272 | "data_type": "R", 1273 | "data_type_ids": null, 1274 | "length": { 1275 | "min": 1, 1276 | "max": 15 1277 | }, 1278 | "notes": "Numeric value of quantity" 1279 | }, 1280 | { 1281 | "id": "SDQ17", 1282 | "type": "element", 1283 | "name": "Identification Code", 1284 | "req": "O", 1285 | "data_type": "AN", 1286 | "data_type_ids": null, 1287 | "length": { 1288 | "min": 2, 1289 | "max": 80 1290 | }, 1291 | "notes": "Code identifying a party or other code" 1292 | }, 1293 | { 1294 | "id": "SDQ18", 1295 | "type": "element", 1296 | "name": "Quantity", 1297 | "req": "O", 1298 | "data_type": "R", 1299 | "data_type_ids": null, 1300 | "length": { 1301 | "min": 1, 1302 | "max": 15 1303 | }, 1304 | "notes": "Numeric value of quantity" 1305 | }, 1306 | { 1307 | "id": "SDQ19", 1308 | "type": "element", 1309 | "name": "Identification Code", 1310 | "req": "O", 1311 | "data_type": "AN", 1312 | "data_type_ids": null, 1313 | "length": { 1314 | "min": 2, 1315 | "max": 80 1316 | }, 1317 | "notes": "Code identifying a party or other code" 1318 | }, 1319 | { 1320 | "id": "SDQ20", 1321 | "type": "element", 1322 | "name": "Quantity", 1323 | "req": "O", 1324 | "data_type": "R", 1325 | "data_type_ids": null, 1326 | "length": { 1327 | "min": 1, 1328 | "max": 15 1329 | }, 1330 | "notes": "Numeric value of quantity" 1331 | }, 1332 | { 1333 | "id": "SDQ21", 1334 | "type": "element", 1335 | "name": "Identification Code", 1336 | "req": "O", 1337 | "data_type": "AN", 1338 | "data_type_ids": null, 1339 | "length": { 1340 | "min": 2, 1341 | "max": 80 1342 | }, 1343 | "notes": "Code identifying a party or other code" 1344 | }, 1345 | { 1346 | "id": "SDQ22", 1347 | "type": "element", 1348 | "name": "Quantity", 1349 | "req": "O", 1350 | "data_type": "R", 1351 | "data_type_ids": null, 1352 | "length": { 1353 | "min": 1, 1354 | "max": 15 1355 | }, 1356 | "notes": "Numeric value of quantity" 1357 | }, 1358 | { 1359 | "id": "SDQ23", 1360 | "type": "element", 1361 | "name": "Location Identifier", 1362 | "req": "O", 1363 | "data_type": "AN", 1364 | "data_type_ids": null, 1365 | "length": { 1366 | "min": 1, 1367 | "max": 30 1368 | }, 1369 | "notes": "Code which identifies a specific location" 1370 | } 1371 | ] 1372 | } 1373 | 1374 | ] 1375 | }, 1376 | { 1377 | "id": "L_CTT", 1378 | "type": "loop", 1379 | "name": "Transaction Totals Loop", 1380 | "req": "O", 1381 | "repeat": 200, 1382 | "segments": [ 1383 | { 1384 | "id": "CTT", 1385 | "type": "segment", 1386 | "name": "Transaction Totals", 1387 | "req": "M", 1388 | "max_uses": 1, 1389 | "notes": "To transmit a hash total for a specific element in the transaction set", 1390 | "elements": [ 1391 | { 1392 | "id": "CTT01", 1393 | "name": "Number of Line Items", 1394 | "type": "element", 1395 | "req": "M", 1396 | "data_type": "N0", 1397 | "data_type_ids": null, 1398 | "length": { 1399 | "min": 1, 1400 | "max": 6 1401 | }, 1402 | "notes": "Total number of line items in the transaction set" 1403 | }, 1404 | { 1405 | "id": "CTT02", 1406 | "name": "Hash Total", 1407 | "type": "element", 1408 | "req": "O", 1409 | "data_type": "R", 1410 | "data_type_ids": null, 1411 | "length": { 1412 | "min": 1, 1413 | "max": 10 1414 | }, 1415 | "notes": "Sum of values of the specified data element. All values in the data element will be summed without regard to decimal points (explicit or implicit) or signs. Truncation will occur on the left most digits if the sum is greater than the maximum size of the hash total of the data element. Example: -.0018 First occurrence of value being hashed. .18 Second occurrence of value being hashed. 1.8 Third occurrence of value being hashed. 18.01 Fourth occurrence of value being hashed. 18E2 Fifth occurrence of value being hashed. -------- 1873 Hash Total" 1416 | } 1417 | ] 1418 | } 1419 | ] 1420 | }, 1421 | { 1422 | "id": "SE", 1423 | "type": "segment", 1424 | "name": "Transaction Set Trailer", 1425 | "req": "M", 1426 | "max_uses": 1, 1427 | "notes": "To indicate the end of the transaction set and provide the count of the transmitted segments (including the beginning (ST) and ending (SE) segments)", 1428 | "elements": [ 1429 | { 1430 | "id": "SE01", 1431 | "type": "element", 1432 | "name": "Number of Included Segments", 1433 | "req": "M", 1434 | "data_type": "N0", 1435 | "data_type_ids": null, 1436 | "length": { 1437 | "min": 1, 1438 | "max": 10 1439 | }, 1440 | "notes": "Total number of segments included in a transaction set including ST and SE segments" 1441 | }, 1442 | { 1443 | "id": "SE02", 1444 | "type": "element", 1445 | "name": "Transaction Set Control Number", 1446 | "req": "M", 1447 | "data_type": "AN", 1448 | "data_type_ids": null, 1449 | "length": { 1450 | "min": 4, 1451 | "max": 9 1452 | }, 1453 | "notes": "Identifying control number that must be unique within the transaction set functional group assigned by the originator for a transaction set" 1454 | } 1455 | ] 1456 | }, 1457 | { 1458 | "id": "GE", 1459 | "type": "segment", 1460 | "name": "Functional Group Trailer", 1461 | "req": "M", 1462 | "max_uses": 1, 1463 | "notes": "To indicate the end of a functional group and to provide control information", 1464 | "elements": [ 1465 | { 1466 | "id": "GE01", 1467 | "type": "element", 1468 | "name": "Number of Transaction Sets Included", 1469 | "req": "M", 1470 | "data_type": "N0", 1471 | "data_type_ids": null, 1472 | "length": { 1473 | "min": 1, 1474 | "max": 6 1475 | }, 1476 | "notes": "Total number of transaction sets included in the functional group or interchange (transmission) group terminated by the trailer containing this data element" 1477 | }, 1478 | { 1479 | "id": "GE02", 1480 | "type": "element", 1481 | "name": "Group Control Number", 1482 | "req": "M", 1483 | "data_type": "N0", 1484 | "data_type_ids": null, 1485 | "length": { 1486 | "min": 1, 1487 | "max": 9 1488 | }, 1489 | "notes": "Assigned number originated and maintained by the sender" 1490 | } 1491 | ] 1492 | }, 1493 | { 1494 | "id": "IEA", 1495 | "type": "segment", 1496 | "name": "Interchange Control Trailer", 1497 | "req": "M", 1498 | "max_uses": 1, 1499 | "notes": "To define the end of an interchange of zero or more functional groups and interchange-related control segments", 1500 | "elements": [ 1501 | { 1502 | "id": "IEA01", 1503 | "type": "element", 1504 | "name": "Number of Included Functional Groups", 1505 | "req": "M", 1506 | "data_type": "N0", 1507 | "data_type_ids": null, 1508 | "length": { 1509 | "min": 1, 1510 | "max": 5 1511 | }, 1512 | "notes": "A count of the number of functional groups included in an interchange" 1513 | }, 1514 | { 1515 | "id": "IEA02", 1516 | "type": "element", 1517 | "name": "Interchange Control Number", 1518 | "req": "M", 1519 | "data_type": "N0", 1520 | "data_type_ids": null, 1521 | "length": { 1522 | "min": 9, 1523 | "max": 9 1524 | }, 1525 | "notes": "A control number assigned by the interchange sender" 1526 | } 1527 | ] 1528 | } 1529 | ] -------------------------------------------------------------------------------- /pythonedi/formats/ST.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "id": "ST", "type": "segment", 3 | "name": "Transaction Set Header", 4 | "req": "M", 5 | "max_uses": 1, 6 | "notes": "", 7 | "elements": [ 8 | { "id": "ST01", "type": "element", 9 | "name": "Transaction Set Identifier Code", 10 | "req": "M", 11 | "data_type": "ID", 12 | "data_type_ids": {"810": "Invoice"}, 13 | "length": {"min": 3, "max": 3}, 14 | "notes": "" 15 | }, 16 | { "id": "ST02", "type": "element", 17 | "name": "Transaction Set Control Number", 18 | "req": "M", 19 | "data_type": "AN", 20 | "data_type_ids": null, 21 | "length": {"min": 4, "max": 9}, 22 | "notes": "This should be a unique control # for each transaction set functional group" 23 | } 24 | ] 25 | } 26 | ] -------------------------------------------------------------------------------- /pythonedi/hint.py: -------------------------------------------------------------------------------- 1 | """ 2 | Explainer produces a human-readable version of the expectation for the 3 | formatted data. 4 | """ 5 | 6 | from colorama import Fore, Style, init 7 | 8 | # Initialize colorama wrapper 9 | init() 10 | 11 | SEGMENT_TEMPLATE = """ 12 | {HEADER_COLOR}[{id}] {name}{END_COLOR} 13 | * Required? {VALUE_COLOR}{req}{END_COLOR} 14 | * Max uses: {VALUE_COLOR}{max_uses}{END_COLOR} 15 | * Syntax rules: {VALUE_COLOR}{syntax_rules}{END_COLOR} 16 | * Notes: {VALUE_COLOR}{notes}{END_COLOR} 17 | """ 18 | 19 | ELEMENT_TEMPLATE = """ 20 | {HEADER_COLOR}{index}{name}{END_COLOR} 21 | * Required? {VALUE_COLOR}{req}{END_COLOR} 22 | * Data type: {VALUE_COLOR}{data_type}{END_COLOR} 23 | * Data type options: {VALUE_COLOR}{data_type_ids}{END_COLOR} 24 | * Length (min: {VALUE_COLOR}{length[min]}{END_COLOR}, max: {VALUE_COLOR}{length[max]}{END_COLOR}) 25 | * Notes: {VALUE_COLOR}{notes}{END_COLOR} 26 | """ 27 | 28 | def explain(structure): 29 | # Decide which type of structure this is 30 | if type(structure) is list: 31 | for segment in structure: 32 | explain_segment(segment) 33 | elif type(structure) is dict and "type" in structure: 34 | if structure["type"] == "segment": 35 | explain_segment(structure) 36 | elif structure["type"] == "element": 37 | explain_element("", structure) 38 | elif structure["type"] == "loop": 39 | explain_loop(structure) 40 | else: 41 | raise TypeError("Expected either a loop, a segment, an element, or a list of segments.") 42 | 43 | 44 | def explain_segment(segment): 45 | print(Fore.CYAN + "\n-- [Segment] --" + Fore.RESET) 46 | if segment["type"] == "segment": 47 | # Parse syntax rules into human-readable format 48 | syntax_rules_list = [] 49 | if "syntax" in segment: 50 | for rule in segment["syntax"]: 51 | # Troubleshooting 52 | if "rule" not in rule or "criteria" not in rule: 53 | raise ValueError("Invalid rule definition in segment {}: {}".format(segment["id"], rule)) 54 | if len(rule["criteria"]) < 2: 55 | raise ValueError("Invalid criteria for syntax rule {} in segment {}: Expected two or more values".format(rule["rule"], segment["id"])) 56 | 57 | if rule["rule"] == "ATLEASTONE": 58 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"]]) 59 | syntax_rules_list.append("At least one of {} is required".format(required_elements)) 60 | elif rule["rule"] == "ALLORNONE": 61 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"]]) 62 | syntax_rules_list.append("If one of {} is present, the rest are required".format(required_elements)) 63 | elif rule["rule"] == "IFATLEASTONE": 64 | first_element = "{}{:02d}".format(segment["id"], rule["criteria"][0]) 65 | required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"][1:]]) 66 | syntax_rules_list.append("If {} is present, at least one of {} are required".format(first_element, required_elements)) 67 | 68 | # Print template 69 | print(SEGMENT_TEMPLATE.format( 70 | syntax_rules="; ".join(syntax_rules_list), 71 | HEADER_COLOR=Fore.CYAN+Style.BRIGHT, 72 | VALUE_COLOR=Fore.YELLOW+Style.BRIGHT, 73 | END_COLOR=Fore.RESET+Style.RESET_ALL, 74 | **segment)) 75 | 76 | # Print elements section 77 | print(Fore.CYAN + " -- [Elements] --" + Fore.RESET) 78 | for i, element in enumerate(segment["elements"]): 79 | explain_element("{}{:02d}: ".format(segment["id"], i+1), element) 80 | 81 | # End segment 82 | print(Fore.CYAN + "--------------------" + Fore.RESET) 83 | 84 | def explain_element(index, element): 85 | # Print template 86 | print(ELEMENT_TEMPLATE.format( 87 | index=index, 88 | HEADER_COLOR=Fore.GREEN, 89 | VALUE_COLOR=Fore.YELLOW+Style.BRIGHT, 90 | END_COLOR=Fore.RESET+Style.RESET_ALL, 91 | **element)) 92 | 93 | def explain_loop(loop): 94 | raise NotImplementedError() -------------------------------------------------------------------------------- /pythonedi/supported_formats.py: -------------------------------------------------------------------------------- 1 | """ 2 | Imports and manages EDI format definitions 3 | """ 4 | 5 | import os 6 | import json 7 | 8 | def load_supported_formats(formats_path): 9 | supported_formats = {} 10 | for filename in os.listdir(formats_path): 11 | if filename.endswith(".json"): 12 | format_name = filename[:-5] 13 | with open(os.path.join(formats_path, filename)) as format_file: 14 | format_def = json.load(format_file) 15 | if type(format_def) is not list: 16 | raise TypeError("Imported definition {} is not a list of segments".format(format_name)) 17 | supported_formats[format_name] = format_def 18 | return supported_formats 19 | 20 | supported_formats = load_supported_formats(os.path.join(os.path.dirname(__file__), "formats")) 21 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ Setup script for PythonEDI 2 | 3 | """ 4 | import re 5 | from setuptools import setup, find_packages 6 | 7 | setup( 8 | name="PythonEDI", 9 | description="An X12 EDI generator/parser", 10 | long_description="""PythonEDI uses JSON format definitions to make it easy 11 | to generate or read X12 EDI messages from/to Python dicts/lists.""", 12 | url="https://github.com/glitchassassin/python-edi", 13 | author="Jon Winsley", 14 | author_email="jon.winsley@gmail.com", 15 | license="MIT", 16 | version="0.1.0", 17 | classifiers=[ 18 | "Development Status :: 3 - Alpha", 19 | "Environment :: Plugins", 20 | "Intended Audience :: Developers", 21 | "Intended Audience :: Healthcare Industry", 22 | "Intended Audience :: System Administrators", 23 | "License :: OSI Approved :: MIT License", 24 | "Topic :: Office/Business", 25 | "Topic :: Text Processing" 26 | ], 27 | keywords="x12 edi 810", 28 | packages=find_packages(exclude=['test']), 29 | package_data={"pythonedi": ["formats/*.json"]}, 30 | install_requires=['colorama'], 31 | include_package_data=True, 32 | ) 33 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Make tests a package 3 | """ -------------------------------------------------------------------------------- /test/test_edi.txt: -------------------------------------------------------------------------------- 1 | ISA^00^ ^00^ ^01^043645501 ^01^068717859 ^170311^1102^U^00401^000005814^0^P^| 2 | GS^IN^SENECA^068717859^20170311^1102^5814^X^004010 3 | ST^810^0001 4 | BIG^20170310^12973821^20170310^078061^^^PR 5 | REF^OQ^500100566875 6 | REF^VN^6947432 7 | N1^SE^SENECA MEDICAL LLC^91^SENECA 8 | N3^PO BOX: 531846 9 | N4^ATLANTA^GA^30353-1846 10 | N1^ST^Marietta Memorial Hosp^91^3929 11 | N2^401 Matthew Street 12 | N4^Marietta^OH^45750 13 | ITD^^3^^^^20170409^30^^^2466939^^30 Days from Invoice Date 14 | IT1^1^4^BG^25.6000^CT^VC^165911^IN^000018^MG^365985 15 | PID^F^^^^TUBE MICROTAINER PST W/LITHIUM 16 | IT1^2^1^CS^56.7100^CT^VC^471565^IN^000035^MG^7086 17 | PID^F^^^^SPONGE DRAIN EXCILON 4X4IN 18 | IT1^3^1^CS^44.4300^CT^VC^604967^IN^000037^MG^2B0062Q 19 | PID^F^^^^SOLUTION DEXTROSE 5% 250ML IN 20 | IT1^4^1^EA^5.7200^CT^VC^656199^IN^000062^MG^79-84167 21 | PID^F^^^^IMMOBILIZER SHOULDER LARGE W/ 22 | IT1^5^2^CS^21.6700^CT^VC^605261^IN^000078^MG^2B7127 23 | PID^F^^^^SOLUTION SODIUM CHLORIDE 0.9% 24 | IT1^6^2^BX^60.0200^CT^VC^117803^IN^000083^MG^367323 25 | PID^F^^^^SET BLOOD COLLECTION WINGED 26 | IT1^7^1^BX^60.5800^CT^VC^134463^IN^000092^MG^A39230 27 | PID^F^^^^CUFF BLADDER BLOOD PRESSURE 28 | IT1^8^24^BX^1.3700^CT^VC^167484^IN^000098^MG^44101 29 | PID^F^^^^BANDAGE ADHESIVE 1X3IN STERILE 30 | IT1^9^4^EA^3.2200^CT^VC^871467^IN^000185^MG^79-84007 31 | PID^F^^^^SLING ARM LARGE DELUXE W/ PAD 32 | IT1^10^1^BX^9.1400^CT^VC^312893^IN^000239^MG^TB50 33 | PID^F^^^^TOOTHBRUSH NYLON 50 TUFT 34 | IT1^11^1^BX^19.4200^CT^VC^136498^IN^000241^MG^RTP085 35 | PID^F^^^^TOOTHPASTE FRESHMINT .85OZ 36 | IT1^12^2^BG^6.1100^CT^VC^239236^IN^000260^MG^9043 37 | PID^F^^^^PADDING CAST 3INX4YD COTTON 38 | IT1^13^12^BX^6.8500^CT^VC^594838^IN^000267^MG^309604 39 | PID^F^^^^SYRINGE ONLY 10CC LUER LOK TIP 40 | IT1^14^8^BX^8.4700^CT^VC^196669^IN^000268^MG^302830 41 | PID^F^^^^SYRINGE ONLY 20CC LUER LOK TIP 42 | IT1^15^4^BX^14.1900^CT^VC^138437^IN^000276^MG^8881882812 43 | PID^F^^^^SYRINGE NEEDLE 1CC 28GX1/2IN 44 | IT1^16^1^CS^187.5300^CT^VC^634790^IN^000286^MG^8888266130 45 | PID^F^^^^TUBE SUMP SALEM 16FR 48IN W/ 46 | IT1^17^2^BX^15.0900^CT^VC^531087^IN^000299^MG^305064 47 | PID^F^^^^SYRINGE NEEDLE 10CC 18GX1 1/2 48 | IT1^18^8^BX^17.0200^CT^VC^590844^IN^000316^MG^47147 49 | PID^F^^^^MASK PROCEDURE FLUIDSHIELD 50 | IT1^19^48^EA^1.3200^CT^VC^348656^IN^000383^MG^59430400 51 | PID^F^^^^CLEANSER SECURA 8OZ SPRAY 52 | IT1^20^6^BX^6.0500^CT^VC^675975^IN^000407^MG^59130000 53 | PID^F^^^^BANDAGE ELASTIC 3INX5YD EZE 54 | IT1^21^6^BX^7.5500^CT^VC^676437^IN^000408^MG^59140000 55 | PID^F^^^^BANDAGE ELASTIC 4INX5 1/2YD 56 | IT1^22^4^BX^7.4800^CT^VC^855049^IN^000415^MG^MDS032273Z 57 | PID^F^^^^JELLY LUBRICATING 2.7GM FOIL 58 | IT1^23^5^BX^10.1400^CT^VC^159837^IN^000424^MG^8881850558 59 | PID^F^^^^NEEDLE MAGELLAN 25GX5/8IN 60 | IT1^24^4^CS^90.9800^CT^VC^183713^IN^000440^MG^61301606625 61 | PID^F^^^^PACK S.M.A.R.T. ASSURE 62 | IT1^25^3^BX^6.4100^CT^VC^101486^IN^000462^MG^1538-3 63 | PID^F^^^^TAPE DURAPORE 3INX10YD 64 | IT1^26^6^BX^6.2500^CT^VC^857078^IN^000497^MG^48390 65 | PID^F^^^^MASK FACE SURGICAL WHITE ADULT 66 | IT1^27^3^CS^114.1300^CT^VC^172345^IN^000500^MG^364902 67 | PID^F^^^^DEVICE ACCESS BLOOD COLLECTION 68 | IT1^28^1^CS^104.3900^CT^VC^233500^IN^000503^MG^DYNJ902505A 69 | PID^F^^^^PACK NEURO BASIC CUSTOM 70 | IT1^29^1^CS^53.4300^CT^VC^516534^IN^000531^MG^6120 71 | PID^F^^^^TOOTHETTE PLUS ORAL SWAB 2'S 72 | IT1^30^2^CS^99.5000^CT^VC^193198^IN^000548^MG^34148 73 | PID^F^^^^WRAP STERILIZATION 48X48IN 74 | IT1^31^6^BX^11.3900^CT^VC^856989^IN^000615^MG^49215 75 | PID^F^^^^MASK SURGICAL ANTI FOG GREEN 76 | IT1^32^6^CS^62.0500^CT^VC^114316^IN^000636^MG^704-BX 77 | PID^F^^^^TOWEL OR XRAY DETECTABLE 78 | IT1^33^1^CS^164.3400^CT^VC^260406^IN^000637^MG^5999034 79 | PID^F^^^^DRESSING EXU-DRY 3X4IN FULL 80 | IT1^34^1^CS^177.6200^CT^VC^192966^IN^010950^MG^2D72NS85X 81 | PID^F^^^^GLOVE SURGICAL 8 1/2 LATEX 82 | IT1^35^1^EA^10.6300^CT^VC^454777^IN^000658^MG^TX4442-00 83 | PID^F^^^^SLING & SWATHE UNIVERSAL FOAM 84 | IT1^36^1^CS^148.1200^CT^VC^188779^IN^000667^MG^008875 85 | PID^F^^^^SODASORB LF PRE-PAK CANISTER 86 | IT1^37^1^CS^65.4400^CT^VC^933697^IN^000669^MG^6146LL 87 | PID^F^^^^TRAY CATHETER FOLEY 16FR 5CC 88 | IT1^38^1^CS^14.7700^CT^VC^153193^IN^000672^MG^68800 89 | PID^F^^^^TRAY IRRIGATION 1200CC W/ 90 | IT1^39^2^CS^58.7500^CT^VC^596718^IN^000677^MG^400 91 | PID^F^^^^SPONGE LAPAROTOMY 18X18IN 92 | IT1^40^1^CS^60.6500^CT^VC^103884^IN^000702^MG^8507SA 93 | PID^F^^^^CONTAINER SHARPS 5QT IN-ROOM 94 | IT1^41^10^BX^6.8800^CT^VC^235200^IN^000711^MG^367861 95 | PID^F^^^^TUBE VACUTAINER DRAW 4ML 96 | IT1^42^20^BX^17.2300^CT^VC^531509^IN^000713^MG^367986 97 | PID^F^^^^TUBE VACUTAINER DRAW 5ML SST 98 | IT1^43^1^CS^29.3100^CT^VC^217971^IN^000732^MG^HCS0066 99 | PID^F^^^^MOUTHWASH 4OZ ALCOHOL FREE 100 | IT1^44^1^CS^280.6400^CT^VC^153674^IN^000758^MG^IPC-5000E 101 | PID^F^^^^CATHETER PRESSURE INTRAUTERINE 102 | IT1^45^36^TB^4.2600^CT^VC^468322^IN^000760^MG^Q55172 103 | PID^F^^^^WIPES SUPER SANI-CLOTH LARGE 104 | IT1^46^2^CS^0.0000^CT^VC^240340^IN^000764^MG^66178 105 | PID^F^^^^NUTRITION SIMILAC PRO ADVANCE 106 | IT1^47^2^BX^229.6800^CT^VC^410266^IN^000767^MG^900013B01 107 | PID^F^^^^KIT NEEDLE GUIDE 21G W/ 48IN 108 | IT1^48^1^CS^189.7400^CT^VC^233511^IN^000833^MG^DYNJ902500A 109 | PID^F^^^^PACK CYSTO CUSTOM 110 | IT1^49^1^CS^65.7800^CT^VC^446112^IN^000841^MG^33500 111 | PID^F^^^^PACK ICE LARGE STAY-DRY 112 | IT1^50^8^BX^23.4500^CT^VC^143011^IN^000852^MG^HCS5001 113 | PID^F^^^^TOURNIQUET 1X18IN SMOOTH BULK 114 | IT1^51^2^CS^324.0900^CT^VC^109582^IN^000900^MG^A3403-22/24 115 | PID^F^^^^TRAY SPINAL W/ DRUGS CUSTOM 116 | IT1^52^1^CS^91.9400^CT^VC^232152^IN^000905^MG^DYNJ51533 117 | PID^F^^^^PACK MAJOR BASIN CUSTOM 118 | IT1^53^1^CS^241.7400^CT^VC^184551^IN^000915^MG^74023 119 | PID^F^^^^SLEEVE SCD COMFORT KNEE LENGTH 120 | IT1^54^4^BX^34.2900^CT^VC^750000^IN^000917^MG^405181 121 | PID^F^^^^NEEDLE SPINAL 22GX3 1/2IN 122 | IT1^55^2^BX^16.7000^CT^VC^448746^IN^000932^MG^372615 123 | PID^F^^^^SCALPEL SAFETY SZ15 DISPOSABLE 124 | IT1^56^30^BX^8.5100^CT^VC^170492^IN^000949^MG^50706 125 | PID^F^^^^GLOVES EXAM SMALL NITRILE 126 | IT1^57^70^BX^8.5100^CT^VC^170493^IN^000950^MG^50707 127 | PID^F^^^^GLOVES EXAM MEDIUM NITRILE 128 | IT1^58^20^BX^8.5100^CT^VC^170496^IN^000951^MG^50708 129 | PID^F^^^^GLOVES EXAM LARGE NITRILE 130 | IT1^59^10^CS^122.0100^CT^VC^184546^IN^000977^MG^74022 131 | PID^F^^^^SLEEVE SCD COMFORT KNEE LENGTH 132 | IT1^60^1^CS^176.1700^CT^VC^237095^IN^000986^MG^DYNJ0620708J 133 | PID^F^^^^PACK VAGINAL DELIVERY CUSTOM 134 | IT1^61^3^CS^89.4500^CT^VC^156776^IN^000992^MG^92342 135 | PID^F^^^^GOWN SURGICAL XLARGE STERILE 136 | IT1^62^48^EA^4.8500^CT^VC^767301^IN^000997^MG^08552 137 | PID^F^^^^WASH WOUND SALINE 210ML SPRAY 138 | IT1^63^3^CS^15.5600^CT^VC^104674^IN^001025^MG^1103 139 | PID^F^^^^CANNULA NASAL 7FT TUBING ADULT 140 | IT1^64^24^EA^6.7600^CT^VC^116943^IN^001030^MG^520211000 141 | PID^F^^^^RESUSCITATOR ADULT SPUR2 W/BAG 142 | IT1^65^1^CS^104.4600^CT^VC^782060^IN^001052^MG^8989PG2 143 | PID^F^^^^CONTAINER SHARPS YELLOW 18GAL 144 | IT1^66^2^BX^19.4500^CT^VC^353698^IN^001053^MG^66000321 145 | PID^F^^^^DRESSING PRIMAPORE 11 3/4X4IN 146 | IT1^67^10^PK^7.1500^CT^VC^887968^IN^001067^MG^367856 147 | PID^F^^^^TUBE VACUTAINER 3ML LAVENDER 148 | IT1^68^10^BX^8.3000^CT^VC^152447^IN^001070^MG^SLN240 149 | PID^F^^^^LANCET ONE STEP NEEDLE 21G 150 | IT1^69^1^CS^164.5300^CT^VC^157695^IN^001073^MG^22591 151 | PID^F^^^^CLEANER INSTRUMENT DETERGENT 152 | IT1^70^1^CS^79.0400^CT^VC^666966^IN^001085^MG^5010SA 153 | PID^F^^^^CONTAINER SPECIMEN 3000ML 24 154 | IT1^71^6^BX^8.3000^CT^VC^152421^IN^001087^MG^SLN200 155 | PID^F^^^^LANCET ONE STEP NEEDLE 23G 156 | IT1^72^24^EA^2.4400^CT^VC^156380^IN^001104^MG^HCS9002 157 | PID^F^^^^THERMOMETER DIGITAL W/ 5 PROBE 158 | IT1^73^48^TB^4.3900^CT^VC^193091^IN^001120^MG^P13872 159 | PID^F^^^^WIPES SANI-CLOTH AF3 LARGE 160 | IT1^74^2^CS^253.0000^CT^VC^152446^IN^001147^MG^2329 161 | PID^F^^^^SENSOR ADHESIVE NEONATAL 18IN 162 | IT1^75^2^CS^12.8400^CT^VC^689430^IN^001152^MG^1115 163 | PID^F^^^^TUBING OXYGEN SUPPLY 7FT 164 | IT1^76^1^BX^88.3400^CT^VC^509190^IN^001176^MG^381454 165 | PID^F^^^^CATHETER IV 16GX1.16IN SAFETY 166 | IT1^77^2^CS^72.6300^CT^VC^864660^IN^001186^MG^77-301291 167 | PID^F^^^^SYRINGE ANGIOGRAPHIC 12CC 168 | IT1^79^10^BX^54.1900^CT^VC^132759^IN^001190^MG^A39048 169 | PID^F^^^^CUFF BLADDER BLOOD PRESSURE 170 | IT1^80^3^CS^51.9500^CT^VC^132736^IN^001191^MG^A39085 171 | PID^F^^^^CUFF BLADDER BLOOD PRESSURE 172 | IT1^81^24^EA^3.5000^CT^VC^174874^IN^001192^MG^SC0120W 173 | PID^F^^^^OINTMENT CHAMOSYN MULTIPURPOSE 174 | IT1^83^2^BX^36.3300^CT^VC^676924^IN^001244^MG^4008 175 | PID^F^^^^DRESSING OPSITE IV 3000 176 | IT1^84^2^BX^15.3000^CT^VC^749580^IN^001251^MG^59420600 177 | PID^F^^^^WIPES SKIN PREP NO-STING 178 | IT1^85^25^EA^3.3800^CT^VC^402487^IN^001253^MG^0035380 179 | PID^F^^^^KIT FEMALE URINE COLLECTION 180 | IT1^86^4^BG^8.3500^CT^VC^792556^IN^001266^MG^1164 181 | PID^F^^^^AIRWAY GUEDEL SIZE4 90MM 9CM 182 | IT1^87^6^CS^113.3700^CT^VC^168648^IN^001267^MG^96002S 183 | PID^F^^^^HOLDER NEEDLE SHORT SAF-T W/ 184 | IT1^88^1^BX^5.2600^CT^VC^218810^IN^001280^MG^05213509001 185 | PID^F^^^^SOLUTION CONTROL ACCU-CHEK 186 | IT1^89^1^CS^431.6000^CT^VC^939199^IN^001344^MG^7300 187 | PID^F^^^^PROTECTOR HEEL STANDARD 188 | IT1^90^4^BX^10.0500^CT^VC^204073^IN^001354^MG^305060 189 | PID^F^^^^SYRINGE NEEDLE 3CC 18GX1 1/2IN 190 | IT1^91^2^CS^467.1900^CT^VC^237896^IN^001372^MG^DYNJ902503B 191 | PID^F^^^^PACK LAP CHOLECYSECTOMY CUSTOM 192 | IT1^92^2^CS^367.4600^CT^VC^233515^MG^DYNJ902504A 193 | PID^F^^^^PACK LAPAROTOMY CUSTOM 194 | IT1^93^8^BX^5.3100^CT^VC^221839^IN^001398^MG^05031-750 195 | PID^F^^^^COVER PROBE THERMOMETER CLEAR 196 | IT1^94^2^CS^172.1500^CT^VC^230162^IN^001410^MG^DYNJ0650215F 197 | PID^F^^^^PACK PERMANENT PACING CUSTOM 198 | IT1^95^2^BX^54.4700^CT^VC^245274^IN^001414^MG^321400000U 199 | PID^F^^^^MASK LARYNGEAL SIZE 4 AURAONCE 200 | IT1^96^1^CS^132.6500^CT^VC^215101^IN^001429^MG^9000-ANDM4 201 | PID^F^^^^PACK TURNAROUND CUSTOM 202 | IT1^97^4^CS^169.5100^CT^VC^122645^IN^001450^MG^260815 203 | PID^F^^^^APPLICATOR CHLORAPREP 26ML W/ 204 | IT1^98^7^CS^33.2000^CT^VC^152603^IN^001466^MG^1915-100 205 | PID^F^^^^ELECTRODE FASTRACE 4 ADHESIVE 206 | IT1^99^2^CS^272.3100^CT^VC^186748^IN^001503^MG^K09-05971B 207 | PID^F^^^^KIT MANIFOLD CUSTOM 208 | IT1^100^1^CS^222.4800^CT^VC^187586^IN^001504^MG^MDD300H 209 | PID^F^^^^SYSTEM WASTE DISPOSAL W/1400ML 210 | IT1^101^3^BX^85.0800^CT^VC^193014^IN^014459^MG^2D72PT60X 211 | PID^F^^^^GLOVE SURGICAL 6 SYNTHETIC 212 | IT1^102^4^BX^85.0800^CT^VC^193015^IN^014325^MG^2D72PT65X 213 | PID^F^^^^GLOVE SURGICAL 6 1/2 SYNTHETIC 214 | IT1^103^4^BX^85.0800^CT^VC^193016^IN^015404^MG^2D72PT70X 215 | PID^F^^^^GLOVE SURGICAL 7 SYNTHETIC 216 | IT1^104^4^BX^85.0800^CT^VC^193019^IN^015312^MG^2D72PT80X 217 | PID^F^^^^GLOVE SURGICAL 8 SYNTHETIC 218 | IT1^105^3^CS^175.8400^CT^VC^233501^IN^001539^MG^DYNJ50775A 219 | PID^F^^^^PACK LOWER ENDO CUSTOM 220 | IT1^106^2^CS^57.1800^CT^VC^137496^MG^332112 221 | PID^F^^^^TRAY SUPPORT NO DRUGS 222 | IT1^107^1^CS^37.3400^CT^VC^620856^IN^000384^MG^MSC095060 223 | PID^F^^^^SHAMPOO & BODY WASH 8OZ SOOTHE 224 | IT1^108^8^CS^4.5300^CT^VC^131731^IN^000284^MG^17116 225 | PID^F^^^^WIPES BABY SENSITIVE PAMPERS 226 | IT1^109^6^BX^59.9400^CT^VC^132751^IN^001189^MG^A39019 227 | PID^F^^^^CUFF BLOOD PRESSURE ADULT LONG 228 | IT1^110^4^BX^7.2400^CT^VC^173729^IN^000277^MG^309657 229 | PID^F^^^^SYRINGE ONLY 3CC LUER LOCK TIP 230 | IT1^111^2^CS^92.5300^CT^VC^182919^IN^000731^MG^006-1692 231 | PID^F^^^^MUG 20 OZ CUSTOM 232 | IT1^112^20^BX^1.2800^CT^VC^389445^IN^000570^MG^6818 233 | PID^F^^^^PAD ALCOHOL PREP WEBCOL MEDIUM 234 | IT1^113^10^BX^7.7900^CT^VC^311910^IN^001402^MG^305180 235 | PID^F^^^^NEEDLE BLUNT FILL 18GX1 1/2IN 236 | IT1^114^36^BX^24.8100^CT^VC^218809^IN^001279^MG^05942861001 237 | PID^F^^^^STRIPS TEST ACCUCHEK INFORM II 238 | IT1^115^12^EA^4.5800^CT^VC^774935^IN^000899^MG^324908 239 | PID^F^^^^OINTMENT PROTECTIVE 8OZ TUBE 240 | IT1^116^2^CS^234.5500^CT^VC^117098^IN^001422^MG^989803107811 241 | PID^F^^^^PAD DEFIBRILLATOR RADIOLUSCENT 242 | IT1^117^3^CS^75.7400^CT^VC^660670^IN^001126^MG^7988 243 | PID^F^^^^BATH IMPREVA 8PK WASHLCLOTH 244 | IT1^118^2^CS^549.2000^CT^VC^222744^IN^001094^MG^DYNDV1532B 245 | PID^F^^^^KIT IV START W/ EXTENSION SET 246 | IT1^119^3^CS^259.3800^CT^VC^310788^IN^000386^MG^367336 247 | PID^F^^^^SET BLOOD COLLECTION WINGED 248 | IT1^120^8^BX^8.3000^CT^VC^166243^IN^000266^MG^309646 249 | PID^F^^^^SYRINGE ONLY 5CC LUER-LOK TIP 250 | IT1^121^100^EA^0.5900^CT^VC^132276^IN^000641^MG^441106 251 | PID^F^^^^GAUZE FLUFF ROLL 4INX4 1/8YD 252 | IT1^122^2^CS^43.6200^CT^VC^850388^IN^000668^MG^3143 253 | PID^F^^^^TRAY CATHETER OPEN SYSTEM 14FR 254 | IT1^123^2^CS^253.0000^CT^VC^166779^IN^001146^MG^2328 255 | PID^F^^^^SENSOR ADHESIVE INFANT 18IN 256 | IT1^124^3^CS^28.0100^CT^VC^570218^IN^001031^MG^8884719009 257 | PID^F^^^^EXERCISER BREATH VOLDYNE 258 | IT1^125^4^EA^5.0000^CT^VC^286153^IN^001046^MG^183910 259 | PID^F^^^^PASTE STOMAHESIVE 2OZ 260 | IT1^126^12^EA^17.5900^CT^VC^198311^IN^001209^MG^HCS9006LF 261 | PID^F^^^^UNIT BLOOD PRESSURE LARGEADULT 262 | TDS^2466939 263 | CTT^124 264 | SE^262^0001 265 | GE^1^5814 266 | IEA^1^000005814 267 | -------------------------------------------------------------------------------- /test/test_parse_edi.py: -------------------------------------------------------------------------------- 1 | """ Parsing test cases for PythonEDI """ 2 | 3 | import unittest 4 | import pprint 5 | import pythonedi 6 | 7 | class TestParse810(unittest.TestCase): 8 | """ Tests the Parser module """ 9 | def setUp(self): 10 | self.parser = pythonedi.EDIParser(edi_format="810") #, segment_delimiter="~") 11 | 12 | def test_parse(self): 13 | with open("test/test_edi.txt", "r") as test_edi_file: 14 | test_edi = test_edi_file.read() 15 | found_segments, edi_data = self.parser.parse(test_edi) 16 | print("\n\n{}".format(found_segments)) 17 | print("\n\n") 18 | pprint.pprint(edi_data) 19 | -------------------------------------------------------------------------------- /test/test_pythonedi.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test cases for pythonedi module 3 | """ 4 | 5 | import string 6 | import random 7 | import unittest 8 | from datetime import datetime 9 | 10 | import pythonedi 11 | 12 | class TestGenerate810(unittest.TestCase): 13 | 14 | def setUp(self): 15 | self.g = pythonedi.EDIGenerator() 16 | 17 | def test_generate(self): 18 | invoice_number = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(22)) 19 | po_number = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(22)) 20 | #pythonedi.explain("810", "ITD") 21 | edi_data = { 22 | "ISA": [ 23 | "00", # Authorization Information Qualifier 24 | "", # Authorization Information 25 | "00", # Security Information Qualifier 26 | "", # Security Information 27 | "ZZ", # Interchange Sender ID Qualifier 28 | "306000000", # Interchange Sender ID 29 | "ZZ", # Interchange Receiver ID Qualifier 30 | "306009503", # Interchange Receiver ID 31 | datetime(2006, 6, 24, 10, 00), # Interchange Date 32 | datetime(2006, 6, 24, 10, 00), # Interchange Time 33 | "U", # Interchange Control Standards Identifier 34 | "00401", # Interchange Control Version Number 35 | "000010770", # Interchange Control Number 36 | "0", # Acknowledgment Requested 37 | "P", # Usage Indicator 38 | "/" # Component Element Separator 39 | ], 40 | "GS": [ 41 | "IN", # Functional Identifier Code 42 | "306000000", # Application Sender's Code 43 | "306009503", # Application Receiver's Code 44 | datetime(2006, 6, 24, 10, 00), # Date 45 | datetime(2006, 6, 24, 10, 00), # Time 46 | "1164", # Group Control Number 47 | "X", # Responsible Agency Code 48 | "004010", # Version/Release/Industry Identifier Code 49 | ], 50 | "ST": [ 51 | "810", # Transaction Set Identifier Code: Invoice 52 | "11640002" # Transaction Set Control Number 53 | ], 54 | "BIG": [ 55 | datetime(2006, 6, 24), # Invoice date 56 | "INV-00777", # Invoice number 57 | datetime(2006, 6, 22), # Purchase order date 58 | "PO-001063", # PO Number 59 | None, 60 | None, 61 | "DR" 62 | ], 63 | "L_N1": [ 64 | { 65 | "N1": [ 66 | "ST", # Entity Identifier Code: Ship To 67 | "SANGA GENERAL HOSPITAL", # Name 68 | "91", # ID Code Qualifier: Assigned by seller 69 | "6877755" # ID number 70 | ], 71 | "N3": [ 72 | "1765 HOSPITAL STREET" # Additional address information 73 | ], 74 | "N4": [ # Geographic location 75 | "WESTWOOD", # City Name 76 | "ON", # State or Province Code 77 | "M8Y 6H8" # Postal Code 78 | ] 79 | }, 80 | { 81 | "N1": [ 82 | "BT", # Entity Identifier Code: Bill To 83 | "SANGA GENERAL HOSPITAL", # Name 84 | "91", # ID Code Qualifier: Assigned by seller 85 | "6877700" # ID number 86 | ], 87 | }, 88 | { 89 | "N1": [ 90 | "VN", # Entity Identifier Code: Vendor 91 | "ALLSUPPLIES INC.", # Name 92 | "91", # ID Code Qualifier: Assigned by seller 93 | "306000000" # ID number 94 | ], 95 | } 96 | ], 97 | "ITD": [ 98 | "05", # Terms Type Code 99 | "3", # Terms Basis Date Code: Invoice Date 100 | None, # Terms Discount % 101 | None, # Terms Discount Due Date 102 | None, # Terms Discount Days Due 103 | datetime(2006, 6, 24), # Terms Net Due Date 104 | "30" # Terms Net Days 105 | ], 106 | "DTM": [ 107 | "011", # Date/Time Qualifier: Shipped 108 | datetime(2006, 6, 20) # Date 109 | ], 110 | "L_IT1": [ 111 | { 112 | "IT1": [ # Baseline Item Data 113 | "1", # Assigned Identification 114 | 1 # Quantity Invoiced 115 | ] 116 | } 117 | ] 118 | } 119 | 120 | message = self.g.build(edi_data) 121 | print("\n\n" + message) 122 | 123 | def test_error_handling(self): 124 | invoice_number = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(22)) 125 | po_number = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(22)) 126 | 127 | edi_data = { 128 | "ISA": [ 129 | "00", # Authorization Information Qualifier 130 | "", # Authorization Information 131 | "00", # Security Information Qualifier 132 | "", # Security Information 133 | "ZZ", # Interchange Sender ID Qualifier 134 | "306000000", # Interchange Sender ID 135 | "ZZ", # Interchange Receiver ID Qualifier 136 | "306009503", # Interchange Receiver ID 137 | datetime.now(), # Interchange Date 138 | datetime.now(), # Interchange Time 139 | "U", # Interchange Control Standards Identifier 140 | "00401", # Interchange Control Version Number 141 | "000010770", # Interchange Control Number 142 | "0", # Acknowledgment Requested 143 | "P", # Usage Indicator 144 | "/" # Component Element Separator 145 | ], 146 | "ST": [ 147 | "810", 148 | "123456" 149 | ], 150 | "BIG": [ 151 | datetime.now(), # Invoice date 152 | invoice_number, # Invoice number 153 | datetime.now(), # Purchase order date 154 | po_number, 155 | None, 156 | None, 157 | "CN" 158 | ], 159 | "REF": [ 160 | "AP" 161 | ] 162 | } 163 | old_level = pythonedi.Debug.level 164 | pythonedi.Debug.level = 0 # Turn off explaining for intentional exceptions 165 | 166 | with self.assertRaises(ValueError): 167 | message = self.g.build(edi_data) 168 | 169 | pythonedi.Debug.level = old_level 170 | --------------------------------------------------------------------------------