├── .dockerignore ├── .github └── workflows │ ├── continuous-integration.yml │ └── test-image-build.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── README.md ├── demo-file ├── demo-single-line.270 ├── demo.270 ├── demo.271 ├── demo.276 ├── demo.277 ├── demo.834 ├── demo.835 ├── demo.837 └── demo.837i ├── logging.yaml ├── push-image.sh ├── pyproject.toml ├── repo-docs ├── CONTAINER_SUPPORT.md ├── DESIGN.md ├── NEW_TRANSACTION.md ├── testing-transactions.png └── transaction-package.png ├── setup.cfg └── src ├── linuxforhealth └── x12 │ ├── __init__.py │ ├── api.py │ ├── cli.py │ ├── config.py │ ├── encoding.py │ ├── io.py │ ├── models.py │ ├── parsing.py │ ├── support.py │ ├── v4010 │ ├── __init__.py │ ├── segments.py │ ├── validators.py │ ├── x12_837_004010X096A1 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ └── x12_837_004010X098A1 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ ├── v5010 │ ├── __init__.py │ ├── segments.py │ ├── validators.py │ ├── x12_270_005010X279A1 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ ├── x12_271_005010X279A1 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ ├── x12_276_005010X212 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ ├── x12_277_005010X212 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ ├── x12_834_005010X220A1 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ ├── x12_835_005010X221A1 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ ├── x12_837_005010X222A2 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ └── x12_837_005010X223A3 │ │ ├── __init__.py │ │ ├── loops.py │ │ ├── parsing.py │ │ ├── segments.py │ │ └── transaction_set.py │ └── validators.py └── tests ├── __init__.py ├── benefit_enrollment_maintenance ├── __init__.py └── test_834_005010X220A1.py ├── conftest.py ├── eligibility ├── __init__.py ├── test_270_005010X279A1.py └── test_271_005010X279A1.py ├── healthcare_claim_institutional ├── __init__.py ├── test_837_004010X096A1.py └── test_837i_005010X223A3.py ├── healthcare_claim_payment ├── __init__.py └── test_835_005010X221A1.py ├── healthcare_claim_professional ├── __init__.py ├── test_837_004010X098A1.py └── test_837_005010X222A2.py ├── healthcare_claim_status ├── __init__.py ├── test_x12_276_005010X212.py └── test_x12_277_005010X212.py ├── resources ├── 270_005010X279A1 │ ├── dependent-health-benefit-check.270 │ └── subscriber-health-benefit-check.270 ├── 271_005010X279A1 │ ├── dependent-health-benefit-check.271 │ ├── subscriber-health-benefit-check-error.271 │ └── subscriber-health-benefit-check.271 ├── 276_005010X212 │ ├── claim-level-status-ncpdp.276 │ ├── claim-level-status.276 │ ├── information-receiver-level-status.276 │ └── provider-level-status.276 ├── 277_005010X212 │ ├── claim-level-status-ncpdp.277 │ ├── claim-level-status.277 │ ├── information-receiver-level-status.277 │ └── provider-level-status.277 ├── 834_005010X220A1 │ ├── add-dependent.834 │ ├── add-subscriber-coverage.834 │ ├── cancel-dependent.834 │ ├── change-subscriber-information.834 │ ├── enroll-employee-managed-care.834 │ ├── enroll-employee-multiple-products.834 │ ├── reinstate-employee-coverage-level.834 │ ├── reinstate-employee.834 │ ├── reinstate-member-eligiblity-ins.834 │ └── terminate-subscriber-eligibility.834 ├── 835_005010X221A1 │ ├── cob-contractural-adjustment.835 │ ├── managed-care.835 │ ├── medicare-part-a.835 │ ├── secondary-payment.835 │ └── tertiary-payment.835 ├── 837_004010X096A1 │ ├── automobile-accident.837 │ ├── homeowners.837 │ ├── institutional-ppo-repriced.837 │ ├── institutional.837 │ └── workers-compensation.837 ├── 837_004010X098A1 │ ├── coordination-of-benefits.837 │ ├── dependent-commercial-insurance-01.837 │ ├── dependent-commercial-insurance-02.837 │ ├── dependent-commercial-insurance-03.837 │ ├── patient-is-dependent.837 │ └── patient-is-subscriber.837 ├── 837_005010X222A2 │ ├── demo.ambulance.example5.837 │ ├── demo.autoaccident.837 │ ├── demo.cob.2ndary.example4.837 │ ├── demo.cob.example3.A.837 │ ├── demo.cob.example3.B.837 │ ├── demo.cob.example3.C.837 │ ├── demo.cob.example4.837 │ ├── demo.drug.example10.1.837 │ ├── demo.drug.example10.2.837 │ ├── demo.drug.example10.3.837 │ ├── demo.example1.837 │ ├── demo.example11.837 │ ├── demo.example12.837 │ ├── demo.example2.837 │ ├── demo.example6.837 │ ├── demo.example7.837 │ ├── demo.example8.837 │ └── demo.example9.837 └── 837_005010X223A3 │ ├── institutional-claim.837i │ ├── out-of-network-repriced-claim.837i │ ├── ppo-repriced-claim.837i │ └── two-claims-single-provider.837i ├── support.py ├── test_4010_segments.py ├── test_5010_segments.py ├── test_api.py ├── test_common_validations.py ├── test_create_parser.py ├── test_encoding.py ├── test_parsing_matcher.py ├── test_support.py ├── test_x12_model_reader.py ├── test_x12_parser_context.py └── test_x12_segment_reader.py /.dockerignore: -------------------------------------------------------------------------------- 1 | .github 2 | .idea 3 | .vscode 4 | **/.pytest_cache 5 | **/linuxforhealth_x12.egg-info 6 | demo-file 7 | repo-docs 8 | **/tests 9 | venv 10 | .gitignore 11 | LICENSE 12 | -------------------------------------------------------------------------------- /.github/workflows/continuous-integration.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | python-version: ["3.9.13", "3.10.5"] 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Set up Python ${{ matrix.python-version }} 19 | uses: actions/setup-python@v2 20 | with: 21 | python-version: ${{ matrix.python-version }} 22 | - name: Install dependencies 23 | run: | 24 | python -m pip install --upgrade pip setuptools 25 | pip install -e .[dev,api] 26 | - name: Validate Formatting 27 | run: | 28 | black -t py38 --check --diff ./src 29 | - name: Execute Unit Tests 30 | run: | 31 | pytest 32 | - name: Run X12 CLI 33 | run: | 34 | for f in demo-file/demo.*; do 35 | lfhx12 -m -p $f 1> /dev/null 36 | done 37 | -------------------------------------------------------------------------------- /.github/workflows/test-image-build.yml: -------------------------------------------------------------------------------- 1 | name: Test X12 Image Build 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build-image: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Check out the repo 14 | uses: actions/checkout@v3 15 | - name: QEMU setup 16 | uses: docker/setup-qemu-action@v2 17 | - name: Docker buildx setup 18 | uses: docker/setup-buildx-action@v2 19 | - name: Build and push Docker image 20 | uses: docker/build-push-action@v3 21 | with: 22 | context: . 23 | build-args: | 24 | X12_SEM_VER=0.57.0 25 | platforms: linux/amd64 26 | push: false 27 | tags: ci-testing -------------------------------------------------------------------------------- /.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 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | build-venv 108 | env/ 109 | venv/ 110 | ENV/ 111 | env.bak/ 112 | venv.bak/ 113 | cli-test/ 114 | 115 | # Spyder project settings 116 | .spyderproject 117 | .spyproject 118 | 119 | # Rope project settings 120 | .ropeproject 121 | 122 | # mkdocs documentation 123 | /site 124 | 125 | # mypy 126 | .mypy_cache/ 127 | .dmypy.json 128 | dmypy.json 129 | 130 | # Pyre type checker 131 | .pyre/ 132 | 133 | # IDE Files 134 | .idea 135 | 136 | # OS Specific 137 | .DS_Store 138 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Builds the LinuxForHealth X12 API container using a multi-stage build 2 | 3 | # build stage 4 | FROM python:3.10-slim-buster AS builder 5 | 6 | # the full semantic version number, used to match to the generated wheel file in dist/ 7 | ARG X12_SEM_VER 8 | 9 | # OS library updates and build tooling 10 | RUN apt-get update 11 | RUN apt-get install -y --no-install-recommends \ 12 | build-essential \ 13 | gcc 14 | 15 | # copy source and build files 16 | WORKDIR /tmp/lfh-x12 17 | COPY setup.cfg . 18 | COPY pyproject.toml . 19 | COPY ../src src/ 20 | 21 | # build the service 22 | RUN python -m venv /tmp/lfh-x12/venv 23 | ENV PATH="/tmp/lfh-x12/venv/bin:$PATH" 24 | RUN python -m pip install --upgrade pip setuptools wheel build 25 | RUN python -m build 26 | RUN python -m pip install dist/linuxforhealth_x12-"$X12_SEM_VER"-py3-none-any.whl[api] 27 | 28 | # main image 29 | FROM python:3.10-slim-buster 30 | 31 | # container build arguments 32 | # lfh user id and group ids 33 | ARG LFH_USER_ID=1000 34 | ARG LFH_GROUP_ID=1000 35 | 36 | # create service user and group 37 | RUN groupadd -g $LFH_GROUP_ID lfh && \ 38 | useradd -m -u $LFH_USER_ID -g lfh lfh 39 | USER lfh 40 | WORKDIR /home/lfh 41 | 42 | # configure and execute application 43 | COPY --from=builder /tmp/lfh-x12/venv ./venv 44 | # set venv executables first in path 45 | ENV PATH="/home/lfh/venv/bin:$PATH" 46 | # listening address for application 47 | ENV X12_UVICORN_HOST=0.0.0.0 48 | EXPOSE 5000 49 | CMD ["python", "-m", "linuxforhealth.x12.api"] 50 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include src/x12/VERSION.txt -------------------------------------------------------------------------------- /demo-file/demo-single-line.270: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~GS*HS*000000005*54321*20131031*1147*1*X*005010X279A1~ST*270*1234*005010X279A1~BHT*0022*13*10001234*20060501*1319~HL*1**20*1~NM1*PR*2*ABC COMPANY*****PI*842610001~HL*2*1*21*1~NM1*1P*2*BONE AND JOINT CLINIC*****SV*2000035~HL*3*2*22*0~TRN*1*93175-012547*9877281234~NM1*IL*1*SMITH*ROBERT****MI*11122333301~DMG*D8*19430519~DTP*291*D8*20060501~EQ*30~SE*13*1234~GE*1*1~IEA*1*000000907~ -------------------------------------------------------------------------------- /demo-file/demo.270: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HS*000000005*54321*20131031*1147*1*X*005010X279A1~ 3 | ST*270*1234*005010X279A1~ 4 | BHT*0022*13*10001234*20060501*1319~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC COMPANY*****PI*842610001~ 7 | HL*2*1*21*1~ 8 | NM1*1P*2*BONE AND JOINT CLINIC*****SV*2000035~ 9 | HL*3*2*22*0~ 10 | TRN*1*93175-012547*9877281234~ 11 | NM1*IL*1*SMITH*ROBERT****MI*11122333301~ 12 | DMG*D8*19430519~ 13 | DTP*291*D8*20060501~ 14 | EQ*30~ 15 | SE*13*1234~ 16 | GE*1*1~ 17 | IEA*1*000000907~ -------------------------------------------------------------------------------- /demo-file/demo.271: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HB*000000005*54321*20131031*1147*1*X*005010X279A1~ 3 | ST*271*4321*005010X279A1~ 4 | BHT*0022*11*10001234*20060501*1319~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC COMPANY*****PI*841610001~ 7 | HL*2*1*21*1~ 8 | NM1*1P*2*BONE AND JOIN CLINIC*****SV*2000035~ 9 | HL*3*2*22*0~ 10 | TRN*2*93175-012547*9877281234~ 11 | NM1*IL*1*SMITH*JOHN****MI*123456789~ 12 | N3*15197 BROADWAY AVENUE*APT 215~ 13 | N4*KANSAS CITY*MO*64108~ 14 | DMG*D8*19630519*M~ 15 | DTP*346*D8*20060101~ 16 | EB*1**30**GOLD 123 PLAN~ 17 | EB*L~ 18 | LS*2120~ 19 | NM1*P3*1*JONES*MARCUS****SV*0202034~ 20 | LE*2120~ 21 | EB*1**1^33^35^47^86^88^98^AL^MH^UC~ 22 | EB*B**1^33^35^47^86^88^98^AL^MH^UC*HM*GOLD 123 PLAN*27*10.00*****Y~ 23 | EB*B**1^33^35^47^86^88^98^AL^MH^UC*HM*GOLD 123 PLAN*27*30.00*****N~ 24 | SE*22*4321~ 25 | GE*1*1~ 26 | IEA*1*000000907~ -------------------------------------------------------------------------------- /demo-file/demo.276: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HR*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*276*0001*005010X212~ 4 | BHT*0010*13*ABC276XXX*20050915*1425~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL*****XX*1666666661~ 11 | HL*4*3*22*0~ 12 | DMG*D8*19301210*M~ 13 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 14 | TRN*1*ABCXYZ1~ 15 | REF*BLT*111~ 16 | REF*EJ*SM123456~ 17 | AMT*T3*8513.88~ 18 | DTP*472*RD8*20050831-20050906~ 19 | HL*5*3*22*0~ 20 | DMG*D8*19301115*F~ 21 | NM1*IL*1*JONES*MARY****MI*234567890A~ 22 | TRN*1*ABCXYZ2~ 23 | REF*BLT*111~ 24 | REF*EJ*J0234567~ 25 | AMT*T3*7599~ 26 | DTP*472*RD8*20050731-20050809~ 27 | HL*6*2*19*1~ 28 | NM1*1P*2*HOME HOSPITAL PHYSICANS*****XX*166666666~ 29 | HL*7*6*22*1~ 30 | NM1*IL*1*MANN*JOHN****MI*345678901~ 31 | HL*8*7*23~ 32 | DMG*D8*19951101*M~ 33 | NM1*QC*1*MANN*JOSEPH~ 34 | TRN*1*ABCXYZ3~ 35 | REF*EJ*MA345678~ 36 | SVC*HC:99203*150*****1~ 37 | DTP*472*D8*20050501~ 38 | SE*36*0001~ 39 | GE*1*1~ 40 | IEA*1*000000907~ -------------------------------------------------------------------------------- /demo-file/demo.277: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HN*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*277*0001*005010X212~ 4 | BHT*0010*08*277X212*20050916*0810*DG~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL*****XX*1666666661~ 11 | HL*4*3*22*0~ 12 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 13 | TRN*2*ABCXYZ1~ 14 | STC*P3:317*20050913**8513.88~ 15 | REF*1K*05347006051~ 16 | REF*BLT*111~ 17 | REF*EJ*SM123456~ 18 | DTP*472*RD8*20050831-20050906~ 19 | HL*5*3*22*0~ 20 | NM1*IL*1*JONES*MARY****MI*234567890A~ 21 | TRN*2*ABCXYZ2~ 22 | STC*F0:3*20050915**7599.00*7599.00~ 23 | REF*1K*0529675341~ 24 | REF*BLT*111~ 25 | REF*EJ*J0234567~ 26 | DTP*472*RD8*20050731-20050809~ 27 | HL*6*2*19*1~ 28 | NM1*1P*2*HOME HOSPITAL PHYSICIANS*****XX*166666666~ 29 | HL*7*6*22*1~ 30 | NM1*IL*1*MANN*JOHN****MI*345678901~ 31 | HL*8*7*23~ 32 | NM1*QC*1*MANN*JOSEPH~ 33 | TRN*2*ABCXYC3~ 34 | STC*F2:88:QC*20050612**150.00*0.00~ 35 | REF*1K*051681010827~ 36 | REF*EJ*MA345678~ 37 | SVC*HC:99203*150.00*0.00****1.00~ 38 | STC*F2:88:QC*20050612~ 39 | DTP*472*D8*20050501~ 40 | SE*38*0001~ 41 | GE*1*1~ 42 | IEA*1*000000907~ -------------------------------------------------------------------------------- /demo-file/demo.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | N1*P5**FI*999888777~ 6 | N1*IN**FI*654456654~ 7 | INS*Y*18*021*20*A***FT~ 8 | REF*0F*123456789~ 9 | REF*1L*123456001~ 10 | DTP*356*D8*19960523~ 11 | NM1*IL*1*DOE*JOHN*P***34*123456789~ 12 | PER*IP**HP*7172343334*WP*7172341240~ 13 | N3*100 MARKET ST*APT 30~ 14 | N4*CAMP HILL*PA*17011**CY*CUMBERLAND~ 15 | DMG*D8*19400816*M~ 16 | HD*021**HLT~ 17 | DTP*348*D8*19960601~ 18 | HD*021**VIS~ 19 | DTP*348*D8*19960601~ 20 | SE*18*0001~ 21 | GE*1*20213~ 22 | IEA*1*000010216~ -------------------------------------------------------------------------------- /demo-file/demo.835: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HP*000000005*54321*20131031*1147*1*X*005010X221A1~ 3 | ST*835*1234~ 4 | BPR*C*150000.00*C*ACH*CTX*01*99999992*DA*123456*1512345678**01*999988880*DA*98765*20020913~ 5 | TRN*1*12345*1512345678~ 6 | DTM*405*20020916~ 7 | N1*PR*INSURANCE COMPANY OF TIMBUCKTU~ 8 | N3*1 MAIN STREET~ 9 | N4*TIMBUCKTU*AK*89111~ 10 | REF*2U*999~ 11 | N1*PE*REGIONAL HOPE HOSPITAL*XX*6543210903~ 12 | LX*110212~ 13 | TS3*6543210903*11*20021231*1*211366.97****138018.40**73348.57~ 14 | TS2*2178.45*1919.71**56.82*197.69*4.23~ 15 | CLP*666123*1*211366.97*138018.40**MA*1999999444444*11*1~ 16 | CAS*CO*45*73348.57~ 17 | NM1*QC*1*JONES*SAM*O***HN*666666666A~ 18 | MIA*0***138018.40~ 19 | DTM*232*20020816~ 20 | DTM*233*20020824~ 21 | QTY*CA*8.00~ 22 | LX*130212~ 23 | TS3*6543210909*13*19961231*1*15000.00****11980.33**3019.67~ 24 | CLP*777777*1*15000.00*11980.33**MB*1999999444445*13*1~ 25 | CAS*CO*45*3019.67~ 26 | NM1*QC*1*BORDER*LIZ*E***HN*996669999B~ 27 | MOA***MA02~ 28 | DTM*232*20020512~ 29 | PLB*6543210903*20021231*CV:CP*-1.27~ 30 | SE*28*1234~ 31 | GE*1*1~ 32 | IEA*1*000000907~ -------------------------------------------------------------------------------- /demo-file/demo.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0021*005010X222A2~ 4 | BHT*0019*00*244579*20061015*1023*CH~ 5 | NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~ 6 | PER*IC*JERRY*TE*3055552222*EX*231~ 7 | NM1*40*2*KEY INSURANCE COMPANY*****46*66783JJT~ 8 | HL*1**20*1~ 9 | PRV*BI*PXC*203BF0100Y~ 10 | NM1*85*2*BEN KILDARE SERVICE*****XX*1912301953~ 11 | N3*234 SEAWAY ST~ 12 | N4*MIAMI*FL*331110000~ 13 | REF*EI*587654321~ 14 | NM1*87*2~ 15 | N3*2345 OCEAN BLVD~ 16 | N4*MIAMI*FL*33111~ 17 | HL*2*1*22*1~ 18 | SBR*P**2222-SJ******CI~ 19 | NM1*IL*1*SMITH*JANE****MI*JS00111223333~ 20 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~ 21 | REF*G2*KA6663~ 22 | HL*3*2*23*0~ 23 | PAT*19~ 24 | NM1*QC*1*SMITH*TED~ 25 | N3*236 N MAIN ST~ 26 | N4*MIAMI*FL*33413~ 27 | DMG*D8*19730501*M~ 28 | CLM*26463774*100***11:B:1*Y*A*Y*I~ 29 | REF*D9*17312345600006351~ 30 | HI*BK:0340*BF:V7389~ 31 | LX*1~ 32 | SV1*HC:99213*40*UN*1.0***1~ 33 | DTP*472*D8*20061003~ 34 | LX*2~ 35 | SV1*HC:87070*15*UN*1.0***1~ 36 | DTP*472*D8*20061003~ 37 | LX*3~ 38 | SV1*HC:99214*35*UN*1.0***2~ 39 | DTP*472*D8*20061010~ 40 | LX*4~ 41 | SV1*HC:86663*10*UN*1.0***2~ 42 | DTP*472*D8*20061010~ 43 | SE*41*0021~ 44 | GE*1*1~ 45 | IEA*1*000000907~ 46 | -------------------------------------------------------------------------------- /demo-file/demo.837i: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X223A3~ 3 | ST*837*987654*005010X223A3~ 4 | BHT*0019*00*0123*19960918*0932*CH~ 5 | NM1*41*2*JONES HOSPITAL*****46*12345~ 6 | PER*IC*JANE DOE*TE*9005555555~ 7 | NM1*40*2*MEDICARE*****46*00120~ 8 | HL*1**20*1~ 9 | PRV*BI*PXC*203BA0200N~ 10 | NM1*85*2*JONES HOSPITAL*****XX*9876540809~ 11 | N3*225 MAIN STREET BARKLEY BUILDING~ 12 | N4*CENTERVILLE*PA*17111~ 13 | REF*EI*567891234~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*******MB~ 16 | NM1*IL*1*DOE*JON*T***MI*030005074A~ 17 | N3*125 CITY AVENUE~ 18 | N4*CENTERVILLE*PA*17111~ 19 | DMG*D8*19261111*M~ 20 | NM1*PR*2*MEDICARE B*****PI*00435~ 21 | REF*G2*330127~ 22 | CLM*756048Q*89.93***14:A:1*Y*A*Y*Y~ 23 | DTP*434*D8*19960911~ 24 | CL1*3**01~ 25 | HI*BK:3669~ 26 | HI*BF:4019*BF:79431~ 27 | HI*BH:A1:D8:19261111*BH:A2:D8:19911101*BH:B1:D8:19261111*BH:B2:D8:19870101~ 28 | HI*BE:A2:::15.31~ 29 | HI*BG:09~ 30 | NM1*71*1*JONES*JOHN*J~ 31 | REF*1G*B99937~ 32 | SBR*S*01*351630*STATE TEACHERS*****CI~ 33 | OI***Y***Y~ 34 | NM1*IL*1*DOE*JANE*S***MI*222004433~ 35 | N3*125 CITY AVENUE~ 36 | N4*CENTERVILLE*PA*17111~ 37 | NM1*PR*2*STATE TEACHERS*****PI*1135~ 38 | LX*1~ 39 | SV2*0305*HC:85025*13.39*UN*1.00~ 40 | DTP*472*D8*19960911~ 41 | LX*2~ 42 | SV2*0730*HC:93005*76.54*UN*3.00~ 43 | DTP*472*D8*19960911~ 44 | SE*42*987654~ 45 | GE*1*1~ 46 | IEA*1*000000907~ -------------------------------------------------------------------------------- /logging.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | disable_existing_loggers: false 3 | formatters: 4 | simple: 5 | format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' 6 | handlers: 7 | console: 8 | class: logging.StreamHandler 9 | level: INFO 10 | formatter: simple 11 | stream: ext://sys.stdout 12 | root: 13 | level: INFO 14 | handlers: [console] 15 | loggers: 16 | x12: 17 | level: INFO 18 | uvicorn: 19 | level: INFO -------------------------------------------------------------------------------- /push-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # push-image.sh 3 | # push-image.sh builds and pushes the multi-platform linuxforhealth/x12 image to an image repository. 4 | # 5 | # Pre-Requisites: 6 | # - The script environment is authenticated to the target image repository. 7 | # - The project has been built and a wheel exists in /dist. 8 | # 9 | # Usage: 10 | # ./push-image [image_tag] [image_url] [platforms] 11 | # 12 | # Positional Script arguments: 13 | # IMAGE_TAG - Aligns with the project's semantic version. Required. 14 | # IMAGE_URL - The image's URL. Defaults to ghcr.io/linuxforhealth/x12. 15 | # PLATFORMS - String containing the list of platforms. Defaults to linux/amd64,linux/arm64,linux/s390x. 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | if [[ $# == 0 ]] 22 | then 23 | echo "Missing required argument IMAGE_TAG" 24 | echo "Usage: ./push-image.sh [image tag] [image url] [platforms]" 25 | exit 1; 26 | fi 27 | 28 | IMAGE_TAG=$1 29 | IMAGE_URL="${2:-ghcr.io/linuxforhealth/x12}" 30 | PLATFORMS="${3:-linux/amd64,linux/arm64,linux/s390x}" 31 | 32 | docker buildx build \ 33 | --pull \ 34 | --push \ 35 | --platform "$PLATFORMS" \ 36 | --build-arg X12_SEM_VER="$IMAGE_TAG" \ 37 | --tag "$IMAGE_URL":"$IMAGE_TAG" \ 38 | --tag "$IMAGE_URL":latest . 39 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>-42", 4 | "wheel"] 5 | build-backend = "setuptools.build_meta" 6 | 7 | [tool.black] 8 | multi_line_output = 3 9 | include_trailing_comma = true 10 | force_grid_wrap = 0 11 | use_parentheses = true 12 | line-length = 88 13 | target-version = ['py38'] 14 | include = '\.pyi?$' 15 | exclude = ''' 16 | ( 17 | /( 18 | | \.git 19 | | \.pytest_cache 20 | )/ 21 | ) 22 | ''' -------------------------------------------------------------------------------- /repo-docs/CONTAINER_SUPPORT.md: -------------------------------------------------------------------------------- 1 | # LinuxForHealth X12 Container Support 2 | 3 | The LinuxForHealth X12 API component supports a containerized execution environment. This guide provides an overview of 4 | how to build and run the image. 5 | 6 | ## Image Build 7 | 8 | ### Supported Build Arguments 9 | 10 | 11 | | Build Argument | Description | Default Value | 12 | |----------------|------------------------------------------------|---------------| 13 | | X12_SEM_VER | The current X12 library sematic version number | None | 14 | | LFH_USER_ID | The user id used for the LFH container user | 1000 | 15 | | LFH_GROUP_ID | The group id used for the LFH container group | 1000 | 16 | 17 | The `X12_SEM_VER`. This argument should align with the current `linuxforhealth.x12.__version__` attribute value and the 18 | desired image tag. 19 | 20 | ```shell 21 | docker build --build-arg X12_SEM_VER=0.57.0 -t x12:0.57.0 . 22 | ``` 23 | 24 | ## Run Container 25 | 26 | ### Supported Environment Configurations 27 | 28 | | Build Argument | Description | Default Value | 29 | |------------------|-----------------------------------|---------------| 30 | | X12_UVICORN_HOST | The container's listening address | 0.0.0.0 | 31 | 32 | 33 | The following command launches the LinuxForHealth X12 container: 34 | ```shell 35 | docker run --name lfh-x12 --rm -d -p 5000:5000 ghcr.io/linuxforhealth/x12:latest 36 | ``` 37 | 38 | To access the Open API UI, browse to http://localhost:5000/docs 39 | 40 | Finally, to stop and remove the container: 41 | ```shell 42 | docker stop lfh-x12 43 | ``` 44 | -------------------------------------------------------------------------------- /repo-docs/testing-transactions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/repo-docs/testing-transactions.png -------------------------------------------------------------------------------- /repo-docs/transaction-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/repo-docs/transaction-package.png -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = linuxforhealth-x12 3 | version = attr: linuxforhealth.x12.__version__ 4 | description = LinuxForHealth x12 streams ASC 5010 X12 health care transactions into Pydantic Models for a pleasant pythonic parsing experience! Integration options include REST endpoints, CLI (command line), or direct access using the Python SDK 5 | long_description: file: README.md 6 | long_description_content_type = text/markdown 7 | license: Apache 2.0 8 | classifiers = 9 | Development Status :: 4 - Beta 10 | License :: OSI Approved :: Apache Software License 11 | Operating System :: OS Independent 12 | Programming Language :: Python :: 3.8 13 | Programming Language :: Python :: 3.9 14 | Intended Audience :: Healthcare Industry 15 | Intended Audience :: Developers 16 | 17 | [options] 18 | install_requires = 19 | pydantic >= 1.9 20 | python-dotenv >= 0.19.0 21 | package_dir= 22 | =src 23 | packages=find_namespace: 24 | python_requires = >= 3.8 25 | zip_safe = False 26 | 27 | [options.packages.find] 28 | where=src 29 | 30 | [options.entry_points] 31 | console_scripts = 32 | lfhx12 = linuxforhealth.x12.cli:main 33 | black = black:patched_main 34 | lfhx12-api = linuxforhealth.x12.api:run_server 35 | 36 | [options.extras_require] 37 | api = fastapi>=0.78.0; uvicorn[standard]>=0.17.0; requests>=2.27.0 38 | dev = black>=22.3.0; pre-commit>=2.14.1;pytest>=7.1.0 -------------------------------------------------------------------------------- /src/linuxforhealth/x12/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | x12 package 3 | 4 | Root package for LinuxForHealth X12 library. 5 | """ 6 | from dotenv import load_dotenv 7 | 8 | load_dotenv() 9 | 10 | __version__ = "0.57.0" 11 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/api.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI, Header, HTTPException, Request, status 2 | from fastapi.exceptions import RequestValidationError 3 | from fastapi.responses import JSONResponse 4 | from fastapi.encoders import jsonable_encoder 5 | import uvicorn 6 | from typing import Dict, Optional, List 7 | from linuxforhealth.x12.config import get_x12_api_config, X12ApiConfig 8 | from linuxforhealth.x12.io import X12SegmentReader, X12ModelReader 9 | from linuxforhealth.x12.parsing import X12ParseException 10 | from pydantic import ValidationError, BaseModel, Field 11 | 12 | app = FastAPI() 13 | 14 | 15 | @app.exception_handler(RequestValidationError) 16 | async def request_validation_handler(request: Request, exc: RequestValidationError): 17 | return JSONResponse( 18 | status_code=status.HTTP_400_BAD_REQUEST, 19 | content=jsonable_encoder( 20 | {"detail": "Invalid request. Expected {'x12': }"} 21 | ), 22 | ) 23 | 24 | 25 | class X12Request(BaseModel): 26 | """ 27 | The X12 Request object 28 | """ 29 | 30 | x12: str = Field(description="The X12 payload to process, conveyed as a string") 31 | 32 | class Config: 33 | schema_extra = { 34 | "example": { 35 | "x12": "ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~GS*HS*000000005*54321*20131031*1147*1*X*005010X279A1~ST*270*1234*005010X279A1~BHT*0022*13*10001234*20060501*1319~HL*1**20*1~NM1*PR*2*ABC COMPANY*****PI*842610001~HL*2*1*21*1~NM1*1P*2*BONE AND JOINT CLINIC*****SV*2000035~HL*3*2*22*0~TRN*1*93175-012547*9877281234~NM1*IL*1*SMITH*ROBERT****MI*11122333301~DMG*D8*19430519~DTP*291*D8*20060501~EQ*30~SE*13*1234~GE*1*1~IEA*1*000000907~", 36 | } 37 | } 38 | 39 | 40 | @app.post("/x12") 41 | async def post_x12( 42 | x12_request: X12Request, 43 | lfh_x12_response: Optional[str] = Header(default="models"), 44 | ) -> List[Dict]: 45 | """ 46 | Processes an incoming X12 payload. 47 | 48 | Requests are submitted as: 49 | 50 | { 51 | "x12": 52 | } 53 | 54 | The response payload is a JSON document containing either the "raw" X12 segments, or a rich 55 | X12 domain model. The response type defaults to the domain model and is configured using the 56 | LFH-X12-RESPONSE header. Valid values include: "segments" or "models". 57 | 58 | :param x12_request: The X12 request model/object. 59 | :param lfh_x12_response: A header value used to drive processing. 60 | 61 | :return: The X12 response - List[List] (segments) or List[Dict] (models) 62 | """ 63 | if lfh_x12_response.lower() not in ("models", "segments"): 64 | lfh_x12_response = "models" 65 | 66 | try: 67 | if lfh_x12_response.lower() == "models": 68 | with X12ModelReader(x12_request.x12) as r: 69 | api_results = [m.dict() for m in r.models()] 70 | else: 71 | with X12SegmentReader(x12_request.x12) as r: 72 | api_results = [] 73 | for segment_name, segment in r.segments(): 74 | segment_data = { 75 | f"{segment_name}{str(i).zfill(2)}": v 76 | for i, v in enumerate(segment) 77 | } 78 | api_results.append(segment_data) 79 | 80 | except (X12ParseException, ValidationError) as error: 81 | raise HTTPException( 82 | status_code=status.HTTP_400_BAD_REQUEST, 83 | detail="Invalid X12 payload. To troubleshoot please run the LFH X12 CLI", 84 | ) 85 | else: 86 | return api_results 87 | 88 | 89 | def run_server(): 90 | """Launches the API server""" 91 | config: X12ApiConfig = get_x12_api_config() 92 | 93 | uvicorn_params = { 94 | "app": config.x12_uvicorn_app, 95 | "host": config.x12_uvicorn_host, 96 | "port": config.x12_uvicorn_port, 97 | "reload": config.x12_uvicorn_reload, 98 | } 99 | 100 | uvicorn.run(**uvicorn_params) 101 | 102 | 103 | if __name__ == "__main__": 104 | run_server() 105 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/cli.py: -------------------------------------------------------------------------------- 1 | """ 2 | cli.py 3 | 4 | The LinuxForHealth X12 Command Line Interface. 5 | 6 | Usage: 7 | pipenv run cli --help 8 | 9 | """ 10 | 11 | import argparse 12 | import json 13 | from .encoding import X12JsonEncoder 14 | from .io import X12SegmentReader, X12ModelReader 15 | from typing import List 16 | 17 | 18 | CLI_DESCRIPTION = """ 19 | The LinuxForHealth X12 CLI parses and validates X12 messages. 20 | Messages are returned in JSON format in either a segment or transactional format. 21 | """ 22 | 23 | 24 | def _create_arg_parser(): 25 | """ 26 | Creates the Argument Parser for the CLI utility. 27 | :return: ArgumentParser 28 | """ 29 | 30 | parser = argparse.ArgumentParser( 31 | prog="LinuxForHealth X12", 32 | description=CLI_DESCRIPTION, 33 | formatter_class=argparse.RawTextHelpFormatter, 34 | ) 35 | 36 | mode_group = parser.add_mutually_exclusive_group() 37 | mode_group.add_argument( 38 | "-s", "--segment", help="Returns X12 segments", action="store_true" 39 | ) 40 | mode_group.add_argument( 41 | "-m", "--model", help="Returns X12 models", action="store_true" 42 | ) 43 | 44 | parser.add_argument( 45 | "-x", 46 | "--exclude", 47 | help="Exclude fields set to None in model output", 48 | action="store_true", 49 | ) 50 | parser.add_argument( 51 | "-p", "--pretty", help="Pretty print output", action="store_true" 52 | ) 53 | parser.add_argument( 54 | "-d", 55 | "--delimiters", 56 | help="Include X12 delimiters in output. Only valid when -m (model mode) is used", 57 | action="store_true", 58 | ) 59 | 60 | parser.add_argument("file", help="The path to a ASC X12 file") 61 | 62 | return parser 63 | 64 | 65 | def _parse_segments(file_path: str) -> List: 66 | """ 67 | Parses X12 segments from an input file. 68 | 69 | :param file_path: The path to the X12 file. 70 | :return: List of X12 segments 71 | """ 72 | 73 | with X12SegmentReader(file_path) as r: 74 | segments = [] 75 | 76 | for segment_name, segment in r.segments(): 77 | segment_data = { 78 | f"{segment_name}{str(i).zfill(2)}": v for i, v in enumerate(segment) 79 | } 80 | segments.append(segment_data) 81 | return segments 82 | 83 | 84 | def _parse_models( 85 | file_path: str, exclude_none: bool = False, output_delimiters: bool = False 86 | ) -> List: 87 | """ 88 | Parses a X12 segment model from a X12 input file. 89 | 90 | :param file_path: The path to the X12 file. 91 | :param exclude_none: Excludes fields set to None from the model output. 92 | :param output_delimiters: When True delimiter metadata is included with each segment. 93 | :return: List of X12 models 94 | """ 95 | 96 | with X12ModelReader(file_path, output_delimiters=output_delimiters) as r: 97 | # if field is not set it will be omitted 98 | # fields explicitly set to None will be included if exclude_none is True 99 | export_params = { 100 | "exclude_unset": True, 101 | "exclude_none": exclude_none, 102 | } 103 | 104 | models = [] 105 | 106 | for m in r.models(): 107 | model_data = m.dict(**export_params) 108 | models.append(model_data) 109 | return models 110 | 111 | 112 | def main(): 113 | """ 114 | CLI module entrypoint 115 | """ 116 | parser = _create_arg_parser() 117 | args = parser.parse_args() 118 | 119 | if args.segment and args.delimiters: 120 | parser.error("-s (segment mode) does not support -d (output delimiters)") 121 | 122 | if args.segment: 123 | x12_data = _parse_segments(args.file) 124 | else: 125 | x12_data = _parse_models(args.file, args.exclude, args.delimiters) 126 | 127 | json_opts = {"cls": X12JsonEncoder} 128 | 129 | if args.pretty: 130 | json_opts["indent"] = 4 131 | 132 | x12_json = json.dumps(x12_data, **json_opts) 133 | print(x12_json) 134 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/config.py: -------------------------------------------------------------------------------- 1 | """ 2 | config.py 3 | 4 | LinuxForHealth X12 Configuration Settings and specification/format "constants" 5 | """ 6 | from enum import IntEnum 7 | from functools import lru_cache 8 | from pydantic import BaseSettings, Field 9 | 10 | 11 | class IsaDelimiters(IntEnum): 12 | """ 13 | The indices used to parse the delimiters conveyed in the ISA segment 14 | """ 15 | 16 | COMPONENT_SEPARATOR = 104 17 | ELEMENT_SEPARATOR = 3 18 | REPETITION_SEPARATOR = 82 19 | SEGMENT_LENGTH = 106 20 | SEGMENT_TERMINATOR = 105 21 | 22 | 23 | class TransactionSetVersionIds(IntEnum): 24 | """ 25 | The indices used to parse transaction set version identifiers. 26 | Transaction set version identifiers are distributed across the ST (transaction set header) and GS (functional group 27 | header) segments. 28 | """ 29 | 30 | # ST01 31 | TRANSACTION_SET_CODE = 1 32 | # GS08 33 | IMPLEMENTATION_VERSION = 8 34 | # ST03 35 | FALLBACK_IMPLEMENTATION_VERSION = 3 36 | 37 | 38 | class X12VersionFields(IntEnum): 39 | """ 40 | Positional field indices for X12 version fields 41 | """ 42 | 43 | ISA_CONTROL_VERSION = 12 44 | GS_FUNCTIONAL_CODE = 1 45 | GS_FUNCTIONAL_VERSION = 8 46 | ST_TRANSACTION_CODE = 1 47 | ST_TRANSACTION_CONTROL = 2 48 | 49 | 50 | class X12Config(BaseSettings): 51 | """ 52 | X12 Parsing and Validation Configurations 53 | """ 54 | 55 | x12_character_set: str = Field(regex="^(BASIC|EXTENDED)$", default="BASIC") 56 | x12_reader_buffer_size: int = 1024000 57 | 58 | class Config: 59 | case_sensitive = False 60 | 61 | 62 | @lru_cache 63 | def get_config() -> "X12Config": 64 | """Returns the X12Config""" 65 | return X12Config() 66 | 67 | 68 | class X12ApiConfig(BaseSettings): 69 | """ 70 | Settings for optional Fast API "server" components. 71 | """ 72 | 73 | x12_uvicorn_app: str = Field( 74 | "linuxforhealth.x12.api:app", description="The path the ASGI app object" 75 | ) 76 | x12_uvicorn_host: str = Field( 77 | "0.0.0.0", description="The ASGI listening address (host)" 78 | ) 79 | x12_uvicorn_port: int = Field(5000, description="The ASGI listening port (host)") 80 | x12_uvicorn_reload: bool = Field( 81 | False, description="Set to True to support hot reloads. Defaults to False" 82 | ) 83 | 84 | 85 | @lru_cache 86 | def get_x12_api_config() -> "X12ApiConfig": 87 | """Returns the X12ApiConfig""" 88 | return X12ApiConfig() 89 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/encoding.py: -------------------------------------------------------------------------------- 1 | """ 2 | encoding.py 3 | 4 | Custom JSON Encoder used to support data types not included in the JSON Specification. 5 | """ 6 | from typing import Any 7 | from json import JSONEncoder 8 | import datetime 9 | import uuid 10 | import base64 11 | import decimal 12 | 13 | 14 | class X12JsonEncoder(JSONEncoder): 15 | """ 16 | Provides additional encoding support for the following types: 17 | - UUID fields 18 | - date, datetime, and time fields 19 | - byte fields 20 | - Decimal fields 21 | """ 22 | 23 | def default(self, o: Any) -> Any: 24 | """ 25 | Overridden to customize the encoding process. 26 | :param o: The current object to encode 27 | """ 28 | if isinstance(o, (datetime.date, datetime.datetime, datetime.time)): 29 | return o.isoformat() 30 | elif isinstance(o, uuid.UUID): 31 | return str(o) 32 | elif isinstance(o, bytes): 33 | return base64.b64encode(o).decode() 34 | elif isinstance(o, decimal.Decimal): 35 | return float(o) 36 | else: 37 | return super().default(o) 38 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/support.py: -------------------------------------------------------------------------------- 1 | """ 2 | support.py 3 | 4 | Convenience functions for X12 Processing. 5 | """ 6 | import datetime 7 | import functools 8 | import os 9 | from typing import Union, Dict 10 | 11 | from pydantic import validator, BaseModel 12 | 13 | from .config import IsaDelimiters 14 | 15 | # maps a X12 transaction implementation version to the latest version in the "major" version 16 | X12_IMPLEMENTATION_VERSIONS = { 17 | # benefit enrollment and maintenance 18 | "005010X220": "005010X220A1", 19 | "005010X220A1": "005010X220A1", 20 | # claims status 21 | "005010X212": "005010X212", 22 | # claim payment 23 | "005010X221": "005010X221A1", 24 | "005010X221A1": "005010X221A1", 25 | # eligibility inquiry 26 | "005010X279": "005010X279A1", 27 | "005010X279A1": "005010X279A1", 28 | # institutional claim 29 | "004010X096": "004010X096A1", 30 | "004010X096A1": "004010X096A1", 31 | "005010X223": "005010X223A3", 32 | "005010X223A1": "005010X223A3", 33 | "005010X223A2": "005010X223A3", 34 | "005010X223A3": "005010X223A3", 35 | # professional claim 36 | "004010X098": "004010X098A1", 37 | "004010X098A1": "004010X098A1", 38 | "005010X222": "005010X222A2", 39 | "005010X222A1": "005010X222A2", 40 | "005010X222A2": "005010X222A2", 41 | } 42 | 43 | 44 | def get_latest_implementation_version(requested_version: str) -> str: 45 | """ 46 | Returns the latest implementation version for a requested version. 47 | For example, the claim payment specification includes the following versions: 005010X221 and 005010X221A1. 48 | 49 | get_latest_implementation_version("005010X221") returns "005010X221A1" 50 | get_latest_implementation_version("005010X221A1") returns "005010X221A1" 51 | 52 | :param requested_version: The requested version used for lookup. 53 | :returns: The latest implementation version 54 | :raises: KeyError if the requested version is not supported 55 | 56 | """ 57 | if requested_version not in X12_IMPLEMENTATION_VERSIONS: 58 | raise KeyError( 59 | f"Unable to match {requested_version} to a specification guide. {requested_version} is not supported" 60 | ) 61 | return X12_IMPLEMENTATION_VERSIONS[requested_version] 62 | 63 | 64 | def is_x12_data(input_data: str) -> bool: 65 | """ 66 | Returns True if the input data appears to be a X12 message. 67 | 68 | :param input_data: Input data to evaluate 69 | :return: True if the input data is a x12 message, otherwise False 70 | """ 71 | 72 | return input_data.startswith("ISA") if input_data else False 73 | 74 | 75 | def is_x12_file(file_path: str) -> bool: 76 | """ 77 | Returns true if the file path exists and is a x12 file. 78 | Environment and user variables are expanded within the file path. 79 | 80 | :param file_path: The file path to test. 81 | :return: True if the file path is a x12 file, otherwise false 82 | """ 83 | 84 | if not file_path: 85 | return False 86 | 87 | expanded_path = os.path.expandvars(os.path.expanduser(file_path)) 88 | if not os.path.exists(expanded_path) or os.path.isdir(expanded_path): 89 | return False 90 | 91 | with (open(expanded_path, "r")) as f: 92 | f.seek(0) 93 | # ISA segment is first 106 characters 94 | isa_segment = f.read(IsaDelimiters.SEGMENT_LENGTH) 95 | return is_x12_data(isa_segment) 96 | 97 | 98 | def parse_interchange_date(date_string: str) -> datetime.date: 99 | """Parses a datetime.date from date fields in the ISA (interchange) segment""" 100 | 101 | return datetime.datetime.strptime(date_string, "%y%m%d").date() 102 | 103 | 104 | def parse_x12_date(date_string: str) -> Union[datetime.date, datetime.datetime, None]: 105 | """Parses a datetime.date or datetime.datetime from date fields in X12 transaction segments""" 106 | parsed_date = None 107 | 108 | if not date_string: 109 | return parsed_date 110 | 111 | if len(date_string) == 8: 112 | # date 113 | parsed_date = datetime.datetime.strptime(date_string, "%Y%m%d").date() 114 | elif len(date_string) == 12: 115 | # date and time 116 | parsed_date = datetime.datetime.strptime(date_string, "%Y%m%d%H%M") 117 | 118 | return parsed_date 119 | 120 | 121 | def count_segments(values: Dict) -> int: 122 | """ 123 | Returns the number of segment records contained within a X12 data model. 124 | 125 | The X12 data model's top level structure includes the following keys: 126 | * header 127 | * : 128 | * footer 129 | The top level keys may contain additional nested structures which contain "segment" keys such as 130 | nm1_segment, st_segment, dtp_segment, se_segment, etc. 131 | 132 | :param values: The validated model values 133 | :returns: the total segment count 134 | """ 135 | segment_count: int = 0 136 | 137 | for k, v in values.items(): 138 | if k.endswith("_segment") and isinstance(v, dict): 139 | segment_count += 1 140 | elif k.endswith("_segment") and isinstance(v, list): 141 | segment_count += len(v) 142 | elif isinstance(v, BaseModel): 143 | segment_count += count_segments(v.dict()) 144 | elif isinstance(v, list): 145 | for item in v: 146 | segment_count += ( 147 | count_segments(item.dict()) 148 | if hasattr(item, "dict") 149 | else count_segments(item) 150 | ) 151 | elif isinstance(v, dict): 152 | segment_count += count_segments(v) 153 | 154 | return segment_count 155 | 156 | 157 | def parse_x12_major_version(x12_implementation_version) -> str: 158 | """ 159 | Parses the x12 major version from an implementation version string. 160 | If the version is invalid, an empty string is returned. 161 | 162 | Example: 163 | x = parse_x12_major_version("005010X279A1") 164 | print(x) 165 | # prints 5010 166 | 167 | x = parse_x12_major_version("00501") 168 | print(x) 169 | # prints "" 170 | 171 | :param x12_implementation_version: The X12 implementation version typically conveyed in ST03 172 | :returns: The x12 major version or an empty string 173 | """ 174 | if x12_implementation_version is None or len(x12_implementation_version) < 6: 175 | return "" 176 | 177 | return x12_implementation_version[2:6] 178 | 179 | 180 | # partial function used to "register" common field validator functions 181 | # common validator functions have the signature (cls, v, values) 182 | field_validator = functools.partial(validator, allow_reuse=True) 183 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v4010/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v4010/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v4010/validators.py: -------------------------------------------------------------------------------- 1 | """ 2 | validators.py 3 | 4 | Common/shared validators which may be reused in transaction sets. 5 | """ 6 | from pydantic import validator 7 | 8 | 9 | @validator("hierarchical_parent_id_number", allow_reuse=True) 10 | def validate_hl_parent_id(cls, field_value): 11 | """ 12 | Validates the top level HL segment to ensure that the segment does not have a parent id. 13 | This validation is utilized withing hierarchical transactions such as the 270/271 (eligibility) 14 | and 276/277 (claims status). 15 | """ 16 | if field_value: 17 | raise ValueError(f"invalid hierarchical_parent_id_number {field_value}") 18 | return field_value 19 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v4010/x12_837_004010X096A1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v4010/x12_837_004010X096A1/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v4010/x12_837_004010X096A1/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Professional Claims 837 004010X098A1 transaction set model. 5 | """ 6 | 7 | from linuxforhealth.x12.models import X12SegmentGroup 8 | from .loops import Header, Footer, Loop1000A, Loop1000B, Loop2000A 9 | from pydantic import Field, root_validator 10 | from typing import List 11 | from linuxforhealth.x12.validators import validate_segment_count 12 | 13 | 14 | class HealthCareClaimProfessional(X12SegmentGroup): 15 | """ 16 | The HealthCare Claim - Professional transaction model (837) 17 | """ 18 | 19 | header: Header 20 | loop_1000a: Loop1000A 21 | loop_1000b: Loop1000B 22 | loop_2000a: List[Loop2000A] = Field(min_items=1) 23 | footer: Footer 24 | 25 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 26 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v4010/x12_837_004010X098A1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v4010/x12_837_004010X098A1/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v4010/x12_837_004010X098A1/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Professional Claims 837 004010X098A1 transaction set model. 5 | """ 6 | 7 | from linuxforhealth.x12.models import X12SegmentGroup 8 | from .loops import Header, Footer, Loop1000A, Loop1000B, Loop2000A 9 | from pydantic import Field, root_validator 10 | from typing import List 11 | from linuxforhealth.x12.validators import validate_segment_count 12 | 13 | 14 | class HealthCareClaimProfessional(X12SegmentGroup): 15 | """ 16 | The HealthCare Claim - Professional transaction model (837) 17 | """ 18 | 19 | header: Header 20 | loop_1000a: Loop1000A 21 | loop_1000b: Loop1000B 22 | loop_2000a: List[Loop2000A] = Field(min_items=1) 23 | footer: Footer 24 | 25 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 26 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | v5010.py 3 | 4 | The v5010 module serves as the package root for X12 "5010" transaction implementations. 5 | Transaction implementations are stored in separate packages with the following structure: 6 | 7 | x12_[transaction_code]_[implementation_version] 8 | / loops.py - Transaction Loop Domain Models 9 | / parsing.py - Transaction Set Parser Implementation and Loop Parser Functions 10 | / segments.py - Specialized Segments for Loop Domain Models 11 | / transaction_set.py - Transaction Set Domain Model 12 | """ 13 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/validators.py: -------------------------------------------------------------------------------- 1 | """ 2 | validators.py 3 | 4 | Common/shared validators which may be reused in transaction sets. 5 | """ 6 | from pydantic import validator 7 | 8 | 9 | @validator("hierarchical_parent_id_number", allow_reuse=True) 10 | def validate_hl_parent_id(cls, field_value): 11 | """ 12 | Validates the top level HL segment to ensure that the segment does not have a parent id. 13 | This validation is utilized withing hierarchical transactions such as the 270/271 (eligibility) 14 | and 276/277 (claims status). 15 | """ 16 | if field_value: 17 | raise ValueError(f"invalid hierarchical_parent_id_number {field_value}") 18 | return field_value 19 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_270_005010X279A1/__init__.py: -------------------------------------------------------------------------------- 1 | from .transaction_set import EligibilityInquiry 2 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_270_005010X279A1/loops.py: -------------------------------------------------------------------------------- 1 | """ 2 | loops.py 3 | 4 | Models the loops, or logical segment groupings, for the Eligibility 270 005010X279A1 transaction set. 5 | The Eligibility Transaction set organizes loops into a hierarchical and nested model. 6 | 7 | - Header 8 | - Loop 2000A (Information Source) 9 | -- Loop 2100A (Information Source Name) 10 | -- Loop 2000B (Information Receiver) 11 | --- Loop 2100B (Information Receiver Name) 12 | --- Loop 2000C (Subscriber) 13 | --- Loop 2100C (Subscriber Name) 14 | --- Loop 2110C (Subscriber Eligibility) 15 | --- Loop 2000D (Dependent) 16 | --- Loop 2100D (Dependent Name) 17 | --- Loop 2110D (Dependent Eligibility) 18 | -- Footer 19 | 20 | The Header and Footer components are not "loops" per the specification, but are included to standardize and simplify 21 | transactional modeling and processing. 22 | """ 23 | 24 | from linuxforhealth.x12.models import X12SegmentGroup 25 | from linuxforhealth.x12.v5010.segments import ( 26 | SeSegment, 27 | N3Segment, 28 | N4Segment, 29 | TrnSegment, 30 | DmgSegment, 31 | HiSegment, 32 | ) 33 | from .segments import ( 34 | HeaderStSegment, 35 | HeaderBhtSegment, 36 | Loop2000DHlSegment, 37 | Loop2000CHlSegment, 38 | Loop2100BNm1Segment, 39 | Loop2000BHlSegment, 40 | Loop2100BRefSegment, 41 | Loop2100ANm1Segment, 42 | Loop2000AHlSegment, 43 | Loop2100CNm1Segment, 44 | Loop2100RefSegment, 45 | Loop2100CInsSegment, 46 | Loop2100DtpSegment, 47 | Loop2110EqSegment, 48 | Loop2110AmtSegment, 49 | Loop2110IiiSegment, 50 | Loop2110RefSegment, 51 | Loop2110DtpSegment, 52 | Loop2100DNm1Segment, 53 | Loop2100DInsSegment, 54 | Loop2100CPrvSegment, 55 | Loop2100BPrvSegment, 56 | ) 57 | from typing import List, Optional 58 | from pydantic import Field, root_validator 59 | from linuxforhealth.x12.validators import validate_duplicate_ref_codes 60 | 61 | 62 | class Header(X12SegmentGroup): 63 | """ 64 | Transaction Header Information 65 | """ 66 | 67 | st_segment: HeaderStSegment 68 | bht_segment: HeaderBhtSegment 69 | 70 | 71 | class Loop2110D(X12SegmentGroup): 72 | """ 73 | Loop 2110D Dependent Eligibility 74 | """ 75 | 76 | eq_segment: Optional[Loop2110EqSegment] 77 | amt_segment: Optional[List[Loop2110AmtSegment]] = Field(min_items=0, max_items=2) 78 | iii_segment: Optional[Loop2110IiiSegment] 79 | ref_segment: Optional[Loop2110RefSegment] 80 | dtp_segment: Optional[Loop2110DtpSegment] 81 | 82 | 83 | class Loop2100D(X12SegmentGroup): 84 | """ 85 | Loop 2100D - Dependent Name 86 | """ 87 | 88 | nm1_segment: Loop2100DNm1Segment 89 | ref_segment: Optional[List[Loop2100RefSegment]] = Field(min_items=0, max_items=9) 90 | n3_segment: Optional[N3Segment] 91 | n4_segment: Optional[N4Segment] 92 | prv_segment: Optional[Loop2100CPrvSegment] 93 | dmg_segment: Optional[DmgSegment] 94 | ins_segment: Optional[Loop2100DInsSegment] 95 | hi_segment: Optional[HiSegment] 96 | dtp_segment: Optional[Loop2100DtpSegment] 97 | loop_2110d: Loop2110D 98 | 99 | _validate_ref_segments = root_validator(allow_reuse=True)( 100 | validate_duplicate_ref_codes 101 | ) 102 | 103 | 104 | class Loop2000D(X12SegmentGroup): 105 | """ 106 | Loop 2000D - Dependent 107 | """ 108 | 109 | hl_segment: Loop2000DHlSegment 110 | trn_segment: Optional[List[TrnSegment]] = Field(min_items=0, max_items=2) 111 | loop_2100d: Loop2100D 112 | 113 | 114 | class Loop2110C(X12SegmentGroup): 115 | """ 116 | Loop2110C - Subscriber Eligibility 117 | """ 118 | 119 | eq_segment: Optional[Loop2110EqSegment] 120 | amt_segment: Optional[List[Loop2110AmtSegment]] = Field(min_items=0, max_items=2) 121 | iii_segment: Optional[Loop2110IiiSegment] 122 | ref_segment: Optional[Loop2110RefSegment] 123 | dtp_segment: Optional[Loop2110DtpSegment] 124 | 125 | 126 | class Loop2100C(X12SegmentGroup): 127 | """ 128 | Loop 2100C - Subscriber Name 129 | """ 130 | 131 | nm1_segment: Loop2100CNm1Segment 132 | ref_segment: Optional[List[Loop2100RefSegment]] = Field(min_items=0, max_items=9) 133 | n3_segment: Optional[N3Segment] 134 | n4_segment: Optional[N4Segment] 135 | prv_segment: Optional[Loop2100CPrvSegment] 136 | dmg_segment: Optional[DmgSegment] 137 | ins_segment: Optional[Loop2100CInsSegment] 138 | hi_segment: Optional[HiSegment] 139 | dtp_segment: Optional[Loop2100DtpSegment] 140 | loop_2110c: Optional[Loop2110C] 141 | 142 | _validate_ref_segments = root_validator(allow_reuse=True)( 143 | validate_duplicate_ref_codes 144 | ) 145 | 146 | 147 | class Loop2000C(X12SegmentGroup): 148 | """ 149 | Loop 2000C - Subscriber 150 | """ 151 | 152 | hl_segment: Loop2000CHlSegment 153 | trn_segment: Optional[List[TrnSegment]] = Field(min_items=0, max_items=2) 154 | loop_2100c: Loop2100C 155 | loop_2000d: Optional[List[Loop2000D]] = Field(min_items=0) 156 | 157 | 158 | class Loop2100B(X12SegmentGroup): 159 | """ 160 | Loop 2100B - Information Receiver Name 161 | """ 162 | 163 | nm1_segment: Loop2100BNm1Segment 164 | ref_segment: Optional[List[Loop2100BRefSegment]] 165 | n3_segment: Optional[N3Segment] 166 | n4_segment: Optional[N4Segment] 167 | prv_segment: Optional[Loop2100BPrvSegment] 168 | 169 | _validate_ref_segments = root_validator(allow_reuse=True)( 170 | validate_duplicate_ref_codes 171 | ) 172 | 173 | 174 | class Loop2000B(X12SegmentGroup): 175 | """ 176 | Loop 2000B - Information Receiver 177 | """ 178 | 179 | hl_segment: Loop2000BHlSegment 180 | loop_2100b: Loop2100B 181 | loop_2000c: List[Loop2000C] = Field(min_items=1) 182 | 183 | 184 | class Loop2100A(X12SegmentGroup): 185 | """ 186 | Loop 2100A - Information Source Name 187 | """ 188 | 189 | nm1_segment: Loop2100ANm1Segment 190 | 191 | 192 | class Loop2000A(X12SegmentGroup): 193 | """ 194 | Loop 2000A - Information Source 195 | The root node/loop for the 270 transaction 196 | 197 | """ 198 | 199 | hl_segment: Loop2000AHlSegment 200 | loop_2100a: Loop2100A 201 | loop_2000b: List[Loop2000B] = Field(min_items=1) 202 | 203 | 204 | class Footer(X12SegmentGroup): 205 | """ 206 | Transaction Footer Information 207 | """ 208 | 209 | se_segment: SeSegment 210 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_270_005010X279A1/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Eligibility 270 005010X279A1 transaction set model. 5 | """ 6 | 7 | from typing import List, Dict, Tuple 8 | 9 | from linuxforhealth.x12.models import X12SegmentGroup 10 | 11 | from .loops import Footer, Header, Loop2000A 12 | from pydantic import root_validator 13 | from linuxforhealth.x12.validators import validate_segment_count 14 | 15 | 16 | class EligibilityInquiry(X12SegmentGroup): 17 | """ 18 | The ASC X12 270 (EligibilityInquiry) transaction model. 19 | """ 20 | 21 | header: Header 22 | loop_2000a: List[Loop2000A] 23 | footer: Footer 24 | 25 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 26 | 27 | @root_validator 28 | def validate_subscriber_name(cls, values): 29 | """ 30 | Validates that the subscriber mame is present if the subscriber is a patient 31 | 32 | :param values: The raw, unvalidated transaction data. 33 | """ 34 | for info_source in values.get("loop_2000a", []): 35 | for info_receiver in info_source.loop_2000b: 36 | for subscriber in info_receiver.loop_2000c: 37 | child_code = subscriber.hl_segment.hierarchical_child_code 38 | first_name = subscriber.loop_2100c.nm1_segment.name_first 39 | 40 | if child_code == "0" and not first_name: 41 | raise ValueError( 42 | f"name_first is required when the subscriber is the patient" 43 | ) 44 | 45 | return values 46 | 47 | @root_validator 48 | def validate_subscriber_hierarchy_child_code(cls, values): 49 | """ 50 | Validates that a subscriber's hierarchy child code is set correctly based on the presence of a dependent loop. 51 | 52 | :param values: The raw, unvalidated transaction data. 53 | """ 54 | for info_source in values.get("loop_2000a", []): 55 | for info_receiver in info_source.loop_2000b: 56 | for subscriber in info_receiver.loop_2000c: 57 | child_code = subscriber.hl_segment.hierarchical_child_code 58 | 59 | if child_code == "1" and not subscriber.loop_2000d: 60 | raise ValueError( 61 | f"Invalid subscriber hierarchy code {child_code} no dependent record is present" 62 | ) 63 | return values 64 | 65 | @root_validator 66 | def validate_hierarchy_ids(cls, values): 67 | """ 68 | Validates the HL segments linkage in regards to the entire EligibilityInquiry transaction. 69 | Validations are limited to checks that are not covered within a segment or field scope. 70 | 71 | :param values: The raw, unvalidated transaction data. 72 | """ 73 | 74 | def get_ids(hl_segment: Dict) -> Tuple[int, int]: 75 | """returns tuple of (id, parent_id)""" 76 | id = hl_segment.hierarchical_id_number 77 | parent_id = hl_segment.hierarchical_parent_id_number 78 | return int(id) if id else 0, int(parent_id) if parent_id else 0 79 | 80 | for info_source in values.get("loop_2000a", []): 81 | # info source does not have a parent id, since it starts a new hierarchy - this is validated at the 82 | # segment level 83 | source_id, _ = get_ids(info_source.hl_segment) 84 | previous_id: int = source_id 85 | 86 | for info_receiver in info_source.loop_2000b: 87 | receiver_id, receiver_parent_id = get_ids(info_receiver.hl_segment) 88 | 89 | if receiver_parent_id != previous_id: 90 | raise ValueError(f"Invalid receiver parent id {receiver_parent_id}") 91 | 92 | if receiver_parent_id != source_id: 93 | raise ValueError( 94 | f"receiver parent id {receiver_parent_id} != source id {source_id}" 95 | ) 96 | 97 | previous_id = receiver_id 98 | 99 | for subscriber in info_receiver.loop_2000c: 100 | subscriber_id, subscriber_parent_id = get_ids(subscriber.hl_segment) 101 | 102 | if subscriber_parent_id != previous_id: 103 | raise ValueError( 104 | f"Invalid subscriber parent id {subscriber_parent_id}" 105 | ) 106 | 107 | if subscriber_parent_id != receiver_id: 108 | raise ValueError( 109 | f"subscriber parent id {subscriber_parent_id} != receiver id {receiver_id}" 110 | ) 111 | 112 | previous_id = subscriber_id 113 | 114 | if not subscriber.loop_2000d: 115 | continue 116 | 117 | for dependent in subscriber.loop_2000d: 118 | dependent_id, dependent_parent_id = get_ids( 119 | dependent.hl_segment 120 | ) 121 | 122 | if dependent_parent_id != previous_id: 123 | raise ValueError( 124 | f"Invalid dependent parent id {dependent_parent_id}" 125 | ) 126 | 127 | if dependent_parent_id != subscriber_id: 128 | raise ValueError( 129 | f"dependent parent id {dependent_parent_id} != subscriber id {subscriber_id}" 130 | ) 131 | 132 | previous_id = dependent_id 133 | return values 134 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_271_005010X279A1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v5010/x12_271_005010X279A1/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_271_005010X279A1/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Eligibility 271 005010X279A1 transaction set model. 5 | """ 6 | 7 | from typing import List, Dict, Tuple 8 | 9 | from linuxforhealth.x12.models import X12SegmentGroup 10 | 11 | from .loops import Footer, Header, Loop2000A 12 | from pydantic import root_validator 13 | from linuxforhealth.x12.validators import validate_segment_count 14 | 15 | 16 | class EligibilityBenefit(X12SegmentGroup): 17 | """ 18 | The ASC X12 271 (EligibilityBenefit) transaction model. 19 | """ 20 | 21 | header: Header 22 | loop_2000a: List[Loop2000A] 23 | footer: Footer 24 | 25 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 26 | 27 | @root_validator 28 | def validate_subscriber_name(cls, values): 29 | """ 30 | Validates that the subscriber mame is present if the subscriber is a patient 31 | 32 | :param values: The raw, unvalidated transaction data. 33 | """ 34 | for info_source in values.get("loop_2000a", []): 35 | for info_receiver in info_source.loop_2000b: 36 | info_receivers = info_receiver.loop_2000c or [] 37 | for subscriber in info_receivers: 38 | child_code = subscriber.hl_segment.hierarchical_child_code 39 | first_name = subscriber.loop_2100c.nm1_segment.name_first 40 | 41 | if child_code == "0" and not first_name: 42 | raise ValueError( 43 | f"name_first is required when the subscriber is the patient" 44 | ) 45 | 46 | return values 47 | 48 | @root_validator 49 | def validate_subscriber_hierarchy_child_code(cls, values): 50 | """ 51 | Validates that a subscriber's hierarchy child code is set correctly based on the presence of a dependent loop. 52 | 53 | :param values: The raw, unvalidated transaction data. 54 | """ 55 | for info_source in values.get("loop_2000a", []): 56 | for info_receiver in info_source.loop_2000b: 57 | info_receivers = info_receiver.loop_2000c or [] 58 | for subscriber in info_receivers: 59 | child_code = subscriber.hl_segment.hierarchical_child_code 60 | 61 | if child_code == "1" and not subscriber.loop_2000d: 62 | raise ValueError( 63 | f"Invalid subscriber hierarchy code {child_code} no dependent record is present" 64 | ) 65 | return values 66 | 67 | @root_validator 68 | def validate_hierarchy_ids(cls, values): 69 | """ 70 | Validates the HL segments linkage in regards to the entire EligibilityInquiry transaction. 71 | Validations are limited to checks that are not covered within a segment or field scope. 72 | 73 | :param values: The raw, unvalidated transaction data. 74 | """ 75 | 76 | def get_ids(hl_segment: Dict) -> Tuple[int, int]: 77 | """returns tuple of (id, parent_id)""" 78 | id = hl_segment.hierarchical_id_number 79 | parent_id = hl_segment.hierarchical_parent_id_number 80 | return int(id) if id else 0, int(parent_id) if parent_id else 0 81 | 82 | for info_source in values.get("loop_2000a", []): 83 | # info source does not have a parent id, since it starts a new hierarchy - this is validated at the 84 | # segment level 85 | source_id, _ = get_ids(info_source.hl_segment) 86 | previous_id: int = source_id 87 | 88 | for info_receiver in info_source.loop_2000b: 89 | receiver_id, receiver_parent_id = get_ids(info_receiver.hl_segment) 90 | 91 | if receiver_parent_id != previous_id: 92 | raise ValueError(f"Invalid receiver parent id {receiver_parent_id}") 93 | 94 | if receiver_parent_id != source_id: 95 | raise ValueError( 96 | f"receiver parent id {receiver_parent_id} != source id {source_id}" 97 | ) 98 | 99 | previous_id = receiver_id 100 | 101 | info_receivers = info_receiver.loop_2000c or [] 102 | for subscriber in info_receivers: 103 | subscriber_id, subscriber_parent_id = get_ids(subscriber.hl_segment) 104 | 105 | if subscriber_parent_id != previous_id: 106 | raise ValueError( 107 | f"Invalid subscriber parent id {subscriber_parent_id}" 108 | ) 109 | 110 | if subscriber_parent_id != receiver_id: 111 | raise ValueError( 112 | f"subscriber parent id {subscriber_parent_id} != receiver id {receiver_id}" 113 | ) 114 | 115 | previous_id = subscriber_id 116 | 117 | if not subscriber.loop_2000d: 118 | continue 119 | 120 | for dependent in subscriber.loop_2000d: 121 | dependent_id, dependent_parent_id = get_ids( 122 | dependent.hl_segment 123 | ) 124 | 125 | if dependent_parent_id != previous_id: 126 | raise ValueError( 127 | f"Invalid dependent parent id {dependent_parent_id}" 128 | ) 129 | 130 | if dependent_parent_id != subscriber_id: 131 | raise ValueError( 132 | f"dependent parent id {dependent_parent_id} != subscriber id {subscriber_id}" 133 | ) 134 | 135 | previous_id = dependent_id 136 | return values 137 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_276_005010X212/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v5010/x12_276_005010X212/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_276_005010X212/loops.py: -------------------------------------------------------------------------------- 1 | """ 2 | loops.py 3 | 4 | Models the loops, or logical segment groupings, for the Health Care Claim Status Request 276 005010X212 transaction set. 5 | The Health Care Claim Status Request organizes loops into a hierarchical and nested model. 6 | 7 | -- Header 8 | -- Loop 2000A (Information Source) 9 | -- Loop 2100A (Payer Name) 10 | -- Loop 2000B (Information Receiver) 11 | -- Loop 2100B (Information Receiver Name) 12 | -- Loop 2000C (Service Provider Detail) 13 | -- Loop 2100C (Provider Name) 14 | -- Loop 2000D (Subscriber Level) 15 | -- Loop 2100D (Subscriber Name) 16 | -- Loop 2200D (Claim Status Tracking Number) 17 | -- Loop 2210D (Service Line Information) 18 | -- Loop 2000E (Dependent Level) 19 | -- Loop 2100E (Dependent Name) 20 | -- Loop 2200E (Claim Status Tracking Number) 21 | -- Loop 2210E (Service Line Information) 22 | -- Footer 23 | 24 | The Subscriber and Dependent Claim Status and Service Line Loops share segment classes as the data structures 25 | are identical. 26 | """ 27 | from linuxforhealth.x12.models import X12SegmentGroup 28 | from .segments import ( 29 | HeaderStSegment, 30 | HeaderBhtSegment, 31 | Loop2000AHlSegment, 32 | Loop2100ANm1Segment, 33 | Loop2000BHlSegment, 34 | Loop2100BNm1Segment, 35 | Loop2000CHlSegment, 36 | Loop2100CNm1Segment, 37 | Loop2000DHlSegment, 38 | Loop2000DDmgSegment, 39 | Loop2100DNm1Segment, 40 | Loop2200DTrnSegment, 41 | Loop2200DRefSegment, 42 | Loop2200DAmtSegment, 43 | Loop2200DDtpSegment, 44 | Loop2210DSvcSegment, 45 | Loop2210DRefSegment, 46 | Loop2210DDtpSegment, 47 | Loop2000EHlSegment, 48 | Loop2100ENm1Segment, 49 | ) 50 | from linuxforhealth.x12.v5010.segments import SeSegment 51 | from typing import List, Optional 52 | from pydantic import Field 53 | 54 | 55 | class Header(X12SegmentGroup): 56 | """ 57 | Transaction Header Information 58 | """ 59 | 60 | st_segment: HeaderStSegment 61 | bht_segment: HeaderBhtSegment 62 | 63 | 64 | class Loop2210E(X12SegmentGroup): 65 | """ 66 | Dependent Claim Status Service Line Information 67 | The segment implementations from the Subscriber loop are used as the structure is the same. 68 | """ 69 | 70 | svc_segment: Loop2210DSvcSegment 71 | ref_segment: Optional[Loop2210DRefSegment] 72 | dtp_segment: Loop2210DDtpSegment 73 | 74 | 75 | class Loop2200E(X12SegmentGroup): 76 | """ 77 | Dependent Claim Status Tracking Number 78 | The segment implementations from the Subscriber loop are used as the structure is the same. 79 | """ 80 | 81 | trn_segment: Loop2200DTrnSegment 82 | ref_segment: Optional[List[Loop2200DRefSegment]] = Field(min_items=0, max_items=7) 83 | amt_segment: Optional[Loop2200DAmtSegment] 84 | dtp_segment: Optional[Loop2200DDtpSegment] 85 | loop_2210e: Optional[List[Loop2210E]] 86 | 87 | 88 | class Loop2100E(X12SegmentGroup): 89 | """ 90 | Dependent Name 91 | """ 92 | 93 | nm1_segment: Loop2100ENm1Segment 94 | 95 | 96 | class Loop2000E(X12SegmentGroup): 97 | """ 98 | Dependent Loop 99 | """ 100 | 101 | hl_segment: Loop2000EHlSegment 102 | dmg_segment: Loop2000DDmgSegment 103 | loop_2100e: Loop2100E 104 | loop_2200e: Optional[List[Loop2200E]] 105 | 106 | 107 | class Loop2210D(X12SegmentGroup): 108 | """ 109 | Subscriber Claim Status Service Line Information 110 | """ 111 | 112 | svc_segment: Loop2210DSvcSegment 113 | ref_segment: Optional[Loop2210DRefSegment] 114 | dtp_segment: Loop2210DDtpSegment 115 | 116 | 117 | class Loop2200D(X12SegmentGroup): 118 | """ 119 | Subscriber Claim Status Tracking Number 120 | """ 121 | 122 | trn_segment: Loop2200DTrnSegment 123 | ref_segment: Optional[List[Loop2200DRefSegment]] = Field(min_items=0, max_items=7) 124 | amt_segment: Optional[Loop2200DAmtSegment] 125 | dtp_segment: Optional[Loop2200DDtpSegment] 126 | loop_2210d: Optional[List[Loop2210D]] 127 | 128 | 129 | class Loop2100D(X12SegmentGroup): 130 | """ 131 | Loop 2100D Subscriber Name 132 | """ 133 | 134 | nm1_segment: Loop2100DNm1Segment 135 | 136 | 137 | class Loop2000D(X12SegmentGroup): 138 | """ 139 | Loop 2000D Subscriber 140 | """ 141 | 142 | hl_segment: Loop2000DHlSegment 143 | dmg_segment: Optional[Loop2000DDmgSegment] 144 | loop_2100d: Loop2100D 145 | loop_2200d: Optional[List[Loop2200D]] 146 | loop_2000e: Optional[List[Loop2000E]] 147 | 148 | 149 | class Loop2100C(X12SegmentGroup): 150 | """ 151 | Loop 2100C - Service Provider Name 152 | """ 153 | 154 | nm1_segment: Loop2100CNm1Segment 155 | 156 | 157 | class Loop2000C(X12SegmentGroup): 158 | """ 159 | Loop 2000C - Service Provider 160 | """ 161 | 162 | hl_segment: Loop2000CHlSegment 163 | loop_2100c: Loop2100C 164 | loop_2000d: List[Loop2000D] = Field(min_items=1) 165 | 166 | 167 | class Loop2100B(X12SegmentGroup): 168 | """ 169 | Loop 2100B - Information Receiver Name 170 | """ 171 | 172 | nm1_segment: Loop2100BNm1Segment 173 | 174 | 175 | class Loop2000B(X12SegmentGroup): 176 | """ 177 | Loop 2000B - Information Receiver 178 | """ 179 | 180 | hl_segment: Loop2000BHlSegment 181 | loop_2100b: Loop2100B 182 | loop_2000c: List[Loop2000C] = Field(min_items=1) 183 | 184 | 185 | class Loop2100A(X12SegmentGroup): 186 | """ 187 | Loop 2100A - Payer Name 188 | """ 189 | 190 | nm1_segment: Loop2100ANm1Segment 191 | 192 | 193 | class Loop2000A(X12SegmentGroup): 194 | """ 195 | Loop 2000A - Information Source 196 | """ 197 | 198 | hl_segment: Loop2000AHlSegment 199 | loop_2100a: Loop2100A 200 | loop_2000b: List[Loop2000B] = Field(min_items=1) 201 | 202 | 203 | class Footer(X12SegmentGroup): 204 | """ 205 | Transaction Footer Information 206 | """ 207 | 208 | se_segment: SeSegment 209 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_276_005010X212/segments.py: -------------------------------------------------------------------------------- 1 | """ 2 | segments.py 3 | 4 | Specialized segment models for the Health Care Claim Status Request 276 005010X212 transaction. 5 | """ 6 | from linuxforhealth.x12.v5010.segments import ( 7 | StSegment, 8 | BhtSegment, 9 | HlSegment, 10 | Nm1Segment, 11 | DmgSegment, 12 | TrnSegment, 13 | RefSegment, 14 | AmtSegment, 15 | DtpSegment, 16 | SvcSegment, 17 | ) 18 | from typing import Literal, Optional, Union 19 | from enum import Enum 20 | import datetime 21 | from decimal import Decimal 22 | 23 | 24 | class HeaderStSegment(StSegment): 25 | """ 26 | Customized ST segment for 837 transaction header 27 | """ 28 | 29 | transaction_set_identifier_code: Literal["276"] 30 | implementation_convention_reference: Literal["005010X212"] 31 | 32 | 33 | class HeaderBhtSegment(BhtSegment): 34 | """ 35 | Header BHT Segment 36 | """ 37 | 38 | hierarchical_structure_code: Literal["0010"] 39 | transaction_set_purpose_code: Literal["13"] 40 | transaction_type_code: Optional[str] 41 | 42 | 43 | class Loop2000AHlSegment(HlSegment): 44 | """ 45 | Information Source HL Segment 46 | """ 47 | 48 | hierarchical_level_code: Literal["20"] 49 | hierarchical_parent_id_number: Optional[str] 50 | hierarchical_child_code: Literal["1"] 51 | 52 | 53 | class Loop2100ANm1Segment(Nm1Segment): 54 | """ 55 | Payer Name 56 | """ 57 | 58 | class IdentificationCodeQualifier(str, Enum): 59 | """ 60 | Code values for NM108 61 | """ 62 | 63 | PAYOR_IDENTIFICATION = "PI" 64 | CMS_PLAN_ID = "XV" 65 | 66 | entity_identifier_code: Literal["PR"] 67 | entity_type_qualifier: Literal["2"] 68 | name_first: Optional[str] 69 | identification_code_qualifier: IdentificationCodeQualifier 70 | 71 | 72 | class Loop2000BHlSegment(HlSegment): 73 | """ 74 | Information Receiver HL Segment 75 | """ 76 | 77 | hierarchical_level_code: Literal["21"] 78 | hierarchical_child_code: Literal["1"] 79 | 80 | 81 | class Loop2100BNm1Segment(Nm1Segment): 82 | """ 83 | Information Receiver Name Segment 84 | """ 85 | 86 | entity_identifier_code: Literal["41"] 87 | identification_code_qualifier: Literal["46"] 88 | 89 | 90 | class Loop2000CHlSegment(HlSegment): 91 | """ 92 | Service Provider HL Segment 93 | """ 94 | 95 | hierarchical_level_code: Literal["19"] 96 | hierarchical_child_code: Literal["1"] 97 | 98 | 99 | class Loop2100CNm1Segment(Nm1Segment): 100 | """ 101 | Service Provider NM1 Segment 102 | """ 103 | 104 | class IdentificationCodeQualifier(str, Enum): 105 | """ 106 | Code values for NM108 107 | """ 108 | 109 | FEDERAL_TAXPAYER_IDENTIFIER_NUMBER = "FI" 110 | SERVICE_PROVIDER_NUMBER = "SV" 111 | CMS_NATIONAL_PROVIDER_IDENTIFIER = "XX" 112 | 113 | entity_identifier_code: Literal["1P"] 114 | name_last_or_organization_name: Optional[str] 115 | identification_code_qualifier: IdentificationCodeQualifier 116 | 117 | 118 | class Loop2000DHlSegment(HlSegment): 119 | """ 120 | Subscriber HL Segment 121 | """ 122 | 123 | hierarchical_level_code: Literal["22"] 124 | 125 | 126 | class Loop2000DDmgSegment(DmgSegment): 127 | """ 128 | Subscriber Demographics 129 | """ 130 | 131 | date_time_period_format_qualifier: Literal["D8"] 132 | date_time_period: Optional[Union[str, datetime.date]] 133 | 134 | 135 | class Loop2100DNm1Segment(Nm1Segment): 136 | """ 137 | Subscriber Name 138 | """ 139 | 140 | class IdentificationCodeQualifier(str, Enum): 141 | """ 142 | Code values for NM108 143 | """ 144 | 145 | EMPLOYER_IDENTIFICATION_NUMBER = "24" 146 | STANDARD_US_HEALTH_IDENTIFIER = "II" 147 | MEMBER_IDENTIFICATION_NUMBER = "MI" 148 | 149 | entity_identifier_code: Literal["IL"] 150 | entity_type_qualifier: Literal["1"] 151 | identification_code_qualifier: IdentificationCodeQualifier 152 | 153 | 154 | class Loop2200DTrnSegment(TrnSegment): 155 | """ 156 | Subscriber Claim Status Tracking Trace Segment 157 | """ 158 | 159 | trace_type_code: Literal["1"] 160 | originating_company_identifier: Optional[str] 161 | reference_identification_2: Optional[str] 162 | 163 | 164 | class Loop2200DRefSegment(RefSegment): 165 | """ 166 | Subscriber Claim Status Tracking Trace Segment Reference Identification 167 | """ 168 | 169 | class ReferenceIdentificationQualifier(str, Enum): 170 | """ 171 | Code values for REF01 172 | """ 173 | 174 | PAYOR_CLAIM_NUMBER = "1K" 175 | BILLING_TYPE = "BLT" 176 | LOCATION_NUMBER = "LU" 177 | GROUP_NUMBER = "6P" 178 | PATIENT_ACCOUNT_NUMBER = "EJ" 179 | PHARMACY_PRESCRIPTION_NUMBER = "XZ" 180 | CLAIM_NUMBER = "D9" 181 | 182 | reference_identification_qualifier: ReferenceIdentificationQualifier 183 | 184 | 185 | class Loop2200DAmtSegment(AmtSegment): 186 | """ 187 | Subscriber Claim Status Tracking Amount Segment 188 | """ 189 | 190 | amount_qualifier_code: Literal["T3"] 191 | 192 | 193 | class Loop2200DDtpSegment(DtpSegment): 194 | """ 195 | Subscriber Claim Status Tracking Amount Segment Dates 196 | """ 197 | 198 | date_time_qualifier: Literal["472"] 199 | 200 | 201 | class Loop2210DSvcSegment(SvcSegment): 202 | """ 203 | Subscriber Claim Status Service Line 204 | """ 205 | 206 | line_item_provider_payment_amount: Optional[Decimal] 207 | original_units_of_service_count: Decimal 208 | 209 | 210 | class Loop2210DRefSegment(RefSegment): 211 | """ 212 | Subscriber Claim Status Service Line Reference Identification 213 | """ 214 | 215 | reference_identification_qualifier: Literal["FJ"] 216 | 217 | 218 | class Loop2210DDtpSegment(DtpSegment): 219 | """ 220 | Subscriber Claim Status Service Line Dates 221 | """ 222 | 223 | date_time_qualifier: Literal["472"] 224 | 225 | 226 | class Loop2000EHlSegment(HlSegment): 227 | """ 228 | Dependent HL Segment 229 | """ 230 | 231 | hierarchical_level_code: Literal["23"] 232 | hierarchical_child_code: Optional[str] 233 | 234 | 235 | class Loop2100ENm1Segment(Nm1Segment): 236 | """ 237 | Dependent Name Segment 238 | """ 239 | 240 | entity_identifier_code: Literal["QC"] 241 | entity_type_qualifier: Literal["1"] 242 | identification_code_qualifier: Optional[str] 243 | identification_code: Optional[str] 244 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_276_005010X212/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Health Care Claims Status 276 005010X212 transaction set model. 5 | """ 6 | from linuxforhealth.x12.models import X12SegmentGroup 7 | from .loops import Header, Footer, Loop2000A 8 | from typing import List 9 | from pydantic import Field, root_validator 10 | from linuxforhealth.x12.validators import validate_segment_count 11 | 12 | 13 | class HealthCareClaimsStatusRequest(X12SegmentGroup): 14 | """ 15 | The Health Care Claims Status transaction model - 276 16 | """ 17 | 18 | header: Header 19 | loop_2000a: List[Loop2000A] = Field(min_items=1) 20 | footer: Footer 21 | 22 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 23 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_277_005010X212/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v5010/x12_277_005010X212/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_277_005010X212/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Health Care Claims Status 277 005010X212 transaction set model. 5 | """ 6 | from linuxforhealth.x12.models import X12SegmentGroup 7 | from .loops import Header, Footer, Loop2000A 8 | from typing import List 9 | from pydantic import Field, root_validator 10 | from linuxforhealth.x12.validators import validate_segment_count 11 | 12 | 13 | class HealthCareClaimsStatusResponse(X12SegmentGroup): 14 | """ 15 | The Health Care Claims Status Response transaction model - 277 16 | """ 17 | 18 | header: Header 19 | loop_2000a: List[Loop2000A] = Field(min_items=1) 20 | footer: Footer 21 | 22 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 23 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_834_005010X220A1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v5010/x12_834_005010X220A1/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_834_005010X220A1/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Enrollment 834 005010X220A1 transaction set model. 5 | """ 6 | 7 | from typing import List, Optional 8 | 9 | from linuxforhealth.x12.models import X12SegmentGroup 10 | 11 | from .loops import Footer, Header, Loop1000A, Loop1000B, Loop1000C, Loop2000 12 | from pydantic import root_validator, Field 13 | from linuxforhealth.x12.validators import validate_segment_count 14 | 15 | 16 | class BenefitEnrollmentAndMaintenance(X12SegmentGroup): 17 | """ 18 | The ASC X12 834 (Benefit Enrollment and Maintenance) transaction model. 19 | """ 20 | 21 | header: Header 22 | loop_1000a: Loop1000A 23 | loop_1000b: Loop1000B 24 | loop_1000c: Optional[List[Loop1000C]] = Field(max_items=2) 25 | loop_2000: List[Loop2000] 26 | footer: Footer 27 | 28 | # _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 29 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_835_005010X221A1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v5010/x12_835_005010X221A1/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_835_005010X221A1/loops.py: -------------------------------------------------------------------------------- 1 | """ 2 | loops.py 3 | 4 | Models the loops, or logical segment groupings, for the Health Care Claim Payment 835 005010X221A1 transaction set model. 5 | The Health Care Claim Payment transaction set organizes loops into a hierarchical and nested model. 6 | """ 7 | from linuxforhealth.x12.models import X12SegmentGroup 8 | from linuxforhealth.x12.v5010.segments import ( 9 | SeSegment, 10 | BprSegment, 11 | DtmSegment, 12 | N3Segment, 13 | N4Segment, 14 | RdmSegment, 15 | LxSegment, 16 | Ts3Segment, 17 | Ts2Segment, 18 | ClpSegment, 19 | Nm1Segment, 20 | MiaSegment, 21 | MoaSegment, 22 | SvcSegment, 23 | PlbSegment, 24 | ) 25 | from .segments import ( 26 | HeaderStSegment, 27 | HeaderTrnSegment, 28 | HeaderCurSegment, 29 | HeaderRefSegment, 30 | Loop1000AN1Segment, 31 | Loop1000ARefSegment, 32 | Loop1000APerSegment, 33 | Loop1000BN1Segment, 34 | Loop1000BRefSegment, 35 | Loop2100CasSegment, 36 | Loop2100RefSegment, 37 | Loop2100DtmSegment, 38 | Loop2100PerSegment, 39 | Loop2100AmtSegment, 40 | Loop2100QtySegment, 41 | Loop2110DtmSegment, 42 | Loop2110CasSegment, 43 | Loop2110RefSegment, 44 | Loop2110AmtSegment, 45 | Loop2110QtySegment, 46 | Loop2110LqSegment, 47 | ) 48 | from typing import Optional, List 49 | from pydantic import Field, root_validator 50 | from decimal import Decimal 51 | 52 | 53 | class Header(X12SegmentGroup): 54 | """ 55 | Transaction Header Information 56 | """ 57 | 58 | st_segment: HeaderStSegment 59 | bpr_segment: BprSegment 60 | trn_segment: HeaderTrnSegment 61 | cur_segment: Optional[HeaderCurSegment] 62 | ref_segment: Optional[List[HeaderRefSegment]] = Field(min_items=0, max_items=2) 63 | dtm_segment: Optional[DtmSegment] 64 | 65 | 66 | class Loop1000A(X12SegmentGroup): 67 | """ 68 | Loop 1000A - Payer Identification 69 | """ 70 | 71 | n1_segment: Loop1000AN1Segment 72 | n3_segment: N3Segment 73 | n4_segment: N4Segment 74 | ref_segment: Optional[List[Loop1000ARefSegment]] = Field(min_items=0, max_items=4) 75 | per_segment: Optional[List[Loop1000APerSegment]] 76 | 77 | 78 | class Loop1000B(X12SegmentGroup): 79 | """ 80 | Loop 1000B - Payee Identification 81 | """ 82 | 83 | n1_segment: Loop1000BN1Segment 84 | n3_segment: Optional[N3Segment] 85 | n4_segment: Optional[N4Segment] 86 | ref_segment: Optional[List[Loop1000BRefSegment]] 87 | rdm_segment: Optional[RdmSegment] 88 | 89 | 90 | class Loop2110(X12SegmentGroup): 91 | """ 92 | Loop 2110 - Service Line Payment Information 93 | """ 94 | 95 | svc_segment: SvcSegment 96 | dtm_segment: Optional[List[Loop2110DtmSegment]] = Field(min_items=0, max_items=2) 97 | cas_segment: Optional[List[Loop2110CasSegment]] = Field(min_items=0, max_items=99) 98 | ref_segment: Optional[List[Loop2110RefSegment]] = Field(min_items=0, max_items=24) 99 | amt_segment: Optional[List[Loop2110AmtSegment]] = Field(min_items=0, max_items=9) 100 | qty_segment: Optional[List[Loop2110QtySegment]] = Field(min_items=0, max_items=6) 101 | lq_segment: Optional[List[Loop2110LqSegment]] = Field(min_items=0, max_items=99) 102 | 103 | 104 | class Loop2100(X12SegmentGroup): 105 | """ 106 | Loop 2100 - Claim Payment Information 107 | """ 108 | 109 | clp_segment: ClpSegment 110 | cas_segment: Optional[List[Loop2100CasSegment]] = Field(min_items=0, max_items=99) 111 | nm1_segment: List[Nm1Segment] = Field(min_items=1, max_items=7) 112 | mia_segment: Optional[MiaSegment] 113 | moa_segment: Optional[MoaSegment] 114 | ref_segment: Optional[List[Loop2100RefSegment]] = Field(min_items=0, max_items=15) 115 | dtm_segment: Optional[List[Loop2100DtmSegment]] = Field(min_items=0, max_items=5) 116 | per_segment: Optional[List[Loop2100PerSegment]] = Field(min_items=0, max_items=2) 117 | amt_segment: Optional[List[Loop2100AmtSegment]] = Field(min_items=0, max_items=13) 118 | qty_segment: Optional[List[Loop2100QtySegment]] = Field(min_items=0, max_items=14) 119 | loop_2110: Optional[List[Loop2110]] = Field(min_items=0, max_items=99) 120 | 121 | @root_validator 122 | def validate_balance(cls, values): 123 | """ 124 | Validates the claim totals reported in the CLP segment against the adjustments made in CAS segments. 125 | The balance is calculated as: 126 | clp.charge amount - cas.adjustments = clp.payment_amount 127 | 128 | CAS segments exist within loops 2100 and 2110 129 | """ 130 | clp_segment = values.get("clp_segment") 131 | if not clp_segment: 132 | return values 133 | charge_amount = clp_segment.total_claim_charge_amount 134 | payment_amount = clp_segment.claim_payment_amount 135 | adjustment_amount = Decimal("0.0") 136 | 137 | cas_segments = values.get("cas_segment", []) 138 | for adjustment in cas_segments: 139 | adjustment_data = adjustment.dict() 140 | for i in range(1, 7, 1): 141 | amount = adjustment_data.get(f"monetary_amount_{i}") 142 | adjustment_amount += amount if amount else Decimal("0.0") 143 | 144 | loop_2110 = values.get("loop_2110") or [] 145 | for service_payment in loop_2110: 146 | adjustments = service_payment.cas_segment or [] 147 | for adjustment in adjustments: 148 | adjustment_data = adjustment.dict() 149 | for i in range(1, 7, 1): 150 | amount = adjustment_data.get(f"monetary_amount_{i}") 151 | adjustment_amount += amount if amount else Decimal("0.0") 152 | 153 | if charge_amount - payment_amount != adjustment_amount: 154 | raise ValueError( 155 | f"Unable to balance charge amount {charge_amount} paid amount {payment_amount} against adjustments {adjustment_amount}" 156 | ) 157 | 158 | return values 159 | 160 | 161 | class Loop2000(X12SegmentGroup): 162 | """ 163 | Loop 2000 - Claim Payment Header Number 164 | """ 165 | 166 | lx_segment: LxSegment 167 | ts3_segment: Optional[Ts3Segment] 168 | ts2_segment: Optional[Ts2Segment] 169 | loop_2100: List[Loop2100] 170 | 171 | 172 | class Footer(X12SegmentGroup): 173 | """ 174 | Transaction Footer Information 175 | """ 176 | 177 | plb_segment: Optional[PlbSegment] 178 | se_segment: SeSegment 179 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_835_005010X221A1/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Health Care Claims Payment 835 005010X221A1 transaction set model. 5 | """ 6 | from linuxforhealth.x12.models import X12SegmentGroup 7 | from .loops import Header, Footer, Loop1000A, Loop1000B, Loop2000 8 | from pydantic import root_validator 9 | from linuxforhealth.x12.validators import validate_segment_count 10 | from typing import List, Set 11 | 12 | 13 | class HealthCareClaimPayment(X12SegmentGroup): 14 | """ 15 | The Health Care Claim Payment/835 transaction 16 | """ 17 | 18 | header: Header 19 | loop_1000a: Loop1000A 20 | loop_1000b: Loop1000B 21 | loop_2000: List[Loop2000] 22 | footer: Footer 23 | 24 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 25 | 26 | @root_validator() 27 | def validate_lx_header(cls, values): 28 | """ 29 | Validates that LX numbers within a transaction set are unique. 30 | """ 31 | numbers: Set = set() 32 | for loop in values.get("loop_2000", []): 33 | n: int = loop.lx_segment.assigned_number 34 | if n in numbers: 35 | raise ValueError(f"duplicate assigned_numbers {n}") 36 | numbers.add(n) 37 | 38 | return values 39 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_837_005010X222A2/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v5010/x12_837_005010X222A2/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_837_005010X222A2/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Professional Claims 837 005010X222A2 transaction set model. 5 | """ 6 | 7 | from linuxforhealth.x12.models import X12SegmentGroup 8 | from .loops import Header, Footer, Loop1000A, Loop1000B, Loop2000A 9 | from pydantic import Field, root_validator 10 | from typing import List 11 | from linuxforhealth.x12.validators import validate_segment_count 12 | 13 | 14 | class HealthCareClaimProfessional(X12SegmentGroup): 15 | """ 16 | The HealthCare Claim - Professional transaction model (837) 17 | """ 18 | 19 | header: Header 20 | loop_1000a: Loop1000A 21 | loop_1000b: Loop1000B 22 | loop_2000a: List[Loop2000A] = Field(min_items=1) 23 | footer: Footer 24 | 25 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 26 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_837_005010X223A3/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/linuxforhealth/x12/v5010/x12_837_005010X223A3/__init__.py -------------------------------------------------------------------------------- /src/linuxforhealth/x12/v5010/x12_837_005010X223A3/transaction_set.py: -------------------------------------------------------------------------------- 1 | """ 2 | transaction_set.py 3 | 4 | Defines the Institutional Claims 837 005010X223A3 transaction set model. 5 | """ 6 | 7 | from linuxforhealth.x12.models import X12SegmentGroup 8 | from .loops import Header, Footer, Loop1000A, Loop1000B, Loop2000A 9 | from pydantic import Field, root_validator 10 | from typing import List 11 | from linuxforhealth.x12.validators import validate_segment_count 12 | 13 | 14 | class HealthCareClaimInstitutional(X12SegmentGroup): 15 | """ 16 | The HealthCare Claim - Institutional transaction model (837) 17 | """ 18 | 19 | header: Header 20 | loop_1000a: Loop1000A 21 | loop_1000b: Loop1000B 22 | loop_2000a: List[Loop2000A] = Field(min_items=1) 23 | footer: Footer 24 | 25 | _validate_segment_count = root_validator(allow_reuse=True)(validate_segment_count) 26 | -------------------------------------------------------------------------------- /src/linuxforhealth/x12/validators.py: -------------------------------------------------------------------------------- 1 | """ 2 | validators.py 3 | 4 | The validator functions in this module are reused across loops within a X12 transaction model. 5 | 6 | Root validators have the signature (cls, values). 7 | 8 | Field validators support a varying signature: 9 | - (cls, v) - where "v" is the value to validate 10 | - (cls, v, values) - where "values" are previously validated fields (dict) 11 | - (cls, v, values, config) - where "config" is the model config 12 | - (cls, kwargs) - provides a key word arguments shorthand for the above parameters 13 | """ 14 | from typing import Dict, Union 15 | from collections import defaultdict 16 | from datetime import datetime 17 | from .support import parse_x12_date, count_segments 18 | 19 | 20 | def _validate_duplicate_codes(values: Dict, segment_name: str, code_field: str): 21 | """ 22 | Validates duplicate code values for repeating segments. 23 | 24 | Example: Some transactional loops support multiple date, DTP, segments. For these cases this validation ensures 25 | that the date_time_qualifier is unique within the loop for the repeating segments. 26 | 27 | Given _validate_duplicate_codes(values, "amt_segment", "amount_qualifier_code"), the following segments are valid: 28 | AMT*D*411~ 29 | AMT*A8*420~ 30 | 31 | The following segments are invalid due to duplicate codes 32 | AMT*D*411~ 33 | AMT*D*411~ 34 | """ 35 | codes = defaultdict(int) 36 | for segment in values.get(segment_name, []): 37 | # account for differing internal representation: model vs dict 38 | if not isinstance(segment, dict): 39 | segment = segment.dict() 40 | 41 | code = segment.get(code_field) 42 | codes[code] += 1 43 | 44 | duplicate_codes = {k for k, v in codes.items() if v > 1} 45 | if duplicate_codes: 46 | raise ValueError( 47 | f"Duplicate {segment_name}.{code_field} codes {duplicate_codes}" 48 | ) 49 | return values 50 | 51 | 52 | def validate_duplicate_ref_codes(cls, values: Dict): 53 | """ 54 | Validates that a loop does not contain duplicate REF codes. 55 | 56 | :param values: The validated transaction data. 57 | :raises: ValueError if duplicate REF codes are found. 58 | """ 59 | return _validate_duplicate_codes( 60 | values, "ref_segment", "reference_identification_qualifier" 61 | ) 62 | 63 | 64 | def validate_duplicate_amt_codes(cls, values: Dict): 65 | """ 66 | Validates that a loop does not contain duplicate REF codes. 67 | 68 | :param values: The validated transaction data. 69 | :raises: ValueError if duplicate REF codes are found. 70 | """ 71 | return _validate_duplicate_codes(values, "amt_segment", "amount_qualifier_code") 72 | 73 | 74 | def validate_duplicate_date_qualifiers(cls, values: Dict): 75 | """ 76 | Validates that a loop does not contain duplicate DTP date qualifiers. 77 | 78 | :param values: The validated transaction data. 79 | :raises: ValueError if duplicate DTP date qualifiers are found. 80 | """ 81 | return _validate_duplicate_codes(values, "dtp_segment", "date_time_qualifier") 82 | 83 | 84 | def validate_date_field(cls, v, values: Dict) -> Union[datetime.date, str, None]: 85 | """ 86 | Validates a date field using the segment's date_time_period_format_qualifier (D8 or RD8). 87 | The date_time_period_format_qualifier is used to indicate if a date field is a specific date or a date range. 88 | Specific dates are have a "D8" qualifier value, while date ranges are qualified using "RD8". 89 | 90 | :param v: The date field value 91 | :param values: The segment's valid values. 92 | :return: The validated date field value 93 | :raises: ValueError if the date field value is an invalid format. 94 | """ 95 | from linuxforhealth.x12.v5010.segments import DtpSegment 96 | 97 | def handle_x12_date(date_string: str): 98 | """Parses a x12 date string, raising a ValueError if an error occurs""" 99 | try: 100 | return parse_x12_date(date_string) 101 | except ValueError: 102 | raise ValueError(f"Invalid date value {date_string}") 103 | 104 | qualifier = values.get("date_time_period_format_qualifier") 105 | 106 | # the date field may be "optional" in which case the qualifier is not present 107 | # if the qualifier field is required, it will be validated at the field level 108 | if not qualifier: 109 | return v 110 | 111 | if ( 112 | qualifier == DtpSegment.DateTimePeriodFormatQualifier.DATE_RANGE 113 | and "-" not in v 114 | ): 115 | raise ValueError(f"Invalid date range {v}") 116 | elif qualifier == DtpSegment.DateTimePeriodFormatQualifier.DATE_RANGE: 117 | for d in v.split("-"): 118 | handle_x12_date(d) 119 | return v 120 | else: 121 | return handle_x12_date(v) 122 | 123 | 124 | def validate_segment_count(cls, values) -> Dict: 125 | """ 126 | Validates the segment count conveyed in the transaction set footer, or SE segment. 127 | This function is only able to count "valid" segments since it is invoked as a "post" validator. 128 | 129 | :param values: The valid transaction set values. 130 | """ 131 | expected_count: int = values["footer"].se_segment.transaction_segment_count 132 | 133 | if not expected_count: 134 | raise ValueError("Expected transaction count not found in SE segment") 135 | 136 | actual_count: int = count_segments(values) 137 | 138 | if expected_count != actual_count: 139 | raise ValueError( 140 | f"SE segment count {expected_count} != actual count {actual_count}" 141 | ) 142 | 143 | return values 144 | -------------------------------------------------------------------------------- /src/tests/__init__.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | # registers helper/convenience functions with pytest to support writing diff/error information to stdout and stderr 4 | pytest.register_assert_rewrite("tests.support") 5 | -------------------------------------------------------------------------------- /src/tests/benefit_enrollment_maintenance/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/tests/benefit_enrollment_maintenance/__init__.py -------------------------------------------------------------------------------- /src/tests/benefit_enrollment_maintenance/test_834_005010X220A1.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_834_005010X220A1.py 3 | 4 | Tests the benefit enrollment (834) transaction 5 | """ 6 | from tests.support import assert_eq_model, resources_directory 7 | import os 8 | import pytest 9 | 10 | 11 | @pytest.fixture 12 | def resource_path() -> str: 13 | return os.path.join(resources_directory, "834_005010X220A1") 14 | 15 | 16 | @pytest.mark.parametrize( 17 | "file_name", 18 | [ 19 | "enroll-employee-multiple-products.834", 20 | # "add-dependent.834", 21 | # "enroll-employee-multiple-products.834", 22 | # "add-subscriber-coverage.834", 23 | # "change-subscriber-information.834", 24 | # "cancel-dependent.834", 25 | # "terminate-subscriber-eligibility.834", 26 | # "reinstate-employee.834", 27 | # "reinstate-employee-coverage-level.834", 28 | # "reinstate-member-eligiblity-ins.834", 29 | ], 30 | ) 31 | def test_834_model(resource_path, file_name: str): 32 | 33 | x12_file_path = os.path.join(resource_path, file_name) 34 | assert os.path.exists(x12_file_path) 35 | assert_eq_model(x12_file_path) 36 | -------------------------------------------------------------------------------- /src/tests/conftest.py: -------------------------------------------------------------------------------- 1 | """ 2 | conftest.py 3 | 4 | Pytest Global Fixtures 5 | """ 6 | import pytest 7 | 8 | from linuxforhealth.x12.config import X12Config 9 | from linuxforhealth.x12.models import X12Delimiters 10 | from linuxforhealth.x12.parsing import X12ParserContext 11 | 12 | 13 | @pytest.fixture 14 | def simple_270_with_new_lines() -> str: 15 | return "\n".join( 16 | [ 17 | "ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~", 18 | "GS*HS*000000005*54321*20131031*1147*1*X*005010X279A1~", 19 | "ST*270*0001*005010X279A1~", 20 | "BHT*0022*13*10001234*20131031*1147~", 21 | "HL*1**20*1~", 22 | "NM1*PR*2*PAYER C*****PI*12345~", 23 | "HL*2*1*21*1~", 24 | "NM1*1P*1*DOE*JOHN****XX*1467857193~", 25 | "REF*4A*000111222~", 26 | "N3*123 MAIN ST.*SUITE 42~", 27 | "N4*SAN MATEO*CA*94401~", 28 | "HL*3*2*22*0~", 29 | "TRN*1*930000000000*9800000004*PD~", 30 | "NM1*IL*1*DOE*JOHN****MI*00000000001~", 31 | "REF*6P*0123456789~", 32 | "DMG*D8*19700101~", 33 | "DTP*291*D8*20131031~", 34 | "EQ*1~", 35 | "SE*17*0001~", 36 | "GE*1*1~", 37 | "IEA*1*000000907~", 38 | ] 39 | ) 40 | 41 | 42 | @pytest.fixture 43 | def simple_270_one_line(simple_270_with_new_lines) -> str: 44 | return simple_270_with_new_lines.replace("\n", "") 45 | 46 | 47 | @pytest.fixture 48 | def large_x12_message() -> str: 49 | """ 50 | Generates a large x12 message by repeating a transaction set a fixed number of times. 51 | :return: large x12 message 52 | """ 53 | 54 | x12_message: str = "\n".join( 55 | [ 56 | "ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~", 57 | "GS*HS*000000005*54321*20131031*1147*1*X*005010X279A1~", 58 | ] 59 | ) 60 | 61 | x12_message += "\n" 62 | # will create 10 transaction sets 63 | for i in range(1, 11, 1): 64 | transaction_set = "\n".join( 65 | [ 66 | # ST02 is the transaction set id - zero filled to 4 characters 67 | f"ST*270*{i:04d}*005010X279A1~", 68 | "BHT*0022*13*10001234*20131031*1147~", 69 | "HL*1**20*1~", 70 | "NM1*PR*2*PAYER C*****PI*12345~", 71 | "HL*2*1*21*1~", 72 | "NM1*1P*1*DOE*JOHN****XX*1467857193~", 73 | "REF*4A*000111222~", 74 | "N3*123 MAIN ST.*SUITE 42~", 75 | "N4*SAN MATEO*CA*94401~", 76 | "HL*3*2*22*0~", 77 | "TRN*1*930000000000*9800000004*PD~", 78 | "NM1*IL*1*DOE*JOHN****MI*00000000001~", 79 | "REF*6P*0123456789~", 80 | "DMG*D8*19700101~", 81 | "DTP*291*D8*20131031~", 82 | "EQ*1~", 83 | # SE02 is the transaction set id - zero filled to 4 characters 84 | f"SE*17*{i:04d}~", 85 | ] 86 | ) 87 | x12_message += transaction_set + "\n" 88 | 89 | x12_message += "\n".join(["GE*1*1~", "IEA*1*000000907~"]) 90 | 91 | return x12_message 92 | 93 | 94 | @pytest.fixture 95 | def config() -> X12Config: 96 | config: X12Config = X12Config() 97 | config.x12_reader_buffer_size = 1024000 98 | return config 99 | 100 | 101 | @pytest.fixture 102 | def x12_delimiters() -> X12Delimiters: 103 | return X12Delimiters() 104 | 105 | 106 | @pytest.fixture 107 | def x12_parser_context() -> X12ParserContext: 108 | return X12ParserContext() 109 | 110 | 111 | @pytest.fixture 112 | def x12_with_custom_delimiters() -> str: 113 | return "\n".join( 114 | [ 115 | "ISA|03|9876543210|01|9876543210|30|000000005 |30|12345 |131031|1147|^|00501|000000907|1|T|:?", 116 | "GS|HS|000000005|54321|20131031|1147|1|X|005010X279A1?", 117 | "ST|270|0001|005010X279A1?", 118 | "BHT|0022|13|10001234|20131031|1147?", 119 | "HL|1||20|1?", 120 | "NM1|PR|2|PAYER C|||||PI|12345?", 121 | "HL|2|1|21|1?", 122 | "NM1|1P|1|DOE|JOHN||||XX|1467857193?", 123 | "REF|4A|000111222?", 124 | "N3|123 MAIN ST.|SUITE 42?", 125 | "N4|SAN MATEO|CA|94401?", 126 | "HL|3|2|22|0?", 127 | "TRN|1|930000000000|9800000004|PD?", 128 | "NM1|IL|1|DOE|JOHN||||MI|00000000001?", 129 | "REF|6P|0123456789?", 130 | "DMG|D8|19700101?", 131 | "DTP|291|D8|20131031?", 132 | "EQ|30?", 133 | "SE|17|0001?", 134 | "GE|1|1?", 135 | "IEA|1|000000907?", 136 | ] 137 | ) 138 | -------------------------------------------------------------------------------- /src/tests/eligibility/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/tests/eligibility/__init__.py -------------------------------------------------------------------------------- /src/tests/eligibility/test_270_005010X279A1.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests use-cases for the 270 005010X279A1 (Eligibility Inquiry) transaction 3 | """ 4 | 5 | import pytest 6 | from tests.support import assert_eq_model, resources_directory 7 | import os 8 | 9 | 10 | @pytest.fixture 11 | def resource_path() -> str: 12 | return os.path.join(resources_directory, "270_005010X279A1") 13 | 14 | 15 | @pytest.mark.parametrize( 16 | "file_name", 17 | ["dependent-health-benefit-check.270", "subscriber-health-benefit-check.270"], 18 | ) 19 | def test_270_model(resource_path, file_name: str): 20 | 21 | x12_file_path = os.path.join(resource_path, file_name) 22 | assert os.path.exists(x12_file_path) 23 | assert_eq_model(x12_file_path) 24 | -------------------------------------------------------------------------------- /src/tests/eligibility/test_271_005010X279A1.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests use-cases for the 271 005010X279A1 (Eligibility Benefit Response) transaction 3 | """ 4 | import pytest 5 | from tests.support import assert_eq_model, resources_directory 6 | import os 7 | 8 | 9 | @pytest.fixture 10 | def resource_path() -> str: 11 | return os.path.join(resources_directory, "271_005010X279A1") 12 | 13 | 14 | @pytest.mark.parametrize( 15 | "file_name", 16 | [ 17 | "subscriber-health-benefit-check.271", 18 | "subscriber-health-benefit-check-error.271", 19 | "dependent-health-benefit-check.271", 20 | ], 21 | ) 22 | def test_271_model(resource_path, file_name: str): 23 | x12_file_path = os.path.join(resource_path, file_name) 24 | assert os.path.exists(x12_file_path) 25 | assert_eq_model(x12_file_path) 26 | -------------------------------------------------------------------------------- /src/tests/healthcare_claim_institutional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/tests/healthcare_claim_institutional/__init__.py -------------------------------------------------------------------------------- /src/tests/healthcare_claim_institutional/test_837_004010X096A1.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_837_004010X096A1.py 3 | """ 4 | import pytest 5 | from tests.support import assert_eq_model, resources_directory 6 | import os 7 | 8 | 9 | @pytest.fixture 10 | def resource_path() -> str: 11 | return os.path.join(resources_directory, "837_004010X096A1") 12 | 13 | 14 | @pytest.mark.parametrize( 15 | "file_name", 16 | [ 17 | "automobile-accident.837", 18 | "homeowners.837", 19 | "institutional-ppo-repriced.837", 20 | "institutional.837", 21 | "workers-compensation.837", 22 | ], 23 | ) 24 | def test_837i_model(resource_path, file_name: str): 25 | x12_file_path = os.path.join(resource_path, file_name) 26 | assert os.path.exists(x12_file_path) 27 | assert_eq_model(x12_file_path) 28 | -------------------------------------------------------------------------------- /src/tests/healthcare_claim_institutional/test_837i_005010X223A3.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_837_005010XX223A3.py 3 | """ 4 | import pytest 5 | from tests.support import assert_eq_model, resources_directory 6 | import os 7 | 8 | 9 | @pytest.fixture 10 | def resource_path() -> str: 11 | return os.path.join(resources_directory, "837_005010X223A3") 12 | 13 | 14 | @pytest.mark.parametrize( 15 | "file_name", 16 | [ 17 | "institutional-claim.837i", 18 | "out-of-network-repriced-claim.837i", 19 | "ppo-repriced-claim.837i", 20 | "two-claims-single-provider.837i", 21 | ], 22 | ) 23 | def test_837i_model(resource_path, file_name: str): 24 | x12_file_path = os.path.join(resource_path, file_name) 25 | assert os.path.exists(x12_file_path) 26 | assert_eq_model(x12_file_path) 27 | -------------------------------------------------------------------------------- /src/tests/healthcare_claim_payment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/tests/healthcare_claim_payment/__init__.py -------------------------------------------------------------------------------- /src/tests/healthcare_claim_payment/test_835_005010X221A1.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_835_005010XX221A1.py 3 | """ 4 | import pytest 5 | from tests.support import assert_eq_model, resources_directory 6 | import os 7 | 8 | 9 | @pytest.fixture 10 | def resource_path() -> str: 11 | return os.path.join(resources_directory, "835_005010X221A1") 12 | 13 | 14 | @pytest.mark.parametrize( 15 | "file_name", 16 | [ 17 | "medicare-part-a.835", 18 | "managed-care.835", 19 | "secondary-payment.835", 20 | "tertiary-payment.835", 21 | "cob-contractural-adjustment.835", 22 | ], 23 | ) 24 | def test_835_model(resource_path, file_name: str): 25 | x12_file_path = os.path.join(resource_path, file_name) 26 | assert os.path.exists(x12_file_path) 27 | assert_eq_model(x12_file_path) 28 | -------------------------------------------------------------------------------- /src/tests/healthcare_claim_professional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/tests/healthcare_claim_professional/__init__.py -------------------------------------------------------------------------------- /src/tests/healthcare_claim_professional/test_837_004010X098A1.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_837_004010X098A1.py 3 | """ 4 | import pytest 5 | from tests.support import assert_eq_model, resources_directory 6 | import os 7 | 8 | 9 | @pytest.fixture 10 | def resource_path() -> str: 11 | return os.path.join(resources_directory, "837_004010X098A1") 12 | 13 | 14 | @pytest.mark.parametrize( 15 | "file_name", 16 | [ 17 | "coordination-of-benefits.837", 18 | "dependent-commercial-insurance-02.837", 19 | "patient-is-dependent.837", 20 | "dependent-commercial-insurance-01.837", 21 | "dependent-commercial-insurance-03.837", 22 | "patient-is-subscriber.837", 23 | ], 24 | ) 25 | def test_837_model(resource_path, file_name: str): 26 | x12_file_path = os.path.join(resource_path, file_name) 27 | assert os.path.exists(x12_file_path) 28 | assert_eq_model(x12_file_path) 29 | -------------------------------------------------------------------------------- /src/tests/healthcare_claim_professional/test_837_005010X222A2.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_837_005010XX222A2.py 3 | """ 4 | import pytest 5 | from tests.support import assert_eq_model, resources_directory 6 | import os 7 | 8 | 9 | @pytest.fixture 10 | def resource_path() -> str: 11 | return os.path.join(resources_directory, "837_005010X222A2") 12 | 13 | 14 | @pytest.mark.parametrize( 15 | "file_name", 16 | [ 17 | "demo.ambulance.example5.837", 18 | "demo.autoaccident.837", 19 | "demo.cob.2ndary.example4.837", 20 | "demo.cob.example3.A.837", 21 | "demo.cob.example3.B.837", 22 | "demo.cob.example3.C.837", 23 | "demo.cob.example4.837", 24 | "demo.drug.example10.1.837", 25 | "demo.drug.example10.2.837", 26 | "demo.drug.example10.3.837", 27 | "demo.example6.837", 28 | "demo.example7.837", 29 | "demo.example8.837", 30 | "demo.example9.837", 31 | "demo.example11.837", 32 | "demo.example12.837", 33 | "demo.example1.837", 34 | "demo.example2.837", 35 | ], 36 | ) 37 | def test_837_model(resource_path, file_name: str): 38 | x12_file_path = os.path.join(resource_path, file_name) 39 | assert os.path.exists(x12_file_path) 40 | assert_eq_model(x12_file_path) 41 | -------------------------------------------------------------------------------- /src/tests/healthcare_claim_status/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxForHealth/x12/c97b41a5b75af557d897067c124ab448b9230d4e/src/tests/healthcare_claim_status/__init__.py -------------------------------------------------------------------------------- /src/tests/healthcare_claim_status/test_x12_276_005010X212.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_x12_276_005010X212.py 3 | 4 | Tests the Health Care Claim Status Request Transaction 5 | """ 6 | import pytest 7 | from tests.support import assert_eq_model, resources_directory 8 | import os 9 | 10 | 11 | @pytest.fixture 12 | def resource_path() -> str: 13 | return os.path.join(resources_directory, "276_005010X212") 14 | 15 | 16 | @pytest.mark.parametrize( 17 | "file_name", 18 | [ 19 | "claim-level-status.276", 20 | "claim-level-status-ncpdp.276", 21 | "information-receiver-level-status.276", 22 | "provider-level-status.276", 23 | ], 24 | ) 25 | def test_276_model(resource_path, file_name: str): 26 | x12_file_path = os.path.join(resource_path, file_name) 27 | assert os.path.exists(x12_file_path) 28 | assert_eq_model(x12_file_path) 29 | -------------------------------------------------------------------------------- /src/tests/healthcare_claim_status/test_x12_277_005010X212.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_x12_277_005010X212.py 3 | 4 | Tests the Health Care Claim Status Response Transaction 5 | """ 6 | import pytest 7 | from tests.support import assert_eq_model, resources_directory 8 | import os 9 | 10 | 11 | @pytest.fixture 12 | def resource_path() -> str: 13 | return os.path.join(resources_directory, "277_005010X212") 14 | 15 | 16 | @pytest.mark.parametrize( 17 | "file_name", 18 | [ 19 | "claim-level-status.277", 20 | "claim-level-status-ncpdp.277", 21 | "information-receiver-level-status.277", 22 | "provider-level-status.277", 23 | ], 24 | ) 25 | def test_277_model(resource_path, file_name: str): 26 | x12_file_path = os.path.join(resource_path, file_name) 27 | assert os.path.exists(x12_file_path) 28 | assert_eq_model(x12_file_path) 29 | -------------------------------------------------------------------------------- /src/tests/resources/270_005010X279A1/dependent-health-benefit-check.270: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HS*000000005*54321*20131031*1147*1*X*005010X279A1~ 3 | ST*270*1234*005010X279A1~ 4 | BHT*0022*13*10001234*20060501*1319~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC COMPANY*****PI*842610001~ 7 | HL*2*1*21*1~ 8 | NM1*1P*1*JONES*MARCUS****SV*2000034~ 9 | HL*3*2*22*1~ 10 | NM1*IL*1******MI*11122333301~ 11 | HL*4*3*23*0~ 12 | TRN*1*93175-012547*9877281234~ 13 | NM1*03*1*SMITH*MARY~ 14 | DMG*D8*19781014~ 15 | DTP*291*D8*20060501~ 16 | EQ*30~ 17 | SE*15*1234~ 18 | GE*1*1~ 19 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/270_005010X279A1/subscriber-health-benefit-check.270: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HS*000000005*54321*20131031*1147*1*X*005010X279A1~ 3 | ST*270*1234*005010X279A1~ 4 | BHT*0022*13*10001234*20060501*1319~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC COMPANY*****PI*842610001~ 7 | HL*2*1*21*1~ 8 | NM1*1P*2*BONE AND JOINT CLINIC*****SV*2000035~ 9 | HL*3*2*22*0~ 10 | TRN*1*93175-012547*9877281234~ 11 | NM1*IL*1*SMITH*ROBERT****MI*11122333301~ 12 | DMG*D8*19430519~ 13 | DTP*291*D8*20060501~ 14 | EQ*30~ 15 | SE*13*1234~ 16 | GE*1*1~ 17 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/271_005010X279A1/dependent-health-benefit-check.271: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HB*000000005*54321*20131031*1147*1*X*005010X279A1~ 3 | ST*271*4321*005010X279A1~ 4 | BHT*0022*11*10001234*20060501*1319~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC COMPANY*****PI*841610001~ 7 | HL*2*1*21*1~ 8 | NM1*1P*2*BONE AND JOIN CLINIC*****SV*2000035~ 9 | HL*3*2*22*1~ 10 | NM1*IL*1*SMITH*JOHN****MI*123456789~ 11 | N3*15197 BROADWAY AVENUE*APT 215~ 12 | N4*KANSAS CITY*MO*64108~ 13 | DMG*D8*19630519*M~ 14 | HL*4*3*23*0~ 15 | TRN*2*93175-012547*9877281234~ 16 | NM1*03*1*SMITH*MARY~ 17 | N3*15197 BROADWAY AVENUE*APT 215~ 18 | N4*KANSAS CITY*MO*64108~ 19 | DMG*D8*19981014*F~ 20 | INS*N*19~ 21 | DTP*346*D8*20060101~ 22 | EB*1**30**GOLD 123 PLAN~ 23 | EB*L~ 24 | LS*2120~ 25 | NM1*P3*1*JONES*MARCUS****SV*0202034~ 26 | LE*2120~ 27 | EB*1**1^33^35^47^86^88^98^AL^MH^UC~ 28 | EB*B**1^33^35^47^86^88^98^AL^MH^UC*HM*GOLD 123 PLAN*27*10.00*****Y~ 29 | EB*B**1^33^35^47^86^88^98^AL^MH^UC*HM*GOLD 123 PLAN*27*30.00*****N~ 30 | SE*28*4321~ 31 | GE*1*1~ 32 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/271_005010X279A1/subscriber-health-benefit-check-error.271: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HB*000000005*54321*20131031*1147*1*X*005010X279A1~ 3 | ST*271*4321*005010X279A1~ 4 | BHT*0022*11*10001234*20060501*1319~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC COMPANY*****PI*842610001~ 7 | HL*2*1*21*0~ 8 | NM1*1P*2*BONE AND JOIN CLINIC*****SV*2000035~ 9 | AAA*Y**50*N~ 10 | SE*8*4323~ 11 | GE*1*1~ 12 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/271_005010X279A1/subscriber-health-benefit-check.271: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HB*000000005*54321*20131031*1147*1*X*005010X279A1~ 3 | ST*271*4321*005010X279A1~ 4 | BHT*0022*11*10001234*20060501*1319~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC COMPANY*****PI*841610001~ 7 | HL*2*1*21*1~ 8 | NM1*1P*2*BONE AND JOIN CLINIC*****SV*2000035~ 9 | HL*3*2*22*0~ 10 | TRN*2*93175-012547*9877281234~ 11 | NM1*IL*1*SMITH*JOHN****MI*123456789~ 12 | N3*15197 BROADWAY AVENUE*APT 215~ 13 | N4*KANSAS CITY*MO*64108~ 14 | DMG*D8*19630519*M~ 15 | DTP*346*D8*20060101~ 16 | EB*1**30**GOLD 123 PLAN~ 17 | EB*L~ 18 | LS*2120~ 19 | NM1*P3*1*JONES*MARCUS****SV*0202034~ 20 | LE*2120~ 21 | EB*1**1^33^35^47^86^88^98^AL^MH^UC~ 22 | EB*B**1^33^35^47^86^88^98^AL^MH^UC*HM*GOLD 123 PLAN*27*10.00*****Y~ 23 | EB*B**1^33^35^47^86^88^98^AL^MH^UC*HM*GOLD 123 PLAN*27*30.00*****N~ 24 | SE*22*4321~ 25 | GE*1*1~ 26 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/276_005010X212/claim-level-status-ncpdp.276: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HR*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*276*0001*005010X212~ 4 | BHT*0010*13*ABC276XXX*20050915*1425~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL PHARMACY*****XX*1666666662~ 11 | HL*4*3*22*0~ 12 | DMG*D8*19301210*M~ 13 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 14 | TRN*1*ABCXYZ1~ 15 | REF*XZ*7654321~ 16 | AMT*T3*85.00~ 17 | DTP*472*D8*20060301~ 18 | SE*16*0001~ 19 | GE*1*1~ 20 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/276_005010X212/claim-level-status.276: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HR*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*276*0001*005010X212~ 4 | BHT*0010*13*ABC276XXX*20050915*1425~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL*****XX*1666666661~ 11 | HL*4*3*22*0~ 12 | DMG*D8*19301210*M~ 13 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 14 | TRN*1*ABCXYZ1~ 15 | REF*BLT*111~ 16 | REF*EJ*SM123456~ 17 | AMT*T3*8513.88~ 18 | DTP*472*RD8*20050831-20050906~ 19 | HL*5*3*22*0~ 20 | DMG*D8*19301115*F~ 21 | NM1*IL*1*JONES*MARY****MI*234567890A~ 22 | TRN*1*ABCXYZ2~ 23 | REF*BLT*111~ 24 | REF*EJ*J0234567~ 25 | AMT*T3*7599.00~ 26 | DTP*472*RD8*20050731-20050809~ 27 | HL*6*2*19*1~ 28 | NM1*1P*2*HOME HOSPITAL PHYSICANS*****XX*166666666~ 29 | HL*7*6*22*1~ 30 | NM1*IL*1*MANN*JOHN****MI*345678901~ 31 | HL*8*7*23~ 32 | DMG*D8*19951101*M~ 33 | NM1*QC*1*MANN*JOSEPH~ 34 | TRN*1*ABCXYZ3~ 35 | REF*EJ*MA345678~ 36 | SVC*HC:99203*150.00*****1.00~ 37 | DTP*472*D8*20050501~ 38 | SE*36*0001~ 39 | GE*1*1~ 40 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/276_005010X212/information-receiver-level-status.276: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HR*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*276*0001*005010X212~ 4 | BHT*0010*13*ABC276XXX*20050915*1425~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL*****XX*1666666661~ 11 | HL*4*3*22*0~ 12 | DMG*D8*19301210*M~ 13 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 14 | TRN*1*ABCXYZ1~ 15 | REF*BLT*111~ 16 | REF*EJ*SM123456~ 17 | AMT*T3*8513.88~ 18 | DTP*472*RD8*20050831-20050906~ 19 | SE*17*0001~ 20 | GE*1*1~ 21 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/276_005010X212/provider-level-status.276: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HR*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*276*0001*005010X212~ 4 | BHT*0010*13*ABC276XXX*20050915*1425~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL*****XX*1666666661~ 11 | HL*4*3*22*0~ 12 | DMG*D8*19301210*M~ 13 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 14 | TRN*1*ABCXYZ1~ 15 | REF*BLT*111~ 16 | REF*EJ*SM123456~ 17 | AMT*T3*8513.88~ 18 | DTP*472*RD8*20050831-20050906~ 19 | HL*5*2*19*1~ 20 | NM1*1P*2*HOME HOSPITAL PHYSICIANS*****XX*6166666666~ 21 | HL*6*5*22*1~ 22 | NM1*IL*1*MANN*JOHN****MI*345678901~ 23 | HL*7*6*23~ 24 | DMG*D8*19951101*M~ 25 | NM1*QC*1*MANN*JOSEPH~ 26 | TRN*1*ABCXYZ3~ 27 | REF*EJ*MA345678~ 28 | SVC*HC:99203*150.00*****1.00~ 29 | DTP*472*D8*20050501~ 30 | SE*28*0001~ 31 | GE*1*1~ 32 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/277_005010X212/claim-level-status-ncpdp.277: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HN*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*277*0001*005010X212~ 4 | BHT*0010*08*277X212*20050916*0810*DG~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL PHARMACY*****XX*1666666662~ 11 | HL*4*3*22*0~ 12 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 13 | TRN*2*ABCXYZ1~ 14 | STC*F2:80::RX*20060301**85.00*0.00~ 15 | REF*1K*05347006051~ 16 | REF*XZ*7654321~ 17 | DTP*472*D8*20060301~ 18 | SE*16*0001~ 19 | GE*1*1~ 20 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/277_005010X212/claim-level-status.277: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HN*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*277*0001*005010X212~ 4 | BHT*0010*08*277X212*20050916*0810*DG~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL*****XX*1666666661~ 11 | HL*4*3*22*0~ 12 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 13 | TRN*2*ABCXYZ1~ 14 | STC*P3:317*20050913**8513.88~ 15 | REF*1K*05347006051~ 16 | REF*BLT*111~ 17 | REF*EJ*SM123456~ 18 | DTP*472*RD8*20050831-20050906~ 19 | HL*5*3*22*0~ 20 | NM1*IL*1*JONES*MARY****MI*234567890A~ 21 | TRN*2*ABCXYZ2~ 22 | STC*F0:3*20050915**7599.00*7599.00~ 23 | REF*1K*0529675341~ 24 | REF*BLT*111~ 25 | REF*EJ*J0234567~ 26 | DTP*472*RD8*20050731-20050809~ 27 | HL*6*2*19*1~ 28 | NM1*1P*2*HOME HOSPITAL PHYSICIANS*****XX*166666666~ 29 | HL*7*6*22*1~ 30 | NM1*IL*1*MANN*JOHN****MI*345678901~ 31 | HL*8*7*23~ 32 | NM1*QC*1*MANN*JOSEPH~ 33 | TRN*2*ABCXYC3~ 34 | STC*F2:88:QC*20050612**150.00*0.00~ 35 | REF*1K*051681010827~ 36 | REF*EJ*MA345678~ 37 | SVC*HC:99203*150.00*0.00****1.00~ 38 | STC*F2:88:QC*20050612~ 39 | DTP*472*D8*20050501~ 40 | SE*38*0001~ 41 | GE*1*1~ 42 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/277_005010X212/information-receiver-level-status.277: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HN*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*277*0001*005010X212~ 4 | BHT*0010*08*277X212*20050916*0810*DG~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*0~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | TRN*2*ABC276XXX~ 10 | STC*E0:0*20050916~ 11 | SE*9*0001~ 12 | GE*1*1~ 13 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/277_005010X212/provider-level-status.277: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HN*000000005*54321*20131031*1147*1*X*005010X212~ 3 | ST*277*0001*005010X212~ 4 | BHT*0010*08*277X212*20050916*0810*DG~ 5 | HL*1**20*1~ 6 | NM1*PR*2*ABC INSURANCE*****PI*12345~ 7 | HL*2*1*21*1~ 8 | NM1*41*2*XYZ SERVICE*****46*X67E~ 9 | HL*3*2*19*1~ 10 | NM1*1P*2*HOME HOSPITAL*****XX*1666666661~ 11 | HL*4*3*22*0~ 12 | NM1*IL*1*SMITH*FRED****MI*123456789A~ 13 | TRN*2*ABCXYZ1~ 14 | STC*P3:317*20050913**8513.88~ 15 | REF*1K*05347006051~ 16 | REF*BLT*111~ 17 | REF*EJ*SM123456~ 18 | DTP*472*RD8*20050831-20050906~ 19 | HL*5*2*19*0~ 20 | NM1*1P*2*HOME HOSPITAL PHYSICIANS*****XX*6166666666~ 21 | TRN*1*0~ 22 | STC*E0:24:85*20050916~ 23 | SE*21*0001~ 24 | GE*1*1~ 25 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/add-dependent.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | REF*38*ABCD012354~ 6 | N1*P5**FI*999888777~ 7 | N1*IN**FI*654456654~ 8 | INS*N*19*021*20*A***FT~ 9 | REF*0F*123456789~ 10 | REF*1L*123456001~ 11 | DTP*351*D8*19980515~ 12 | NM1*IL*1*DOE*JOHN*P***34*103229876~ 13 | DMG*D8*19770816*M~ 14 | NM1*M8*2*PENN STATE UNIVERSITY~ 15 | HD*021**HLT~ 16 | DTP*348*D8*19960601~ 17 | SE*15*0001~ 18 | GE*1*20213~ 19 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/add-subscriber-coverage.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | REF*38*ABCD012354~ 6 | N1*P5**FI*999888777~ 7 | N1*IN**FI*654456654~ 8 | INS*Y*18*001*22*A***FT~ 9 | REF*0F*123456789~ 10 | REF*1L*123456001~ 11 | NM1*IL*1*SMITH*WILLIAM****ZZ*2024433307~ 12 | HD*021**DEN~ 13 | DTP*348*D8*20020701~ 14 | SE*12*0001~ 15 | GE*1*20213~ 16 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/cancel-dependent.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | REF*38*ABCD012354~ 6 | N1*P5**FI*999888777~ 7 | N1*IN**FI*654456654~ 8 | INS*N*19*024*07*A~ 9 | REF*0F*123456789~ 10 | REF*1L*123456001~ 11 | DTP*357*D8*19960801~ 12 | NM1*IL*1*DOE*JAMES*E***34*103229876~ 13 | DMG*D8*19770816*M~ 14 | SE*12*0001~ 15 | GE*1*20213~ 16 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/change-subscriber-information.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | N1*P5**FI*999888777~ 6 | N1*IN**FI*654456654~ 7 | INS*Y*18*001*25*A***FT~ 8 | REF*0F*123456789~ 9 | REF*1L*123456001~ 10 | NM1*IL*1*DOE*JAMES****34*103229876~ 11 | DMG*D8*19500415*M~ 12 | NM1*70*1*DOE*JAMES*E~ 13 | DMG*D8*19500416*M~ 14 | SE*12*0001~ 15 | GE*1*20213~ 16 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/enroll-employee-managed-care.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | N1*P5**FI*999888777~ 6 | N1*IN**FI*654456654~ 7 | INS*Y*18*021*20*A***FT~ 8 | REF*0F*123456789~ 9 | REF*1L*123456001~ 10 | DTP*358*D8*19960523~ 11 | NM1*IL*1*SMITH*WILLIAM****34*202443307~ 12 | PER*IP**HP*7172343334*WP*7172341240~ 13 | N3*1715 SOUTHWIND AVENUE~ 14 | N4*ANYTOWN*PA*171110000~ 15 | DMG*D8*19700614*M~ 16 | HD*021**HMO~ 17 | DTP*348*D8*19960601~ 18 | LX*01~ 19 | NM1*P3*1*BROWN*BERNARD**DR**SV*143766*25~ 20 | SE*18*0001~ 21 | GE*1*20213~ 22 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/enroll-employee-multiple-products.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | N1*P5**FI*999888777~ 6 | N1*IN**FI*654456654~ 7 | INS*Y*18*021*20*A***FT~ 8 | REF*0F*123456789~ 9 | REF*1L*123456001~ 10 | DTP*356*D8*19960523~ 11 | NM1*IL*1*DOE*JOHN*P***34*123456789~ 12 | PER*IP**HP*7172343334*WP*7172341240~ 13 | N3*100 MARKET ST*APT 30~ 14 | N4*CAMP HILL*PA*17011**CY*CUMBERLAND~ 15 | DMG*D8*19400816*M~ 16 | HD*021**HLT~ 17 | DTP*348*D8*19960601~ 18 | HD*021**VIS~ 19 | DTP*348*D8*19960601~ 20 | SE*18*0001~ 21 | GE*1*20213~ 22 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/reinstate-employee-coverage-level.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | REF*38*ABCD012354~ 6 | N1*P5**FI*999888777~ 7 | N1*IN**FI*654456654~ 8 | INS*Y*18*025**A***FT~ 9 | REF*0F*202443307~ 10 | REF*1L*123456001~ 11 | NM1*IL*1*SMITH*WILLIAM****ZZ*202443307~ 12 | HD*025**DEN~ 13 | DTP*348*D8*20020701~ 14 | SE*12*0001~ 15 | GE*1*20213~ 16 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/reinstate-employee.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | REF*38*ABCD012354~ 6 | N1*P5**FI*999888777~ 7 | N1*IN**FI*654456654~ 8 | INS*Y*18*025*20*A***FT~ 9 | REF*0F*123456789~ 10 | REF*1L*123456001~ 11 | DTP*303*D8*19961001~ 12 | NM1*IL*1*DOE*JAMES*E***34*103229876~ 13 | SE*11*0001~ 14 | GE*1*20213~ 15 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/reinstate-member-eligiblity-ins.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*20020601*1200****2~ 5 | REF*38*ABCD012354~ 6 | N1*P5**FI*999888777~ 7 | N1*IN**FI*654456654~ 8 | INS*Y*18*025**A***FT~ 9 | REF*0F*202443307~ 10 | REF*1L*123456001~ 11 | NM1*IL*1*SMITH*WILLIAM****ZZ*202443307~ 12 | SE*10*0001~ 13 | GE*1*20213~ 14 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/834_005010X220A1/terminate-subscriber-eligibility.834: -------------------------------------------------------------------------------- 1 | ISA*00* *00* *ZZ*123456789012345*ZZ*123456789012346*080503*1705*>*00501*000010216*0*T*:~ 2 | GS*BE*1234567890*1234567890*20080503*1705*20213*X*005010X220A1~ 3 | ST*834*0001*005010X220A1~ 4 | BGN*00*12456*19980520*1200****2~ 5 | N1*P5**FI*999888777~ 6 | N1*IN**FI*654456654~ 7 | INS*Y*19*024*08*A***TE~ 8 | REF*0F*123456789~ 9 | REF*1L*123456001~ 10 | DTP*357*D8*19960801~ 11 | NM1*IL*1*DOE*JOHN*E***34*103229876~ 12 | SE*10*0001~ 13 | GE*1*20213~ 14 | IEA*1*000010216~ -------------------------------------------------------------------------------- /src/tests/resources/835_005010X221A1/cob-contractural-adjustment.835: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HP*000000005*54321*20131031*1147*1*X*005010X221A1~ 3 | ST*835*0001~ 4 | BPR*I*34.00*C*CHK***********20050318~ 5 | TRN*1*0063158ABC*1566339911~ 6 | REF*EV*030240928~ 7 | DTM*405*20050318~ 8 | N1*PR*YOUR TAX DOLLARS AT WORK~ 9 | N3*481A00 DEAR RUN ROAD~ 10 | N4*WEST PALM BCH*FL*11114~ 11 | N1*PE*ATONEWITHHEALTH*FI*3UR334563~ 12 | N3*3501 JOHNSON STREET~ 13 | N4*SUNSHINE*FL*12345~ 14 | REF*PQ*11861~ 15 | LX*1~ 16 | CLP*0001000055*2*541.00*34.00**12*50650619501~ 17 | NM1*QC*1*BURCK*RAYMOND*W***MI*987654321~ 18 | NM1*82*2*PROFESSIONAL TEST 1*****BS*34426~ 19 | DTM*232*20050202~ 20 | DTM*233*20050202~ 21 | SVC*HC>55669*541.00*34.00**1.00~ 22 | DTM*472*20050202~ 23 | CAS*OA*23*516.00~ 24 | CAS*OA*94*-9.00~ 25 | REF*1B*44280~ 26 | AMT*B6*550.00~ 27 | SE*25*0001~ 28 | GE*1*1~ 29 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/835_005010X221A1/managed-care.835: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HP*000000005*54321*20131031*1147*1*X*005010X221A1~ 3 | ST*835*112233~ 4 | BPR*I*945.00*C*ACH*CCP*01*888999777*DA*24681012*1935665544**01*111333555*DA*144444*20002316~ 5 | TRN*1*7170066655*1935665544~ 6 | DTM*405*20020314~ 7 | N1*PR*RUSHMORE LIFE~ 8 | N3*10 SOUTH AVENUE~ 9 | N4*RAPID CITY*SD*55111~ 10 | N1*PE*ACME MEDICAL CENTER*XX*5544667733~ 11 | REF*TJ*777667755~ 12 | LX*1~ 13 | CLP*5554555444*1*800.00*450.00*300.00*12*94060555410000~ 14 | CAS*CO*A2*50.00~ 15 | NM1*QC*1*BUDD*WILLIAM****MI*33344555510~ 16 | SVC*HC:99211*800.00*500.00~ 17 | DTM*150*20020301~ 18 | DTM*151*20020304~ 19 | CAS*PR*1*300.00~ 20 | CLP*8765432112*1*1200.00*495.00*600.00*12*94077799230000~ 21 | CAS*CO*A2*55.00~ 22 | NM1*QC*1*SETTLE*SUSAN****MI*44455666610~ 23 | SVC*HC:93555*1200.00*550.00~ 24 | DTM*150*20020310~ 25 | DTM*151*20020312~ 26 | CAS*PR*1*600.00~ 27 | CAS*CO*45*50.00~ 28 | SE*26*112233~ 29 | GE*1*1~ 30 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/835_005010X221A1/medicare-part-a.835: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HP*000000005*54321*20131031*1147*1*X*005010X221A1~ 3 | ST*835*1234~ 4 | BPR*C*150000.00*C*ACH*CTX*01*99999992*DA*123456*1512345678**01*999988880*DA*98765*20020913~ 5 | TRN*1*12345*1512345678~ 6 | DTM*405*20020916~ 7 | N1*PR*INSURANCE COMPANY OF TIMBUCKTU~ 8 | N3*1 MAIN STREET~ 9 | N4*TIMBUCKTU*AK*89111~ 10 | REF*2U*999~ 11 | N1*PE*REGIONAL HOPE HOSPITAL*XX*6543210903~ 12 | LX*110212~ 13 | TS3*6543210903*11*20021231*1*211366.97****138018.40**73348.57~ 14 | TS2*2178.45*1919.71**56.82*197.69*4.23~ 15 | CLP*666123*1*211366.97*138018.40**MA*1999999444444*11*1~ 16 | CAS*CO*45*73348.57~ 17 | NM1*QC*1*JONES*SAM*O***HN*666666666A~ 18 | MIA*0***138018.40~ 19 | DTM*232*20020816~ 20 | DTM*233*20020824~ 21 | QTY*CA*8.00~ 22 | LX*130212~ 23 | TS3*6543210909*13*19961231*1*15000.00****11980.33**3019.67~ 24 | CLP*777777*1*15000.00*11980.33**MB*1999999444445*13*1~ 25 | CAS*CO*45*3019.67~ 26 | NM1*QC*1*BORDER*LIZ*E***HN*996669999B~ 27 | MOA***MA02~ 28 | DTM*232*20020512~ 29 | PLB*6543210903*20021231*CV:CP*-1.27~ 30 | SE*28*1234~ 31 | GE*1*1~ 32 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/835_005010X221A1/secondary-payment.835: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HP*000000005*54321*20131031*1147*1*X*005010X221A1~ 3 | ST*835*1234~ 4 | BPR*I*1222.00*C*CHK***********20050412~ 5 | TRN*1*0012524965*1559123456~ 6 | REF*EV*030240928~ 7 | DTM*405*20050412~ 8 | N1*PR*YOUR TAX DOLLARS AT WORK~ 9 | N3*481A00 DEAR RUN ROAD~ 10 | N4*WEST PALM BCH*FL*11114~ 11 | N1*PE*ACME MEDICAL CENTER*FI*599944521~ 12 | N3*PO BOX 863382~ 13 | N4*ORLANDO*FL*55115~ 14 | REF*PQ*10488~ 15 | LX*1~ 16 | CLP*L0004828311*2*10323.64*912.00**12*05090256390*11*1~ 17 | CAS*OA*23*9411.64~ 18 | NM1*QC*1*TOWNSEND*WILLIAM*P***MI*XXX123456789~ 19 | NM1*82*2*ACME MEDICAL CENTER*****BD*987~ 20 | DTM*232*20050303~ 21 | DTM*233*20050304~ 22 | AMT*AU*912.00~ 23 | LX*2~ 24 | CLP*0001000053*2*751.50*310.00*220.00*12*05630626430~ 25 | NM1*QC*1*BAKI*ANGI****MI*456789123~ 26 | NM1*82*2*SMITH JONES PA*****BS*34426~ 27 | DTM*232*20050106~ 28 | DTM*233*20050106~ 29 | SVC*HC>12345>26*166.50*30.00**1.00~ 30 | DTM*472*20050106~ 31 | CAS*OA*23*136.50~ 32 | REF*1B*43285~ 33 | AMT*B6*150.00~ 34 | SVC*HC>66543>26*585.00*280.00*220*1.00~ 35 | DTM*472*20050106~ 36 | CAS*PR*1*150.00**2*70.00~ 37 | CAS*CO*42*85.00~ 38 | REF*1B*43285~ 39 | AMT*B6*500.00~ 40 | SE*38*1234~ 41 | GE*1*1~ 42 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/835_005010X221A1/tertiary-payment.835: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HP*000000005*54321*20131031*1147*1*X*005010X221A1~ 3 | ST*835*0001~ 4 | BPR*I*187.50*C*CHK***********20050412~ 5 | TRN*1*0012524879*1559123456~ 6 | REF*EV*030240928~ 7 | DTM*405*20050412~ 8 | N1*PR*YOUR TAX DOLLARS AT WORK~ 9 | N3*481A00 DEAR RUN ROAD~ 10 | N4*WEST PALM BCH*FL*11114~ 11 | N1*PE*ACME MEDICAL CENTER*FI*599944521~ 12 | N3*PO BOX 863382~ 13 | N4*ORLANDO*FL*55115~ 14 | REF*PQ*10488~ 15 | LX*1~ 16 | CLP*0001000054*3*1766.50*187.50**12*50580155533~ 17 | NM1*QC*1*ISLAND*ELLIS*E***MI*789123456~ 18 | NM1*82*2*JONES JONES ASSOCIATES*****BS*AB34U~ 19 | DTM*232*20050120~ 20 | SVC*HC*24599.00*1766.50*187.50**1~ 21 | DTM*472*20050120~ 22 | CAS*OA*23*1579.00~ 23 | REF*1B*44280~ 24 | AMT*B6*1700.00~ 25 | SE*23*0001~ 26 | GE*1*1~ 27 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X096A1/automobile-accident.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X096A1~ 3 | ST*837*987185~ 4 | BHT*0019*00*0324*19970331*1800*CH~ 5 | REF*87*004010X096~ 6 | NM1*41*2*INSURANCE CARRIER*****46*3214~ 7 | PER*IC*JANE DOE*TE*9005555555~ 8 | NM1*40*2*CBO*****46*1234~ 9 | HL*1**20*1~ 10 | PRV*BI*ZZ*203BA0200N~ 11 | NM1*85*2*HALL OF FAME MEMORIAL HOSPITAL*****XX*888HF444~ 12 | N3*1 CANTON ROAD~ 13 | N4*BROKEN FIELD*CA*99998~ 14 | REF*1J*737373737~ 15 | HL*2*1*22*1~ 16 | SBR*P********AM~ 17 | NM1*IL*1*HOWLING*HAL****MI*B999777791G~ 18 | N3*327 BRONCO DRIVE~ 19 | N4*GETAWAY*CA*99999~ 20 | NM1*PR*2*HEISMAN INSURANCE COMPANY*****XV*999888777~ 21 | HL*3*2*23*0~ 22 | PAT*41~ 23 | NM1*QC*1*DIMPSON*DJ****MI*000000032~ 24 | N3*32 BUFFALO RUN~ 25 | N4*ROCKING HORSE*CA*99666~ 26 | DMG*D8*19480601*M~ 27 | REF*1W*32323232~ 28 | CLM*6721*545.00***13:A:1***Y*Y~ 29 | DTP*434*D8*19970318~ 30 | CL1*3*7*1~ 31 | HI*BK:884.2**BN:E986.0~ 32 | HI*BK:884.2**BN:E986.0~ 33 | NM1*71*1*LOMBARDO*VINCENT****XX*777TD777~ 34 | LX*1~ 35 | SV2*450*HC:98765*150.00*UN*1.00~ 36 | DTP*472*D8*19940617~ 37 | LX*2~ 38 | SV2*360*HC:26591*75.00*UN*1.00~ 39 | DTP*472*D8*19970318~ 40 | LX*3~ 41 | SV2*312*HC:86225*100.00*UN*2.00~ 42 | DTP*472*D8*19940318~ 43 | LX*4~ 44 | SV2*360*HC:99283*220.00*UN*1.00~ 45 | DTP*472*D8*19940318~ 46 | SE*44*987185~ 47 | GE*1*1~ 48 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X096A1/homeowners.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X096A1~ 3 | ST*837*987183~ 4 | BHT*0019*00*0123*19970327*1410*CH~ 5 | REF*87*004010X096~ 6 | NM1*41*2*INSURANCE CARRIER*****46*3214~ 7 | PER*IC*JANE DOE*TE*9005555555~ 8 | NM1*40*2*CBO*****46*1234~ 9 | HL*1**20*1~ 10 | PRV*BI*ZZ*203BA0200N~ 11 | NM1*85*2*DUFFER’S MEMORIAL HOSPITAL*****XX*111DM222~ 12 | N3*541 DOGLEG DRIVE~ 13 | N4*GOLFERS HAVEN*FL*91919~ 14 | REF*1J*444661111~ 15 | HL*2*1*22*1~ 16 | SBR*P********LI~ 17 | NM1*IL*1*NORTON*GRAIG****MI*970925824~ 18 | N3*72 FAIRWAY DRIVE~ 19 | N4*GOLFERS HAVEN*FL*91919~ 20 | NM1*PR*2*LAST CHANCE INSURANCE COMPANY*****XV*123456789~ 21 | HL*3*2*23*0~ 22 | PAT*41~ 23 | NM1*QC*1*CLIFTON*WILLIAM****MI*686868686~ 24 | N3*1600 RAZORBACK AVENUE~ 25 | N4*LITTLE ROCK*AR*54321~ 26 | DMG*D8*19491013*M~ 27 | REF*1W*88N522371~ 28 | CLM*67129*450.00***13:A:1***Y*Y~ 29 | DTP*434*D8*19970318~ 30 | CL1*3*7*1~ 31 | HI*BK:922.3*BF:847.2~ 32 | NM1*71*1*ZEUSS*THEODORE****XX*999DS427~ 33 | PRV*AT*ZZ*363LP0200N~ 34 | NM1*73*1*FLOOD*RAY****XX*671RF535~ 35 | LX*1~ 36 | SV2*450*HC:98765*75.00*UN*1.00~ 37 | DTP*472*D8*19970318~ 38 | LX*2~ 39 | SV2*320*HC:72110*150.00*UN*1.00~ 40 | DTP*472*D8*19970318~ 41 | LX*3~ 42 | SV2*360*HC:99282*225.00*UN*1.00~ 43 | DTP*472*D8*19970318~ 44 | SE*42*987183~ 45 | GE*1*1~ 46 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X096A1/institutional-ppo-repriced.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X096A1~ 3 | ST*837*987655~ 4 | BHT*0019*00*0124*19970103*0936*CH~ 5 | REF*87*004010X096~ 6 | NM1*41*2*HEALTHCARE PPO*****46*TGJ23~ 7 | PER*IC*JANE DOE*TE*9005555555~ 8 | NM1*40*2*KEY INSURANCE COMPANY*****46*962TT8R~ 9 | HL*1**20*1~ 10 | PRV*BI*ZZ*203BA0200N~ 11 | NM1*85*2*GENERAL HOSPITAL*****XX*370673111~ 12 | N3*125 VIRGINIA AVE~ 13 | N4*BLOOMINGTON*IL*61701~ 14 | HL*2*1*22*1~ 15 | SBR*P********CI~ 16 | NM1*IL*1*BOZARTH*LANCE*D***MI*32762113503~ 17 | N3*5707 FERN FLOWER DR~ 18 | N4*COLUMBIA*MO*65202~ 19 | REF*SY*327621135~ 20 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*66783JJT~ 21 | HL*3*2*23*0~ 22 | PAT*01~ 23 | NM1*QC*1*BOZARTH*MAGGIE*B~ 24 | N3*5707 FERN FLOWER DR~ 25 | N4*COLUMBIA*MO*65202~ 26 | DMG*D8*19691125*F~ 27 | REF*SY*329524430~ 28 | CLM*72255589*2593.69***11:A:1***Y*Y~ 29 | DTP*434*RD8*19961222-19961224~ 30 | DTP*435*DT*199612220930~ 31 | DTP*096*TM*199612221630~ 32 | CL1*3*1*01~ 33 | REF*9A*6003E0332701~ 34 | HI*BK:643.03~ 35 | QTY*CA*2.00*DA~ 36 | HCP*06*2040.00*553.69*252665599~ 37 | NM1*71*1*NORDSTRUM*HAROLD****XX*572999543~ 38 | PRV*AT*ZZ*363LP0200N~ 39 | LX*1~ 40 | SV2*120**802.00*DA*2.00~ 41 | LX*2~ 42 | SV2*250**354.49*UN*1.00~ 43 | LX*3~ 44 | SV2*258**949.68*UN*1.00~ 45 | LX*4~ 46 | SV2*270**112.02*UN*1.00~ 47 | LX*5~ 48 | SV2*300**375.50*UN*1.00~ 49 | SE*47*987655~ 50 | GE*1*1~ 51 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X096A1/institutional.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X096A1~ 3 | ST*837*987654~ 4 | BHT*0019*00*0123*19960918*0932*CH~ 5 | REF*87*004010X096~ 6 | NM1*41*2*MEDICARE*****46*00120~ 7 | PER*IC*JANE DOE*TE*9005555555~ 8 | NM1*40*2*JONES HOSPITAL*****46*12345~ 9 | HL*1**20*1~ 10 | PRV*BI*ZZ*203BA0200N~ 11 | NM1*85*2*JONES HOSPITAL*****XX*330127~ 12 | N3*225 MAIN STREET BARKLEY BUILDING~ 13 | N4*CENTERVILLE*PA*17111~ 14 | REF*G2*987654080~ 15 | HL*2*1*22*0~ 16 | SBR*P*18*******MB~ 17 | NM1*IL*1*DOE*JOHN*T***MI*030005074A~ 18 | N3*125 CITY AVENUE~ 19 | N4*CENTERVILLE*PA*17111~ 20 | DMG*D8*19261111*M~ 21 | NM1*PR*2*MEDICARE B*****PI*00435~ 22 | CLM*756048Q*89.93***14:A:1**A*Y*Y~ 23 | DTP*434*D8*19960911~ 24 | CL1*3*1~ 25 | HI*BK:366.9~ 26 | HI*BF:401.9*BF:794.31~ 27 | HI*BQ:15.3:D8:19960911~ 28 | HI*BH:A1:D8:19261111*BH:A2:D8:19911101*BH:B1:D8:19261111*BH:B2:D8:19870101~ 29 | HI*BE:A2:::15.31~ 30 | HI*BG:09~ 31 | NM1*71*1*JONES*JOHN*J***XX*B99937~ 32 | PRV*AT*ZZ*363LP0200N~ 33 | SBR*S*01*351630*STATE TEACHERS*GP****CI~ 34 | DMG***F~ 35 | OI***Y***Y~ 36 | NM1*IL*1*DOE*JANE*S***MI*222004433~ 37 | N3*125 CITY AVENUE~ 38 | N4*CENTERVILLE*PA*17111~ 39 | NM1*PR*2*STATE TEACHERS*****PI*1135~ 40 | LX*1~ 41 | SV2*305*HC:85025*13.39*UN*1.00~ 42 | DTP*472*D8*19960911~ 43 | LX*2~ 44 | SV2*730*HC:93005*76.54*UN*3.00~ 45 | DTP*472*D8*19960911~ 46 | SE*44*987654~ 47 | GE*1*1~ 48 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X096A1/workers-compensation.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X096A1~ 3 | ST*837*987184~ 4 | BHT*0019*00*0124*19970331*1020*CH~ 5 | REF*87*004010X096~ 6 | NM1*41*2*PISTACHIO COMMUNITY HOSPITAL*****46*877196543~ 7 | PER*IC*JANE DOE*TE*9005555555~ 8 | NM1*40*2*CBO*****46*1234~ 9 | HL*1**20*1~ 10 | PRV*BI*ZZ*203BA0200N~ 11 | NM1*85*2*PISTACHIO COMMUNITY HOSPITAL*****XX*222PC333~ 12 | N3*300 CHOLESTEROL COURT~ 13 | N4*PISTACHIO*VT*55557~ 14 | REF*1J*877196543~ 15 | HL*2*1*22*1~ 16 | SBR*P********WC~ 17 | NM1*IL*2*JEN & BARRY’S ICE CREAM SHOPPE*****MI*WC962222L~ 18 | N3*123 ROCKY ROAD~ 19 | N4*CHERRY*VT*55555~ 20 | NM1*PR*2*BASKET & ROBERTS INSURANCE COMPANY*****XV*345345345~ 21 | HL*3*2*23*0~ 22 | PAT*20~ 23 | NM1*QC*1*PLUMP*PENNY****MI*888228888~ 24 | N3*265 DOUBLE DIP LANE~ 25 | N4*SUGAR CONE*VT*55544~ 26 | DMG*D8*19770211*F~ 27 | REF*1W*W9123499~ 28 | CLM*67188*350.00***13:A:1***Y*Y~ 29 | DTP*434*D8*19970318~ 30 | CL1*3*7*1~ 31 | HI*BK:816.02~ 32 | HI*BF:354.0~ 33 | HI*BR:79.04:D8:19970212~ 34 | NM1*71*1*SWEETTOOTH*SAM****XX*777ST123~ 35 | NM1*73*1*GAMMA*RAY****XX*555XR321~ 36 | LX*1~ 37 | SV2*450.00*HC:98765*100.00*UN*1.00~ 38 | DTP*472*D8*19970212~ 39 | LX*2~ 40 | SV2*320.00*HC:73140*50.00*UN*1.00~ 41 | DTP*472*D8*19970212~ 42 | LX*3~ 43 | SV2*360.00*HC:99283*200.00*UN*1.00~ 44 | DTP*472*D8*19970212~ 45 | SE*43*987184~ 46 | GE*1*1~ 47 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X098A1/coordination-of-benefits.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X098A1~ 3 | ST*837*0002~ 4 | BHT*0019*00*0123*19981015*1023*CH~ 5 | REF*87*004010X098~ 6 | NM1*41*2*PREMIER BILLING SERVICE*****46*567890~ 7 | PER*IC*JERRY*TE*3055552222~ 8 | NM1*40*2*XYZ REPRICER*****46*66783JJT~ 9 | HL*1**20*1~ 10 | NM1*85*2*PREMIER BILLING SERVICE*****24*587654321~ 11 | N3*1234 SEAWAY ST~ 12 | N4*MIAMI*FL*33111~ 13 | REF*G2*TGJ23~ 14 | PER*IC*CONNIE*TE*3055551234~ 15 | NM1*87*2*KILDARE ASSOC*****24*581234567~ 16 | N3*2345 OCEAN BLVD~ 17 | N4*MIAMI*FL*33111~ 18 | REF*G2*99878ABA~ 19 | HL*2*1*22*1~ 20 | SBR*P********CI~ 21 | NM1*IL*1*SMITH*JANE****MI*111223333~ 22 | DMG*D8*19430501*F~ 23 | REF*1W*JS00111223333~ 24 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~ 25 | N3*3333OCEAN ST~ 26 | N4*SOUTH MIAMI*FL*33000~ 27 | HL*3*2*23*0~ 28 | PAT*19~ 29 | NM1*QC*1*SMITH*TED****MI*JS01111223333~ 30 | N3*236N MAIN ST~ 31 | N4*MIAMI*FL*33413~ 32 | DMG*D8*19730501*M~ 33 | REF*SY*000221111~ 34 | CLM*26407789*79.04***11::1*Y*A*Y*Y*B~ 35 | HI*BK:4779*BF:2724*BF:2780*BF:53081~ 36 | NM1*82*1*KILDARE*BEN****24*999996666~ 37 | PRV*PE*ZZ*203BF0100Y~ 38 | REF*G2*KA6663~ 39 | NM1*77*2*KILDARE ASSOCIATES*****24*581234567~ 40 | N3*2345 OCEAN BLVD~ 41 | N4*MIAMI*FL*33111~ 42 | LX*1~ 43 | SV1*HC:99213*43.00*UN*1.00***1:2:3:4~ 44 | DTP*472*D8*19971003~ 45 | LX*2~ 46 | SV1*HC:90782*15.00*UN*1.00***1:2~ 47 | DTP*472*D8*19971003~ 48 | LX*3~ 49 | SV1*HC:J3301*21.04*UN*1.00***1:2~ 50 | DTP*472*D8*19971003~ 51 | SE*49*0002~ 52 | GE*1*1~ 53 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X098A1/dependent-commercial-insurance-01.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X098A1~ 3 | ST*837*872391~ 4 | BHT*0019*00*0123*19970410*1339*CH~ 5 | REF*87*004010X098~ 6 | NM1*41*2*PRESIDENTIAL CHIROPRACTIC*****46*777BH666~ 7 | PER*IC*LARRY*TE*3215556677~ 8 | NM1*40*2*LAST CHANCE INSURANCE COMPANY*****46*123456789~ 9 | HL*1**20*1~ 10 | NM1*85*2*PRESIDENTIAL CHIROPRACTIC*****XX*777BH666~ 11 | N3*5 LUMBAR LANE~ 12 | N4*GOLFERS HAVEN*FL*91919~ 13 | REF*EI*222559999~ 14 | PER*IC*SUSAN*TE*3215557777~ 15 | HL*2*1*22*1~ 16 | SBR*P********LM~ 17 | NM1*IL*1*NORTON*GRAIG****MI*970925824~ 18 | NM1*PR*2*LAST CHANCE INSURANCE COMPANY*****XV*123456789~ 19 | N3*1 DESERT LINE ROAD~ 20 | N4*RENO*NV*44544~ 21 | HL*3*2*23*0~ 22 | PAT*41~ 23 | NM1*QC*1*CLIFTON*WILLIAM****MI*234557329~ 24 | N3*1600 RAZORBACK AVENUE~ 25 | N4*LITTLE ROCK*AR*54321~ 26 | DMG*D8*19491013*M~ 27 | REF*Y4*88N522371~ 28 | CLM*686868686*245.00***11::1.00*Y*A*Y*Y*B*OA~ 29 | DTP*454*D8*19970318~ 30 | DTP*439*D8*19970317~ 31 | CR2*1*1.00***DA*1.00*1.00*A*Y***Y~ 32 | HI*BK:8472~ 33 | NM1*DN*1*ZEUSS*THEODORE****XX*999DS427~ 34 | PRV*RF*ZZ*203BF0100Y~ 35 | NM1*82*1*DONALD*MACK****XX*999OU812~ 36 | PRV*PE*ZZ*111NS0005N~ 37 | REF*EI*311235689~ 38 | LX*1~ 39 | SV1*HC:99204*60.00*UN*1.00***1~ 40 | DTP*472*D8*19970318~ 41 | LX*2~ 42 | SV1*HC:72100*75.00*UN*1.00***1~ 43 | DTP*472*D8*19970318~ 44 | LX*3~ 45 | SV1*HC:97010*25.00*UN*1.00***1~ 46 | DTP*472*D8*19970318~ 47 | LX*4~ 48 | SV1*HC:97014*25.00*UN*1.00***1~ 49 | DTP*472*D8*19970318~ 50 | LX*5~ 51 | SV1*HC:97124*35.00*UN*1.00***1~ 52 | DTP*472*D8*19970318~ 53 | LX*6~ 54 | SV1*HC:97035*25.00*UN*1.00***1~ 55 | DTP*472*D8*19970318~ 56 | SE*54*872391~ 57 | GE*1*1~ 58 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X098A1/dependent-commercial-insurance-02.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X098A1~ 3 | ST*837*872401~ 4 | BHT*0019*00*0124*19970411*0724*CH~ 5 | REF*87*004010X098~ 6 | NM1*41*2*SPEEDY BILLING SERVICE*****46*333119999~ 7 | PER*IC*SAM SPEEDY*TE*8154445555~ 8 | NM1*40*2*BASKET & ROBERTS INSURANCE COMPANY*****46*345345345~ 9 | HL*1**20*1~ 10 | NM1*85*2*SPEEDY BILLING SERVICE*****24*333119999~ 11 | N3*1 EDI WAY~ 12 | N4*WALNUT*VT*55333~ 13 | NM1*87*1*SWEETTOOTH*SAM****XX*777ST123~ 14 | N3*837 PROFESSIONAL DRIVE~ 15 | N4*PISTACHIO*VT*55557~ 16 | REF*EI*331330001~ 17 | REF*G2*331330001~ 18 | HL*2*1*22*1~ 19 | SBR*P********WC~ 20 | NM1*IL*2*JEN & BARRY’S ICE CREAM SHOPPE*****MI*WC962222L~ 21 | NM1*PR*2*BASKET & ROBERTS INSURANCE COMPANY*****XV*345345345~ 22 | N3*31 FLAVOR STREET~ 23 | N4*MAPLE*VT*55222~ 24 | HL*3*2*23*0~ 25 | PAT*20~ 26 | NM1*QC*1*PLUMP*PENNY****MI*115683870~ 27 | N3*265 DOUBLE DIP LANE~ 28 | N4*SUGAR CONE*VT*55544~ 29 | DMG*D8*19770211*F~ 30 | REF*Y4*W9123499~ 31 | CLM*888228888*405.00***11::1*Y*A*Y*Y*B*EM:OA~ 32 | DTP*439*D8*19970212~ 33 | DTP*454*D8*19970212~ 34 | HI*BK:81602*BF:354~ 35 | NM1*82*1*SWEETTOOTH*SAM****XX*777ST123~ 36 | PRV*PE*ZZ*203BE004Y~ 37 | REF*EI*331330001~ 38 | NM1*77*2*PISTACHIO EMERGENCY SERVICES*****XX*ERP66655~ 39 | N3*123 EMERGENCY WAY~ 40 | N4*PISTACHIO*VT*55556~ 41 | LX*1~ 42 | SV1*HC:99242*120.00*UN*1.00***1**Y~ 43 | DTP*472*D8*19970226~ 44 | LX*2~ 45 | SV1*HC:A4570*25.00*UN*1.00***1**Y~ 46 | DTP*472*D8*19970226~ 47 | LX*3~ 48 | SV1*HC:73140*50.00*UN*1.00***1**Y~ 49 | DTP*472*D8*19970226~ 50 | LX*4~ 51 | SV1*HC:99283*210.00*UN*1.00*23**1:2**Y~ 52 | DTP*472*D8*19970212~ 53 | SE*51*872401~ 54 | GE*1*1~ 55 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X098A1/dependent-commercial-insurance-03.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X098A1~ 3 | ST*837*872501~ 4 | BHT*0019*00*0125*19970411*1524*CH~ 5 | REF*87*004010X098~ 6 | NM1*41*2*FERMANN HAND & FOOTCLINIC*****46*591PD123~ 7 | PER*IC*JAN FOOT*TE*8156667777~ 8 | NM1*40*2*HEISMAN INSURANCE COMPANY*****46*555667777~ 9 | HL*1**20*1~ 10 | NM1*85*2*FERMANN HAND & FOOTCLINIC*****XX*591PD123~ 11 | N3*10 1/2 SHOEMAKER STREET~ 12 | N4*COBBLER*CA*99997~ 13 | REF*EI*579999999~ 14 | HL*2*1*22*1~ 15 | SBR*P********AM~ 16 | NM1*IL*1*HOWLING*HAL****MI*B99977791G~ 17 | NM1*PR*2*HEISMAN INSURANCE COMPANY*****XV*999888777~ 18 | N3*1 TROPHY LANE~ 19 | N4*NYAC*NY*10032~ 20 | HL*3*2*23*0~ 21 | PAT*41~ 22 | NM1*QC*1*DIMPSON*DJ****MI*567324788~ 23 | N3*32 BUFFALO RUN~ 24 | N4*ROCKING HORSE*CA*99666~ 25 | DMG*D8*19480601*M~ 26 | REF*Y4*32323232~ 27 | CLM*900000032*185.00***11::1*Y*A*Y*Y*B*AA~ 28 | DTP*439*D8*19940617~ 29 | HI*BK:8842~ 30 | NM1*82*1*MOGLIE*BRUNO****XX*687AB861~ 31 | PRV*PE*ZZ*203BE004Y~ 32 | NM1*77*2*FERMANN HAND & FOOT CLINIC*****XX*591PD123~ 33 | N3*10 1/2 SHOEMAKER STREET~ 34 | N4*COBBLER*CA*99997~ 35 | LX*1~ 36 | SV1*HC:99201*150.00*UN*1.00***1**Y~ 37 | DTP*472*D8*19940620~ 38 | LX*2~ 39 | SV1*HC:26010*35.00*UN*1.00***1**Y~ 40 | DTP*472*D8*19940620~ 41 | SE*39*872501~ 42 | GE*1*1~ 43 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X098A1/patient-is-dependent.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X098A1~ 3 | ST*837*3456~ 4 | BHT*0019*00*244579*19981015*1023*CH~ 5 | REF*87*004010X098~ 6 | NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~ 7 | PER*IC*JERRY*TE*3055552222*EX*231~ 8 | NM1*40*2*XYZ REPRICER*****46*66783JJT~ 9 | HL*1**20*1~ 10 | NM1*85*2*PREMIER BILLING SERVICE*****24*587654321~ 11 | N3*234 SEAWAY ST~ 12 | N4*MIAMI*FL*33111~ 13 | REF*G2*PBS3334~ 14 | NM1*87*2*KILDARE ASSOC*****24*581234567~ 15 | N3*2345OCEAN BLVD~ 16 | N4*MAIMI*FL*33111~ 17 | REF*G2*99878-ABA~ 18 | HL*2*1*22*1~ 19 | SBR*P**2222-SJ******CI~ 20 | NM1*IL*1*SMITH*JANE****MI*11223333~ 21 | DMG*D8*19430501*F~ 22 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~ 23 | N3*3333 OCEAN ST~ 24 | N4*SOUTH MIAMI*FL*33000~ 25 | HL*3*2*23*0~ 26 | PAT*19~ 27 | NM1*QC*1*SMITH*TED****MI*JS01111223333~ 28 | N3*236 N MAIN ST~ 29 | N4*MIAMI*FL*33413~ 30 | DMG*D8*19730501*M~ 31 | REF*SY*000221111~ 32 | CLM*26463774*100.00***11::1*Y*A*Y*Y*S~ 33 | REF*D9*17312345600006351~ 34 | HI*BK:0340*BF:V7389~ 35 | NM1*82*1*KILDARE*BEN****24*999996666~ 36 | PRV*PE*ZZ*203BF0100Y~ 37 | REF*G2*KA6663~ 38 | NM1*77*2*KILDARE ASSOCIATES*****24*581234567~ 39 | N3*2345 OCEAN BLVD~ 40 | N4*MIAMI*FL*33111~ 41 | LX*1~ 42 | SV1*HC:99213*40.00*UN*1.00***1~ 43 | DTP*472*D8*19981003~ 44 | LX*2~ 45 | SV1*HC:87072*15.00*UN*1.00***1~ 46 | DTP*472*D8*19981003~ 47 | LX*3~ 48 | SV1*HC:99214*35.00*UN*1.00***2~ 49 | DTP*472*D8*19981010~ 50 | LX*4~ 51 | SV1*HC:86663*10.00*UN*1.00***2~ 52 | DTP*472*D8*19981010~ 53 | SE*51*3456~ 54 | GE*1*1~ 55 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_004010X098A1/patient-is-subscriber.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*004010X098A1~ 3 | ST*837*0021~ 4 | BHT*0019*00*0123*19981015*1023*RP~ 5 | REF*87*004010X098~ 6 | NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~ 7 | PER*IC*JERRY*TE*3055552222*EX*231~ 8 | NM1*40*2*REPRICER XYZ*****46*66783JJT~ 9 | HL*1**20*1~ 10 | NM1*85*2*PREMIER BILLING SERVICE*****24*587654321~ 11 | N3*234 Seaway St~ 12 | N4*Miami*FL*33111~ 13 | NM1*87*2*KILDAREASSOC*****24*581234567~ 14 | N3*2345 OCEAN BLVD~ 15 | N4*MIAMI*FL*33111~ 16 | HL*2*1*22*0~ 17 | SBR*P*18*12312-A******HM~ 18 | NM1*IL*1*SMITH*TED****MI*000221111~ 19 | N3*236 N MAIN ST~ 20 | N4*MIAMI*FL*33413~ 21 | DMG*D8*19430501*M~ 22 | NM1*PR*2*ALLIANCE HEALTH AND LIFE INSURANCE*****PI*741234~ 23 | CLM*26462967*100.00***11::1*Y*A*Y*Y*C~ 24 | DTP*431*D8*19981003~ 25 | REF*D9*17312345600006351~ 26 | HI*BK:0340*BF:V7389~ 27 | NM1*82*1*KILDARE*BEN****34*112233334~ 28 | PRV*PE*ZZ*203BF0100Y~ 29 | NM1*77*2*KILDARE ASSOCIATES*****24*581234567~ 30 | N3*2345 OCEAN BLVD~ 31 | N4*MIAMI*FL*33111~ 32 | LX*1~ 33 | SV1*HC:99213*40.00*UN*1.00***1~ 34 | DTP*472*D8*19981003~ 35 | LX*2~ 36 | SV1*HC:87072*15.00*UN*1.00***1~ 37 | DTP*472*D8*19981003~ 38 | LX*3~ 39 | SV1*HC:99214*35.00*UN*1.00***2~ 40 | DTP*472*D8*19981010~ 41 | LX*4~ 42 | SV1*HC:86663*10.00*UN*1.00***2~ 43 | DTP*472*D8*19981010~ 44 | SE*42*0021~ 45 | GE*1*1~ 46 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.ambulance.example5.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*000017712*005010X222A2~ 4 | BHT*0019*00*000017712*20050208*1112*CH~ 5 | NM1*41*2*AAA AMBULANCE SERVICE*****46*376985369~ 6 | PER*IC*LISA SMITH*TE*3037752536~ 7 | NM1*40*2*MEDICARE B*****46*123245~ 8 | HL*1**20*1~ 9 | PRV*BI*PXC*3416L0300X~ 10 | NM1*85*2*AAA AMBULANCE SERVICE*****XX*2366554859~ 11 | N3*12202 AIRPORT WAY~ 12 | N4*BROOMFIELD*CO*800210021~ 13 | REF*EI*376985369~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*******MB~ 16 | NM1*IL*1*JONES*SARAH*A***MI*012345678A~ 17 | N3*1129 REINDEER ROAD~ 18 | N4*CARR*CO*80612~ 19 | DMG*D8*19630729*F~ 20 | NM1*PR*2*MEDICARE PART B*****PI*123245~ 21 | N3*PO BOX 3543~ 22 | N4*BALTIMORE*MD*666013543~ 23 | CLM*051068*766.50***41::1*Y*A*Y*Y*P*OA~ 24 | DTP*439*D8*20050208~ 25 | CR1*LB*275.00**A*DH*21.00****PATIENT IMOBILIZED~ 26 | CRC*07*Y*04*06*09~ 27 | CRC*07*N*05*07*08~ 28 | HI*BK:8628*BF:E8888*BF:9592*BF:8540~ 29 | NM1*PW*2~ 30 | N3*1129 REINDEER ROAD~ 31 | N4*CARR*CO*80612~ 32 | NM1*45*2~ 33 | N3*10005 BANNOCK ST~ 34 | N4*CHEYENNE*WY*82009~ 35 | LX*1~ 36 | SV1*HC:A0427:RH*700.00*UN*1.00***1:2:3:4**Y~ 37 | DTP*472*D8*20050208~ 38 | QTY*PT*2.00~ 39 | REF*6R*1001~ 40 | NTE*ADD*CARDIAC EMERGENCY~ 41 | LX*2~ 42 | SV1*HC:A0425:RH*8.20*UN*21.00***1:2:3:4**Y~ 43 | DTP*472*D8*20050208~ 44 | QTY*PT*2.00~ 45 | REF*6R*1002~ 46 | LX*3~ 47 | SV1*HC:A0422:RH*46.00*UN*1.00***1:2:3:4**Y~ 48 | DTP*472*D8*20050208~ 49 | REF*6R*1003~ 50 | LX*4~ 51 | SV1*HC:A0382:RH*12.30*UN*1.00***1:2:3:4**Y~ 52 | DTP*472*D8*20050208~ 53 | REF*6R*1004~ 54 | SE*52*000017712~ 55 | GE*1*1~ 56 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.autoaccident.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0021*005010X222A2~ 4 | BHT*0019*00*0125*20051111*1524*CH~ 5 | NM1*41*2*ASSOCIATED MEDICAL GROUP*****46*1253695747~ 6 | PER*IC*JANICE HENDRIX*TE*2125557987~ 7 | NM1*40*2*HEISMAN INSURANCE COMPANY*****46*999888777~ 8 | HL*1**20*1~ 9 | NM1*85*2*ASSOCIATED MEDICAL GROUP*****XX*1253695747~ 10 | N3*10 1/2 SHOEMAKER STREET~ 11 | N4*COBBLER*CA*99997~ 12 | REF*EI*579999999~ 13 | HL*2*1*22*1~ 14 | SBR*P********AM~ 15 | NM1*IL*1*HOWLING*HAL****MI*B99977791G~ 16 | NM1*PR*2*HEISMAN INSURANCE COMPANY*****PI*999888777~ 17 | HL*3*2*23*0~ 18 | PAT*21~ 19 | NM1*QC*1*DIMPSON*DJ~ 20 | N3*32 BUFFALO RUN~ 21 | N4*ROCKING HORSE*CA*99666~ 22 | DMG*D8*19480601*M~ 23 | REF*Y4*32323232~ 24 | PER*IC*DJ DIMPSON*TE*8157665902~ 25 | CLM*900000032*185.00***11:B:1*Y*A*Y*Y**AA:::CA~ 26 | DTP*439*D8*20051031~ 27 | DTP*444*D8*20051031~ 28 | HI*BK:8540~ 29 | NM1*82*1*MOGLIE*BRUNO****XX*2366552595~ 30 | PRV*PE*PXC*208D00000X~ 31 | NM1*77*2*ASSOCIATED MEDICAL GROUP*****XX*1235767887~ 32 | N3*101 EAST PRYOR STREET~ 33 | N4*LOMA LINDA*CA*99622~ 34 | PER*IC*KAREN SPARKLE*TE*3425557987~ 35 | LX*1~ 36 | SV1*HC:99201*150.00*UN*1.00***1**Y~ 37 | DTP*472*D8*20051031~ 38 | LX*2~ 39 | SV1*HC:26010*35.00*UN*1.00***1**Y~ 40 | DTP*472*D8*20051031~ 41 | SE*39*0021~ 42 | GE*1*1~ 43 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.cob.2ndary.example4.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*3701*005010X222A2~ 4 | BHT*0019*00*007227*20050215*075420*CH~ 5 | NM1*41*2*DAVID GREEN*****46*S01057~ 6 | PER*IC*KATHY SMITH*TE*4105558888~ 7 | NM1*40*2*MEDICARE PART B MARYLAND*****46*12345~ 8 | HL*1**20*1~ 9 | NM1*85*1*GREENE*DAVID*M***XX*1234567890~ 10 | N3*1264 OAK WOOD AVE~ 11 | N4*BALTIMORE*MD*21236~ 12 | REF*EI*987654321~ 13 | PER*IC*DR*TE*4105551212~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*******MB~ 16 | NM1*IL*1*WILLIAMSON*MATTHEW*J***MI*123456789A~ 17 | N3*128 BROADCREEK~ 18 | N4*BALTIMORE*MD*21234~ 19 | DMG*D8*19250110*M~ 20 | NM1*PR*2*MEDICARE PART B MARYLAND*****PI*C12345~ 21 | CLM*125WILL*145.50***11>B>1*Y*A*Y*Y~ 22 | DTP*454*D8*20050115~ 23 | DTP*453*D8*20050110~ 24 | DTP*455*D8*20050113~ 25 | CR2********A**CHRONIC PAIN AND DISCOMFORT~ 26 | HI*BK>7215~ 27 | LX*1~ 28 | SV1*HC>98940*145.50*UN*1.00***1~ 29 | DTP*472*D8*20050215~ 30 | REF*6R*01~ 31 | SE*29*3701~ 32 | GE*1*1~ 33 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.cob.example3.A.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0021*005010X222A2~ 4 | BHT*0019*00*0123*20051015*1023*CH~ 5 | NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~ 6 | PER*IC*JERRY*TE*3055552222~ 7 | NM1*40*2*XYZ REPRICER*****46*66783JJT~ 8 | HL*1**20*1~ 9 | NM1*85*1*KILDARE*BEN****XX*1999996666~ 10 | N3*1234 SEAWAY ST~ 11 | N4*MIAMI*FL*33111~ 12 | REF*EI*123456789~ 13 | PER*IC*CONNIE*TE*3055551234~ 14 | NM1*87*2~ 15 | N3*2345 OCEAN BLVD~ 16 | N4*MIAMI*FL*33111~ 17 | HL*2*1*22*1~ 18 | SBR*P********CI~ 19 | NM1*IL*1*SMITH*JANE****MI*111223333~ 20 | DMG*D8*19430501*F~ 21 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~ 22 | N3*3333 OCEAN ST~ 23 | N4*SOUTH MIAMI*FL*33000~ 24 | REF*G2*PBS3334~ 25 | HL*3*2*23*0~ 26 | PAT*19~ 27 | NM1*QC*1*SMITH*TED~ 28 | N3*236 N MAIN ST~ 29 | N4*MIAMI*FL*33413~ 30 | DMG*D8*19730501*M~ 31 | CLM*26407789*79.04***11:B:1*Y*A*Y*I*P~ 32 | HI*BK:4779*BF:2724*BF:2780*BF:53081~ 33 | NM1*82*1*KILDARE*BEN****XX*1999996666~ 34 | PRV*PE*PXC*204C00000X~ 35 | REF*G2*KA6663~ 36 | NM1*77*2*KILDARE ASSOCIATES*****XX*1581234567~ 37 | N3*2345 OCEAN BLVD~ 38 | N4*MIAMI*FL*33111~ 39 | SBR*S*01*******12~ 40 | OI***Y*P**Y~ 41 | NM1*IL*1*SMITH*JACK****MI*T55TY666~ 42 | N3*236 N MAIN ST~ 43 | N4*MIAMI*FL*33111~ 44 | LX*1~ 45 | SV1*HC:99213*43.00*UN*1.00***1:2:3:4~ 46 | DTP*472*D8*20051003~ 47 | LX*2~ 48 | SV1*HC:90782*15.00*UN*1.00***1:2~ 49 | DTP*472*D8*20051003~ 50 | LX*3~ 51 | SV1*HC:J3301*21.04*UN*1.00***1:2~ 52 | DTP*472*D8*20051003~ 53 | SE*51*0021~ 54 | GE*1*1~ 55 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.cob.example3.B.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*1234*005010X222A2~ 4 | BHT*0019*00*0123*20051015*1023*CH~ 5 | NM1*41*2*PREMIER BILLING SERVICE*****46*12EEER000TY~ 6 | PER*IC*JERRY*TE*3055552222~ 7 | NM1*40*2*GREAT PRAIRIES HEALTH*****46*567890~ 8 | HL*1**20*1~ 9 | NM1*85*1*KILDARE*BEN****XX*1999996666~ 10 | N3*1234 SEAWAY ST~ 11 | N4*MIAMI*FL*33111~ 12 | REF*EI*123456789~ 13 | PER*IC*CONNIE*TE*3055551234~ 14 | NM1*87*2~ 15 | N3*2345*OCEAN BLVD~ 16 | N4*MIAMI*FL*3111~ 17 | HL*2*1*22*1~ 18 | SBR*S********CI~ 19 | NM1*IL*1*SMITH*JACK****MI*222334444~ 20 | DMG*D8*19431022*M~ 21 | NM1*PR*2*GREAT PRAIRIES HEALTH*****PI*567890~ 22 | N3*4456 SOUTH SHORE BLVD~ 23 | N4*CHICAGO*IL*44444~ 24 | REF*G2*567890~ 25 | HL*3*2*23*0~ 26 | PAT*19~ 27 | NM1*QC*1*SMITH*TED~ 28 | N3*236 N MAIN ST~ 29 | N4*MIAMI*FL*33413~ 30 | DMG*D8*19730501*M~ 31 | CLM*26407789*79.04***11:B:1*Y*A*Y*I~ 32 | HI*BK:4779*BF:2724*BF:2780*BF:53081~ 33 | NM1*82*1*KILDARE*BEN****XX*1999996666~ 34 | PRV*PE*PXC*204C00000X~ 35 | REF*G2*88877~ 36 | NM1*77*2*KILDARE ASSOCIATES*****XX*1581234567~ 37 | N3*2345 OCEAN BLVD~ 38 | N4*MIAMI*FL*33111~ 39 | SBR*P*01*******12~ 40 | CAS*PR*1*21.89**2*15.00~ 41 | AMT*D*39.15~ 42 | AMT*EAF*36.89~ 43 | OI***Y*P**Y~ 44 | NM1*IL*1*SMITH*JANE****MI*JS00111223333~ 45 | N3*236 N MAIN ST~ 46 | N4*MIAMI*FL*33111~ 47 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~ 48 | LX*1~ 49 | SV1*HC:99213*43.00*UN*1.00***1:2:3:4~ 50 | DTP*472*D8*20051003~ 51 | SVD*999996666*40.00*HC:99213**1.00~ 52 | CAS*CO*42*3.00~ 53 | DTP*573*D8*20051015~ 54 | LX*2~ 55 | SV1*HC:90782*15.00*UN*1.00***1:2~ 56 | DTP*472*D8*20051003~ 57 | SVD*999996666*15.00*HC:90782**1.00~ 58 | DTP*573*D8*20051015~ 59 | LX*3~ 60 | SV1*HC:J3301*21.04*UN*1.00***1:2~ 61 | DTP*472*D8*20051003~ 62 | SVD*999996666*21.04*HC:J3301**1.00~ 63 | DTP*573*D8*20051015~ 64 | SE*62*1234~ 65 | GE*1*1~ 66 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.cob.example3.C.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0024*005010X222A2~ 4 | BHT*0019*00*0123*20051015*1023*CH~ 5 | NM1*41*2*KEY INSURANCE*****46*999996666~ 6 | PER*IC*JERRY*TE*3055552222~ 7 | NM1*40*2*GREAT PRAIRIES*****46*567890~ 8 | HL*1**20*1~ 9 | NM1*85*1*KILDARE*BEN****XX*1999996666~ 10 | N3*1234*SEAWAY ST~ 11 | N4*MIAMI*FL*33111~ 12 | REF*EI*123456789~ 13 | PER*IC*CONNIE*TE*3055551234~ 14 | NM1*87*2~ 15 | N3*2345*OCEAN BLVD~ 16 | N4*MAIMI*FL*33111~ 17 | HL*2*1*22*1~ 18 | SBR*S********CI~ 19 | NM1*IL*1*SmITH*JACK****MI*22233444~ 20 | DMG*D8*19431022*M~ 21 | NM1*PR*2*GREAT PRAIRIES HEALTH*****PI*567890~ 22 | N3*4456 SOUTH SHORE BLVD~ 23 | N4*CHICAGO*IL*44444~ 24 | REF*G2*EJ6666~ 25 | HL*3*2*23*0~ 26 | PAT*19~ 27 | NM1*QC*1*SMITH*TED~ 28 | N3*236 N MAIN ST~ 29 | N4*MIAMI*FL*33413~ 30 | DMG*D8*19730501*M~ 31 | CLM*26407789*79.04***11:B:1*Y*A*Y*I*P~ 32 | HI*BK:4779*BF:2724*BF:2780*BF:53081~ 33 | NM1*82*1*KILDARE*BEN****XX*1999996666~ 34 | PRV*PE*PXC*204C00000X~ 35 | REF*G2*PBS3334~ 36 | NM1*77*2*KILDARE ASSOCIATES*****XX*1581234567~ 37 | N3*2345 OCEAN BLVD~ 38 | N4*MIAMI*FL*33111~ 39 | SBR*P*01*******12~ 40 | CAS*PR*1*21.89**2*15.00~ 41 | AMT*D*39.15~ 42 | AMT*EAF*36.89~ 43 | OI***Y*P**Y~ 44 | NM1*IL*1*SMITH*JANE****MI*JS00111223333~ 45 | N3*236 N MAIN ST~ 46 | N4*MIAMI*FL*33111~ 47 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~ 48 | NM1*82*1~ 49 | REF*G2*PBS3334~ 50 | LX*1~ 51 | SV1*HC:99213*43.00*UN*1.00***1:2:3:4~ 52 | DTP*472*D8*20051003~ 53 | SVD*999996666*40.00*HC:99213**1.00~ 54 | CAS*CO*42*3.00~ 55 | DTP*573*D8*20051015~ 56 | LX*2~ 57 | SV1*HC:90782*15.00*UN*1.00***1:2~ 58 | DTP*472*D8*20051003~ 59 | SVD*999996666*15.00*HC:90782**1.00~ 60 | DTP*573*D8*20051015~ 61 | LX*3~ 62 | SV1*HC:J3301*21.04*UN*1.00***1:2~ 63 | DTP*472*D8*20051003~ 64 | SVD*999996666*21.04*HC:J3301**1.00~ 65 | DTP*573*D8*20051015~ 66 | SE*64*0024~ 67 | GE*1*1~ 68 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.cob.example4.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0002*005010X222A2~ 4 | BHT*0019*00*000001142*20050214*115101*CH~ 5 | NM1*41*2*SPECIALISTS*****46*1111111~ 6 | PER*IC*SUE*TE*8005558888~ 7 | NM1*40*2*MEDICARE PENNSYLVANIA*****46*10234~ 8 | HL*1**20*1~ 9 | NM1*85*2*SPECIALISTS*****XX*0100000009~ 10 | N3*5 MAP COURT~ 11 | N4*MAYNE*PA*21236~ 12 | REF*EI*890123456~ 13 | HL*2*1*22*0~ 14 | SBR*S*18**MEDICARE*12****MB~ 15 | NM1*IL*1*MEDYUM*WAYNE*M***MI*102200221B1~ 16 | N3*1010 THOUSAND OAK LANE~ 17 | N4*MAYN*PA*17089~ 18 | DMG*D8*19560110*M~ 19 | NM1*PR*2*MEDICARE*****PI*10234~ 20 | N3*5232 MAYNE AVENUE~ 21 | N4*LYGHT*PA*17009~ 22 | CLM*101KEN6055*120.00***11:B:1*Y*A*Y*Y*P~ 23 | HI*BK:71516*BF:71906~ 24 | NM1*DN*1*BRYHT*LEE*T~ 25 | REF*1G*B01010~ 26 | NM1*82*1*HENZES*JACK****XX*9090909090~ 27 | PRV*PE*PXC*207X00000X~ 28 | REF*G2*110102CCC~ 29 | SBR*P*01**COMMERCE*****12~ 30 | AMT*D*80.00~ 31 | AMT*F2*15.00~ 32 | OI***Y*P**Y~ 33 | NM1*IL*1*MEDYUM*CAROL****MI*COM188-404777~ 34 | N3*PO BOX 45~ 35 | N4*MAYN*PA*17089~ 36 | NM1*PR*2*COMMERCE*****PI*59999~ 37 | LX*1~ 38 | SV1*HC:99203:25*120.00*UN*1.00***1:2~ 39 | DTP*472*D8*20050119~ 40 | SVD*59999*80.00*HC:99203:25**1.00~ 41 | CAS*CO*42*25.00~ 42 | CAS*PR*2*15.00~ 43 | DTP*573*D8*20050128~ 44 | SE*42*0002~ 45 | GE*1*1~ 46 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.drug.example10.1.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0711*005010X222A2~ 4 | BHT*0019*00*0013*20040801*1200*CH~ 5 | NM1*41*2*Associates in Medicine*****46*587654321~ 6 | PER*IC*Bud Holly*TE*8017268899~ 7 | NM1*40*2*XYZ Receiver*****46*369852758~ 8 | HL*1**20*1~ 9 | NM1*85*2*Associates in Medicine*****XX*1234567893~ 10 | N3*1313 Las Vegas Boulevard~ 11 | N4*Las Vegas*NV*89109~ 12 | REF*EI*587654321~ 13 | HL*2*1*22*0~ 14 | SBR*P*18*GRP01020102******CI~ 15 | NM1*IL*1*Vaughn*Steve*R***MI*MBRID12345~ 16 | N3*236 Diamond ST~ 17 | N4*Las Vegas*NV*89109~ 18 | DMG*D8*19430501*M~ 19 | NM1*PR*2*R&R Health Plan*****XV*PLANID12345~ 20 | CLM*CLMNO12345*103.37***11:B:1*Y*A*Y*Y~ 21 | HI*BK:03591~ 22 | NM1*82*1*Hendrix*Jim****XX*1122333341~ 23 | PRV*PE*PXC*208D00000X~ 24 | LX*1~ 25 | SV1*HC:90782*50.00*UN*1.00*11**1~ 26 | DTP*472*D8*20040711~ 27 | LX*2~ 28 | SV1*HC:J1550*53.37*UN*1.00*11**1~ 29 | DTP*472*D8*20040711~ 30 | AMT*T*3.37~ 31 | LIN**N4*00026063512~ 32 | CTP****10.00*ML~ 33 | SE*31*0711~ 34 | GE*1*1~ 35 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.drug.example10.2.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0711*005010X222A2~ 4 | BHT*0019*00*0013*20040301*1200*CH~ 5 | NM1*41*2*Quality Billing Service Corporation*****46*587654321~ 6 | PER*IC*Bud Holly*TE*8017268899~ 7 | NM1*40*2*XYZ Receiver*****46*369852758~ 8 | HL*1**20*1~ 9 | NM1*85*2*Professional Home IV, LLC*****XX*1234567893~ 10 | N3*1500 Industrial Drive~ 11 | N4*Libertyville*IL*60048~ 12 | REF*EI*10-1234567~ 13 | PER*IC*Brenda Holly*TE*8019999999~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*GRP01020102******CI~ 16 | NM1*IL*1*Smith*Steve*A***MI*MBRID01234~ 17 | N3*15210 Juliet Lane~ 18 | N4*Libertyville*IL*60048~ 19 | DMG*D8*19430501*M~ 20 | NM1*PR*2*R&R Health Plan*****XV*PLANID12345~ 21 | CLM*CLMNO12345*2232.93***12:B:1*Y*A*Y*Y~ 22 | HI*BK:4659~ 23 | LX*1~ 24 | SV1*HC:S9500*1400.00*UN*7.00*12**1~ 25 | DTP*472*RD8*20040201-20040207~ 26 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 27 | LX*2~ 28 | SV1*HC:S5001*682.50*UN*7.00*12**1~ 29 | DTP*472*RD8*20040201-20040207~ 30 | DTP*471*D8*20040130~ 31 | LIN**N4*00004196501~ 32 | CTP****7.00*UN~ 33 | REF*XZ*2530001~ 34 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 35 | LX*3~ 36 | SV1*HC:S5000*15.12*UN*14.00*12**1~ 37 | DTP*472*RD8*20040201-20040207~ 38 | DTP*471*D8*20040130~ 39 | LIN**N4*63323024910~ 40 | CTP****14.00*UN~ 41 | REF*XZ*2530001~ 42 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 43 | LX*4~ 44 | SV1*HC:S5000*67.69*UN*7.00*12**1~ 45 | DTP*472*RD8*20040201-20040207~ 46 | DTP*471*D8*20040130~ 47 | LIN**N4*00338004938~ 48 | CTP****7.00*UN~ 49 | REF*XZ*2530001~ 50 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 51 | LX*5~ 52 | SV1*HC:S5000*57.12*UN*14.00*12**1~ 53 | DTP*472*RD8*20040201-20040207~ 54 | DTP*471*D8*20040130~ 55 | LIN**N4*08290033010~ 56 | CTP****14.00*UN~ 57 | REF*XZ*2530002~ 58 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 59 | LX*6~ 60 | SV1*HC:S5000*10.50*UN*7.00*12**1~ 61 | DTP*472*RD8*20040201-20040207~ 62 | DTP*471*D8*20040130~ 63 | LIN**N4*08290038005~ 64 | CTP****7.00*UN~ 65 | REF*XZ*2530003~ 66 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 67 | SE*65*0711~ 68 | GE*1*1~ 69 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.drug.example10.3.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0711*005010X222A2~ 4 | BHT*0019*00*0013*20040301*1200*CH~ 5 | NM1*41*2*Quality Billing Service Corporation*****46*587654321~ 6 | PER*IC*Bud Holly*TE*8017268899~ 7 | NM1*40*2*XYZ Receiver*****46*369852758~ 8 | HL*1**20*1~ 9 | NM1*85*2*Professional Home IV, LLC*****XX*1234567893~ 10 | N3*1500 Industrial Drive~ 11 | N4*Libertyville*IL*60048~ 12 | REF*EI*10-1234567~ 13 | PER*IC*Brenda Holly*TE*8019999999~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*GRP01020102******CI~ 16 | NM1*IL*1*Smith*Steve*A***MI*MBRID01234~ 17 | N3*15210 Juliet Lane~ 18 | N4*Libertyville*IL*60048~ 19 | DMG*D8*19430501*M~ 20 | NM1*PR*2*R&R Health Plan*****XV*PLANID12345~ 21 | CLM*CLMNO12345*2232.93***12:B:1*Y*A*Y*Y~ 22 | HI*BK:4659~ 23 | LX*1~ 24 | SV1*HC:S9500*1400.00*UN*7.00*12**1~ 25 | DTP*472*RD8*20040201-20040207~ 26 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 27 | LX*2~ 28 | SV1*HC:J0696*682.50*UN*56.00*12**1~ 29 | DTP*472*RD8*20040201-20040207~ 30 | DTP*471*D8*20040130~ 31 | LIN**N4*00004196501~ 32 | CTP****7.00*UN~ 33 | REF*XZ*2530001~ 34 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 35 | LX*3~ 36 | SV1*HC:J7051*15.12*UN*28.00*12**1~ 37 | DTP*472*RD8*20040201-20040207~ 38 | DTP*471*D8*20040130~ 39 | LIN**N4*63323024910~ 40 | CTP****14.00*UN~ 41 | REF*XZ*2530001~ 42 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 43 | LX*4~ 44 | SV1*HC:J3490:::::Sod Chl 0.9%see NDC#*67.69*UN*7.00*12**1~ 45 | DTP*472*RD8*20040201-20040207~ 46 | DTP*471*D8*20040130~ 47 | LIN**N4*00338004938~ 48 | CTP****7.00*UN~ 49 | REF*XZ*2530001~ 50 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 51 | LX*5~ 52 | SV1*HC:J3490:::::Sod Chl 0.9% see NDC#*57.12*UN*14.00*12**1~ 53 | DTP*472*RD8*20040201-20040207~ 54 | DTP*471*D8*20040130~ 55 | LIN**N4*08290033010~ 56 | CTP****14.00*UN~ 57 | REF*XZ*2530002~ 58 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 59 | LX*6~ 60 | SV1*HC:J3490:::::Hep Lock see NDC#*10.50*UN*7.00*12**1~ 61 | DTP*472*RD8*20040201-20040207~ 62 | DTP*471*D8*20040130~ 63 | LIN**N4*08290038005~ 64 | CTP****7.00*UN~ 65 | REF*XZ*2530003~ 66 | NM1*DK*1*Welby*Marcus****XX*1112223338~ 67 | SE*65*0711~ 68 | GE*1*1~ 69 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example1.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0021*005010X222A2~ 4 | BHT*0019*00*244579*20061015*1023*CH~ 5 | NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~ 6 | PER*IC*JERRY*TE*3055552222*EX*231~ 7 | NM1*40*2*KEY INSURANCE COMPANY*****46*66783JJT~ 8 | HL*1**20*1~ 9 | PRV*BI*PXC*203BF0100Y~ 10 | NM1*85*2*BEN KILDARE SERVICE*****XX*1912301953~ 11 | N3*234 SEAWAY ST~ 12 | N4*MIAMI*FL*331110000~ 13 | REF*EI*587654321~ 14 | NM1*87*2~ 15 | N3*2345 OCEAN BLVD~ 16 | N4*MIAMI*FL*33111~ 17 | HL*2*1*22*1~ 18 | SBR*P**2222-SJ******CI~ 19 | NM1*IL*1*SMITH*JANE****MI*JS00111223333~ 20 | NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~ 21 | HL*3*2*23*0~ 22 | PAT*19~ 23 | NM1*QC*1*SMITH*TED~ 24 | N3*236 N MAIN ST~ 25 | N4*MIAMI*FL*33413~ 26 | DMG*D8*19730501*M~ 27 | CLM*26463774*100.00***11:B:1*Y*A*Y*I~ 28 | REF*D9*17312345600006351~ 29 | HI*BK:0340*BF:V7389~ 30 | LX*1~ 31 | SV1*HC:99213*40.00*UN*1.00***1~ 32 | DTP*472*D8*20061003~ 33 | LX*2~ 34 | SV1*HC:87070*15.00*UN*1.00***1~ 35 | DTP*472*D8*20061003~ 36 | LX*3~ 37 | SV1*HC:99214*35.00*UN*1.00***2~ 38 | DTP*472*D8*20061010~ 39 | LX*4~ 40 | SV1*HC:86663*10.00*UN*1.00***2~ 41 | DTP*472*D8*20061010~ 42 | SE*40*0021~ 43 | GE*1*1~ 44 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example11.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*1002*005010X222A2~ 4 | BHT*0019*00*1002*20050620*09460000*CH~ 5 | NM1*41*2*REGIONAL PPO NETWORK*****46*123456789~ 6 | PER*IC*SUBMITTER CONTACT INFO*TE*8001231234~ 7 | NM1*40*2*EXTRA HEALTHY INSURANCE*****46*112244~ 8 | HL*1**20*1~ 9 | NM1*85*2*HAPPY DOCTORS GROUP PRACTICE*****XX*1234567890~ 10 | N3*P O BOX 123~ 11 | N4*FORT WAYNE*IN*462540000~ 12 | REF*EI*555512345~ 13 | PER*IC*SUE BILLINGSWORTH*TE*8881231234~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*123XYZ******CI~ 16 | NM1*IL*1*RING*DIAMOND*D***MI*00124A089~ 17 | N3*123 EXAMPLE DRIVE~ 18 | N4*INDIANAPOLIS*IN*462290000~ 19 | DMG*D8*19401229*F~ 20 | NM1*PR*2*EXTRA HEALTHY INSURANCE*****PI*12345~ 21 | CLM*ABC123-RI*28.75***11>B>1*Y*A*Y*Y*P~ 22 | REF*9A*0902352342~ 23 | REF*D9*061505501749388~ 24 | HI*BK>496*BF>25000~ 25 | HCP*03*26.75*2.00*908231234~ 26 | NM1*DN*1*DOE*JOHN****XX*9988776655~ 27 | NM1*82*1*ANTHONY*SUSAN*B***XX*1122334455~ 28 | NM1*77*2*HAPPY DOCTORS GROUP~ 29 | N3*123 FEEL GOOD ROAD~ 30 | N4*WASHINGTON*IN*475010000~ 31 | LX*1~ 32 | SV1*HC>E0570>RR*25.00*UN*1.00***1>2~ 33 | DTP*472*D8*20050514~ 34 | HCP*03*23.75*1.25*908231234~ 35 | LX*2~ 36 | SV1*HC>A7003>NU*3.75*UN*1.00***1~ 37 | DTP*472*D8*20050514~ 38 | HCP*03*3.00*0.75*908231234~ 39 | SE*37*1002~ 40 | GE*1*1~ 41 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example12.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*1024*005010X222A2~ 4 | BHT*0019*00*1024*20050711*1335*CH~ 5 | NM1*41*2*REGIONAL PPO NETWORK*****46*123456789~ 6 | PER*IC*SUBMITTER CONTACT INFO*TE*8001231234~ 7 | NM1*40*2*CONSERVATIVE INSURANCE*****46*000110002~ 8 | HL*1**20*1~ 9 | NM1*85*2*EMERGENCY PHYSICIANS GROUP*****XX*1122334455~ 10 | N3*7423 SUPER STREET~ 11 | N4*BILLINGS*MO*919910000~ 12 | REF*EI*111002222~ 13 | HL*2*1*22*1~ 14 | SBR*P**232AA******CI~ 15 | NM1*IL*1*SMITH*MATTHEW*R***MI*57976235C~ 16 | N3*5698 SOUTH STREET~ 17 | N4*BILLINGS*MO*919910000~ 18 | DMG*D8*19561015*M~ 19 | NM1*PR*2*CONSERVATIVE INSURANCE*****PI*00123~ 20 | HL*3*2*23*0~ 21 | PAT*19~ 22 | NM1*QC*1*SMITH*TOM*E~ 23 | N3*5698 SOUTH STREET~ 24 | N4*BILLINGS*MO*919910000~ 25 | DMG*D8*19960807*M~ 26 | CLM*TS234H3*252.71***23>B>1*Y*A*Y*Y*P~ 27 | REF*9A*0902345406~ 28 | REF*D9*687534234346~ 29 | HI*BK>9951~ 30 | HCP*00*0.00**333001234*********T1~ 31 | NM1*82*1*BLUE*JACKIE*D***XX*1112223336~ 32 | SBR*S*18*56567******12~ 33 | OI***Y***Y~ 34 | NM1*IL*1*SMITH*TOM*E***MI*23424570~ 35 | N3*5698 SOUTH STREET~ 36 | N4*BILLINGS*MO*919910000~ 37 | NM1*PR*2*SECONDARY INSURANCE COMPANY*****PI*95645~ 38 | LX*1~ 39 | SV1*HC>99284*252.71*UN*1.00***1~ 40 | DTP*472*D8*20050506~ 41 | SE*39*1024~ 42 | GE*1*1~ 43 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example2.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0021*005010X222A2~ 4 | BHT*0019*00*0123*20061015*1023*RP~ 5 | NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~ 6 | PER*IC*JERRY*TE*3055552222*EX*231~ 7 | NM1*40*2*AHLIC*****46*66783JJT~ 8 | HL*1**20*1~ 9 | PRV*BI*PXC*203BF0100Y~ 10 | NM1*85*2*BEN KILDARE SERVICE*****XX*9876543210~ 11 | N3*234 SEAWAY ST~ 12 | N4*MIAMI*FL*33111~ 13 | REF*EI*587654321~ 14 | NM1*87*2~ 15 | N3*2345 OCEAN BLVD~ 16 | N4*MIAMI*FL*33111~ 17 | HL*2*1*22*0~ 18 | SBR*P*18*12312-A******HM~ 19 | NM1*IL*1*SMITH*TED****MI*00221111~ 20 | N3*236 N MAIN ST~ 21 | N4*MIAMI*FL*33413~ 22 | DMG*D8*19430501*M~ 23 | NM1*PR*2*ALLIANCE HEALTH AND LIFE INSURANCE*****PI*741234~ 24 | CLM*26462967*100.00***11:B:1*Y*A*Y*I~ 25 | DTP*431*D8*19981003~ 26 | REF*D9*17312345600006351~ 27 | HI*BK:0340*BF:V7389~ 28 | NM1*77*2*KILDARE ASSOCIATES*****XX*5812345679~ 29 | N3*2345 OCEAN BLVD~ 30 | N4*MIAMI*FL*33111~ 31 | LX*1~ 32 | SV1*HC:99213*40.00*UN*1.00***1~ 33 | DTP*472*D8*20061003~ 34 | LX*2~ 35 | SV1*HC:87072*15.00*UN*1.00***1~ 36 | DTP*472*D8*20061003~ 37 | LX*3~ 38 | SV1*HC:99214*35.00*UN*1.00***2~ 39 | DTP*472*D8*20061010~ 40 | LX*4~ 41 | SV1*HC:86663*10.00*UN*1.00***2~ 42 | DTP*472*D8*20061010~ 43 | SE*41*0021~ 44 | GE*1*1~ 45 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example6.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*3701*005010X222A2~ 4 | BHT*0019*00*007227*20050215*075420*CH~ 5 | NM1*41*2*DAVID GREEN*****46*S01057~ 6 | PER*IC*KATHY SMITH*TE*4105558888~ 7 | NM1*40*2*MEDICARE PART B MARYLAND*****46*12345~ 8 | HL*1**20*1~ 9 | NM1*85*1*GREENE*DAVID*M***XX*1234567890~ 10 | N3*1264 OAK WOOD AVE~ 11 | N4*BALTIMORE*MD*21236~ 12 | REF*EI*987654321~ 13 | PER*IC*DR*TE*4105551212~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*******MB~ 16 | NM1*IL*1*WILLIAMSON*MATTHEW*J***MI*123456789A~ 17 | N3*128 BROADCREEK~ 18 | N4*BALTIMORE*MD*21234~ 19 | DMG*D8*19250110*M~ 20 | NM1*PR*2*MEDICARE PART B MARYLAND*****PI*C12345~ 21 | CLM*125WILL*145.50***11>B>1*Y*A*Y*Y~ 22 | DTP*454*D8*20050115~ 23 | DTP*453*D8*20050110~ 24 | DTP*455*D8*20050113~ 25 | CR2********A**CHRONIC PAIN AND DISCOMFORT~ 26 | HI*BK>7215~ 27 | LX*1~ 28 | SV1*HC>98940*145.50*UN*1.00***1~ 29 | DTP*472*D8*20050215~ 30 | REF*6R*01~ 31 | SE*29*3701~ 32 | GE*1*1~ 33 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example7.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0001*005010X222A2~ 4 | BHT*0019*00*16*20050326*1036*CH~ 5 | NM1*41*2*OXYGEN SUPPLY COMPANY*****46*ABC11111~ 6 | PER*IC*BONNIE*TE*8125551111*EM*HELPDESK@OXYGEN.COM~ 7 | NM1*40*2*DMERC CARRIER*****46*99999~ 8 | HL*1**20*1~ 9 | NM1*85*2*OXYGEN SUPPLY COMPANY*****XX*9992233334~ 10 | N3*1800 EAST RIDGE DRIVE~ 11 | N4*RICHMOND*IN*46224~ 12 | REF*EI*389999999~ 13 | HL*2*1*22*0~ 14 | SBR*P*18*******MB~ 15 | NM1*IL*1*SMITH*TERRY****MI*111222333A~ 16 | N3*121 SOUTH ST~ 17 | N4*RICHMOND*IN*46236~ 18 | DMG*D8*19380105*F~ 19 | NM1*PR*2*DMERC CARRIER*****PI*99999~ 20 | CLM*R03996273 #01*520.24***11:B:1*Y*A*Y*Y~ 21 | HI*BK:496*BF:51881*BF:2859~ 22 | LX*1~ 23 | SV1*HC:E1390:RR*461.10*UN*1.00***1:2~ 24 | PWK*CT*AA~ 25 | CR3*R*MO*99.00~ 26 | DTP*472*RD8*20050321-20050321~ 27 | DTP*607*D8*20050321~ 28 | DTP*463*D8*20040321~ 29 | DTP*461*D8*20050301~ 30 | NM1*DK*1*WILSON*LARRY****XX*5555511111~ 31 | N3*1212 NORTH MERIDIAN~ 32 | N4*RICHMOND*IN*46223~ 33 | REF*1G*X99999~ 34 | PER*IC*LEE*TE*5554446666~ 35 | LQ*UT*04.03~ 36 | FRM*1A**056~ 37 | FRM*1C**20050228~ 38 | FRM*2**1~ 39 | FRM*3**1~ 40 | FRM*4*Y~ 41 | FRM*5**2~ 42 | FRM*7*Y~ 43 | FRM*8*N~ 44 | FRM*9*Y~ 45 | LX*2~ 46 | SV1*HC:E0431:RR*59.14*UN*1.00***1:2~ 47 | PWK*CT*AA~ 48 | CR3*R*MO*99.00~ 49 | DTP*472*RD8*20050321-20050321~ 50 | DTP*607*D8*20050321~ 51 | DTP*463*D8*20040321~ 52 | DTP*461*D8*20050301~ 53 | NM1*DK*1*WILSON*LARRY****XX*5555511111~ 54 | N3*1212 NORTH MERIDIAN~ 55 | N4*RICHMOND*IN*46223~ 56 | REF*1G*X99999~ 57 | PER*IC*LEE*TE*5554446666~ 58 | LQ*UT*04.03~ 59 | FRM*1A**056~ 60 | FRM*1C**20050228~ 61 | FRM*2**1~ 62 | FRM*3**1~ 63 | FRM*4*Y~ 64 | FRM*5**2~ 65 | FRM*7*Y~ 66 | FRM*8*N~ 67 | FRM*9*Y~ 68 | SE*66*0001~ 69 | GE*1*1~ 70 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example8.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*112233*005010X222A2~ 4 | BHT*0019*00*16*20050326*1036*CH~ 5 | NM1*41*2*XYZ WHEELCHAIRS INC*****46*ABC55~ 6 | PER*IC*JANE*TE*2225551111~ 7 | NM1*40*2*DMERC CARRIER*****46*99999~ 8 | HL*1**20*1~ 9 | NM1*85*2*XYZ WHEELCHAIR INC*****XX*7778889999~ 10 | N3*1440 NORTH STREET~ 11 | N4*LAFAYETTE*IN*47904~ 12 | REF*EI*123567989~ 13 | REF*1G*0426960001~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*******MB~ 16 | PAT*******01*155.00~ 17 | NM1*IL*1*SMITH*JAMES****MI*987654321A~ 18 | N3*12 MAIN ST~ 19 | N4*FRANKFORT*IN*46209~ 20 | DMG*D8*19201023*M~ 21 | NM1*PR*2*DMERC CARRIER*****PI*99999~ 22 | CLM*SMI123*75.00***12:B:1*Y*A*Y*Y~ 23 | HI*BK:436*BF:3449~ 24 | LX*1~ 25 | SV1*HC:K0001:RR:KH:BR*75.00*UN*1.00***1:2~ 26 | PWK*CT*AA~ 27 | CR3*I*MO*99.00~ 28 | DTP*472*RD8*20050321-20050321~ 29 | DTP*463*D8*20040321~ 30 | DTP*461*D8*20050321~ 31 | MEA*TR*HT*70.00~ 32 | NM1*DK*1*WILSON*RANDALL****XX*1111155555~ 33 | N3*1226 WEST RAILROAD STREET~ 34 | N4*LAFAYETTE*IN*47905~ 35 | REF*1G*M12345~ 36 | PER*IC*LEE*TE*7659259999~ 37 | LQ*UT*02.03B~ 38 | FRM*1*Y~ 39 | FRM*2*N~ 40 | FRM*3*N~ 41 | FRM*4*N~ 42 | FRM*5**8~ 43 | FRM*8*N~ 44 | FRM*9*Y~ 45 | SE*43*112233~ 46 | GE*1*1~ 47 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X222A2/demo.example9.837: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X222A2~ 3 | ST*837*0001*005010X222A2~ 4 | BHT*0019*00*0123*20050117*1023*CH~ 5 | NM1*41*2*PROVIDER MEDICAL GROUP*****46*N305~ 6 | PER*IC*NINA*TE*6155551212*EX*911~ 7 | NM1*40*2*ABC PAYER*****46*05440~ 8 | HL*1**20*1~ 9 | NM1*85*2*PROVIDER MEDICAL GROUP*****XX*2366554859~ 10 | N3*1234 WEST END AVE~ 11 | N4*NASHVILLE*TN*37232~ 12 | REF*EI*756473826~ 13 | HL*2*1*22*0~ 14 | SBR*P*18*******MB~ 15 | NM1*IL*1*JONES*MARGARET****MI*123456789A~ 16 | N3*123 RAINBOW ROAD~ 17 | N4*NASHVILLE*TN*37232~ 18 | DMG*D8*19740303*F~ 19 | NM1*PR*2*ABC PAYER*****PI*05440~ 20 | CLM*153829140*827.00***22>B>1*Y*A*Y*Y~ 21 | HI*BK>36616~ 22 | NM1*82*1*TOWNSEND*JACOB*E***XX*5678912345~ 23 | PRV*PE*PXC*207L00000X~ 24 | REF*1G*A41234~ 25 | NM1*77*2*PROVIDER OP HOSP*****XX*432198765~ 26 | N3*345 MAIN DRIVE~ 27 | N4*NASHVILLE*TN*37232~ 28 | LX*1~ 29 | SV1*HC>00142>QK>QS>P1*827.00*MJ*61.00***1.00~ 30 | DTP*472*D8*20050112~ 31 | SE*29*0001~ 32 | GE*1*1~ 33 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X223A3/institutional-claim.837i: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X223A3~ 3 | ST*837*987654*005010X223A3~ 4 | BHT*0019*00*0123*19960918*0932*CH~ 5 | NM1*41*2*JONES HOSPITAL*****46*12345~ 6 | PER*IC*JANE DOE*TE*9005555555~ 7 | NM1*40*2*MEDICARE*****46*00120~ 8 | HL*1**20*1~ 9 | PRV*BI*PXC*203BA0200N~ 10 | NM1*85*2*JONES HOSPITAL*****XX*9876540809~ 11 | N3*225 MAIN STREET BARKLEY BUILDING~ 12 | N4*CENTERVILLE*PA*17111~ 13 | REF*EI*567891234~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*******MB~ 16 | NM1*IL*1*DOE*JON*T***MI*030005074A~ 17 | N3*125 CITY AVENUE~ 18 | N4*CENTERVILLE*PA*17111~ 19 | DMG*D8*19261111*M~ 20 | NM1*PR*2*MEDICARE B*****PI*00435~ 21 | REF*G2*330127~ 22 | CLM*756048Q*89.93***14:A:1*Y*A*Y*Y~ 23 | DTP*434*D8*19960911~ 24 | CL1*3**01~ 25 | HI*BK:3669~ 26 | HI*BF:4019*BF:79431~ 27 | HI*BH:A1:D8:19261111*BH:A2:D8:19911101*BH:B1:D8:19261111*BH:B2:D8:19870101~ 28 | HI*BE:A2:::15.31~ 29 | HI*BG:09~ 30 | NM1*71*1*JONES*JOHN*J~ 31 | REF*1G*B99937~ 32 | SBR*S*01*351630*STATE TEACHERS*****CI~ 33 | OI***Y***Y~ 34 | NM1*IL*1*DOE*JANE*S***MI*222004433~ 35 | N3*125 CITY AVENUE~ 36 | N4*CENTERVILLE*PA*17111~ 37 | NM1*PR*2*STATE TEACHERS*****PI*1135~ 38 | LX*1~ 39 | SV2*0305*HC:85025*13.39*UN*1.00~ 40 | DTP*472*D8*19960911~ 41 | LX*2~ 42 | SV2*0730*HC:93005*76.54*UN*3.00~ 43 | DTP*472*D8*19960911~ 44 | SE*42*987654~ 45 | GE*1*1~ 46 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X223A3/out-of-network-repriced-claim.837i: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X223A3~ 3 | ST*837*1024*005010X223A3~ 4 | BHT*0019*00*1024*20050711*1335*CH~ 5 | NM1*41*2*REGIONAL PPO NETWORK*****46*123456789~ 6 | PER*IC*SUBMITTER CONTACT INFO*TE*8001231234~ 7 | NM1*40*2*CONSERVATIVE INSURANCE COMPANY*****46*000110002~ 8 | HL*1**20*1~ 9 | NM1*85*2*LOCAL HOSPITAL*****XX*1122334455~ 10 | N3*3423 SMALL STREET~ 11 | N4*COLUMBUS*OH*432150000~ 12 | REF*EI*111002222~ 13 | HL*2*1*22*0~ 14 | SBR*P*18*34561W******CI~ 15 | NM1*IL*1*SMITH*JAMES*A***MI*34902390F~ 16 | N3*934 NORTH STREET~ 17 | N4*COLUMBUS*OH*432150000~ 18 | DMG*D8*19621015*M~ 19 | NM1*PR*2*CONSERVATIVE INSURANCE*****PI*0012~ 20 | CLM*W392-49141*14.84***13>A>1*Y*A*Y*Y~ 21 | DTP*434*RD8*20050617-20050617~ 22 | DTP*435*DT*200506170800~ 23 | CL1*1*1*01~ 24 | AMT*F3*14.84~ 25 | REF*9A*459804390823~ 26 | REF*D9*32423466233~ 27 | HI*BK>53081~ 28 | HCP*00*0.00**333001234*********T1~ 29 | NM1*71*1*RIVERS*DAWN****XX*2244224455~ 30 | LX*1~ 31 | SV2*0301*HC>82270*14.84*UN*1.00~ 32 | DTP*472*D8*20050617~ 33 | SE*31*1024~ 34 | GE*1*1~ 35 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X223A3/ppo-repriced-claim.837i: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X223A3~ 3 | ST*837*1002*005010X223A3~ 4 | BHT*0019*00*1002*20050721*09460000*CH~ 5 | NM1*41*2*REGIONAL PPO NETWORK*****46*123456789~ 6 | PER*IC*SUBMITTER CONTACT INFO*TE*8001231234~ 7 | NM1*40*2*LOCAL INSURANCE COMPANY*****46*54334452~ 8 | HL*1**20*1~ 9 | NM1*85*2*GOOD HEALTH HOSPITAL*****XX*1257234346~ 10 | N3*592 NORTH ELM STREET~ 11 | N4*EDGEWOOD*AZ*860015590~ 12 | REF*EI*344232321~ 13 | HL*2*1*22*1~ 14 | SBR*P**46522567AW******CI~ 15 | NM1*IL*1*JONES*JENNY****MI*345U8423H~ 16 | N3*4512 WEST AVENUE~ 17 | N4*EVANSVILLE*AZ*863030000~ 18 | DMG*D8*19690731*F~ 19 | NM1*PR*2*LOCAL INSURANCE COMPANY*****PI*7452723~ 20 | HL*3*2*23*0~ 21 | PAT*19~ 22 | NM1*QC*1*JONES*JOY~ 23 | N3*4512 WEST AVENUE~ 24 | N4*EVANSVILLE*AZ*863030000~ 25 | DMG*D8*19980820*F~ 26 | CLM*456DFH43*237.50***13>A>1*Y*A*Y*Y~ 27 | DTP*434*RD8*20050706-20050706~ 28 | DTP*435*DT*200507060800~ 29 | CL1*1*2*01~ 30 | AMT*F3*237.50~ 31 | REF*9A*09459034092~ 32 | REF*D9*04566877634343456~ 33 | HI*BK>38181~ 34 | HI*BF>38900~ 35 | HI*BH>11>D8>20050706~ 36 | HCP*03*182.88*54.62*123456789~ 37 | NM1*71*1*JOHNSON*SIMON****XX*5544332211~ 38 | SBR*S*19*T&T PLUMBING COMPANY******CI~ 39 | OI***Y***Y~ 40 | NM1*IL*1*JONES*GEORGE****MI*56454566~ 41 | NM1*PR*2*OTHER COVERAGE COMPANY*****PI*534524~ 42 | LX*1~ 43 | SV2*0471*HC>92557*178.00*UN*1.00~ 44 | DTP*472*D8*20050706~ 45 | HCP*03*137.06*40.94~ 46 | LX*2~ 47 | SV2*0471*HC>92567*59.50*UN*1.00~ 48 | DTP*472*D8*20050706~ 49 | HCP*03*45.82*13.68~ 50 | SE*48*1002~ 51 | GE*1*1~ 52 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/resources/837_005010X223A3/two-claims-single-provider.837i: -------------------------------------------------------------------------------- 1 | ISA*03*9876543210*01*9876543210*30*000000005 *30*12345 *131031*1147*^*00501*000000907*1*T*:~ 2 | GS*HC*000000005*54321*20131031*1147*1*X*005010X223A3~ 3 | ST*837*987654*005010X223A3~ 4 | BHT*0019*00*0123*20050630*0932*CH~ 5 | NM1*41*2*JONES HOSPITAL*****46*12345~ 6 | PER*IC*JANE DOE*TE*1112223333~ 7 | NM1*40*2*TRICARE*****46*99999~ 8 | HL*1**20*1~ 9 | PRV*BI*PXC*282N00000X~ 10 | NM1*85*2*JONES HOSPITAL*****XX*1234567890~ 11 | N3*225 MAIN STREET~ 12 | N4*ANYWHERE*PA*17111~ 13 | REF*EI*123456789~ 14 | HL*2*1*22*0~ 15 | SBR*P*18*******CH~ 16 | NM1*IL*1*DOE*JON*T***MI*030005074~ 17 | N3*125 CITY AVENUE~ 18 | N4*CENTERVILLE*PA*17111~ 19 | DMG*D8*19681111*M~ 20 | NM1*PR*2*TRICARE*****PI*99999~ 21 | CLM*756048Q*89.95***13:A:1*Y*C*Y*Y~ 22 | DTP*434*RD8*20050315-20050315~ 23 | CL1*1**01~ 24 | HI*BK:3669~ 25 | HI*BF:4019*BF:79431~ 26 | NM1*71*1*JONES*JOHN*J***XX*1122334455~ 27 | REF*1G*U12345~ 28 | LX*1~ 29 | SV2*0305*HC:85025*13.39*UN*1.00~ 30 | DTP*472*D8*20050315~ 31 | LX*2~ 32 | SV2*0730*HC:93005*76.56*UN*3.00~ 33 | DTP*472*D8*20050315~ 34 | HL*3*1*22*0~ 35 | SBR*P*18*******CH~ 36 | NM1*IL*1*SMITH*JOE****MI*123405074~ 37 | N3*5 MAIN STREET~ 38 | N4*ANYWHERE*PA*17111~ 39 | DMG*D8*19621210*M~ 40 | NM1*PR*2*TRICARE*****PI*99999~ 41 | CLM*756049Q*50.00***13:A:1*Y*C*Y*Y~ 42 | DTP*434*RD8*20050401-20050401~ 43 | CL1*1**01~ 44 | HI*BK:30000~ 45 | NM1*71*1*JONES*JUDY*J***XX*9999999999~ 46 | PRV*AT*PXC*363LP0200N~ 47 | LX*1~ 48 | SV2*0300*HC:85087*50.00*UN*1.00~ 49 | DTP*472*D8*20050401~ 50 | SE*48*987654~ 51 | GE*1*1~ 52 | IEA*1*000000907~ -------------------------------------------------------------------------------- /src/tests/support.py: -------------------------------------------------------------------------------- 1 | """ 2 | support.py 3 | 4 | Reusable assertions and utilities for X12 based test cases 5 | """ 6 | from linuxforhealth.x12.io import X12ModelReader 7 | import os 8 | 9 | # base resource directory for "file fixtures" (sample x12 transactions) 10 | resources_directory = os.path.join( 11 | os.path.dirname(os.path.realpath(__file__)), 12 | "resources", 13 | ) 14 | 15 | 16 | def assert_eq_model(x12_path: str): 17 | """ 18 | Asserts that a generated X12 model is equal to provided input. 19 | `assert_eq_model` is constrained to processing an input with a single functional group, but does support 20 | multiple transaction sets. 21 | 22 | :param x12_path: The path to a X12 file 23 | """ 24 | with open(x12_path) as f: 25 | x12_data = "".join([l for l in f.readlines() if l]) 26 | 27 | with X12ModelReader(x12_data) as r: 28 | 29 | segment_terminator = r._x12_segment_reader.delimiters.segment_terminator 30 | segments = [ 31 | s for s in x12_data.split(segment_terminator) if s and s != "\n" 32 | ] 33 | 34 | assert "ISA" in segments[0] 35 | assert "GS" in segments[1] 36 | assert "GE" in segments[-2] 37 | assert "IEA" in segments[-1] 38 | 39 | control_header = ( 40 | segment_terminator.join(segments[0:2]) + segment_terminator + "\n" 41 | ) 42 | control_footer = segment_terminator.join(segments[-2:]) + segment_terminator 43 | transaction_sets: str = "" 44 | 45 | for m in r.models(): 46 | transaction_sets += m.x12() 47 | 48 | actual = f"{control_header}{transaction_sets}{control_footer}" 49 | assert actual == x12_data 50 | -------------------------------------------------------------------------------- /src/tests/test_4010_segments.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_4010_segments.py 3 | 4 | Tests the Pydantic X12 segment models specific to the 4010 specification 5 | """ 6 | from linuxforhealth.x12.v4010.segments import Cr7Segment, Cr5Segment, Cr6Segment 7 | 8 | 9 | def test_cr5_segment(): 10 | segment_data = { 11 | "certification_type_code": "I", 12 | "treatment_period_count": "6", 13 | "arterial_blood_gas_quantity": "56", 14 | "oxygen_test_condition_code": "R", 15 | "oxygen_test_findings_code_1": "1", 16 | } 17 | cr5_segment: Cr5Segment = Cr5Segment(**segment_data) 18 | assert cr5_segment.x12() == "CR5*I*6.00********56.00**R*1~" 19 | 20 | 21 | def test_cr7_segment(): 22 | segment_data = { 23 | "discipline_type_code": "PT", 24 | "total_visits_rendered": "4", 25 | "total_visits_projected": "12", 26 | } 27 | cr7_segment: Cr7Segment = Cr7Segment(**segment_data) 28 | assert cr7_segment.x12() == "CR7*PT*4*12~" 29 | 30 | 31 | def test_cr6_segment(): 32 | segment_data = { 33 | "prognosis_indicator": "4", 34 | "soc_date": "19941191", 35 | "date_time_period_format_qualifier": "RD8", 36 | "certification_period": "19941101-19941231", 37 | "diagnosis_date": "19941015", 38 | "skilled_nursing_facility_indicator": "N", 39 | "medicare_coverage_indicator": "Y", 40 | "certification_type_indicator": "I", 41 | "last_visit_date": "19941101", 42 | "patient_location_code": "A", 43 | } 44 | cr6_segment: Cr6Segment = Cr6Segment(**segment_data) 45 | assert ( 46 | cr6_segment.x12() 47 | == "CR6*4*19941191*RD8*19941101-19941231*19941015*N*Y*I*****19941101****A~" 48 | ) 49 | -------------------------------------------------------------------------------- /src/tests/test_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_api.py 3 | 4 | Tests the optional Fast API x12/endpoint 5 | """ 6 | import pytest 7 | from linuxforhealth.x12.api import app 8 | from typing import Dict 9 | 10 | # determine if we need to skip the API tests, based on the installation 11 | try: 12 | from fastapi.testclient import TestClient 13 | 14 | is_fastapi_disabled = False 15 | except ImportError: 16 | is_fastapi_disabled = True 17 | 18 | 19 | @pytest.fixture() 20 | def api_test_client() -> TestClient: 21 | """Returns the API test client fixture""" 22 | test_client = TestClient(app) 23 | return test_client 24 | 25 | 26 | @pytest.fixture 27 | def mock_x12_payload(simple_270_with_new_lines: str) -> Dict: 28 | x12_payload = {"x12": simple_270_with_new_lines} 29 | return x12_payload 30 | 31 | 32 | @pytest.mark.skipif(is_fastapi_disabled, reason="X12 API endpoint is not enabled") 33 | @pytest.mark.parametrize( 34 | "header, expected_first_value", 35 | [ 36 | (None, "header"), 37 | ("models", "header"), 38 | ("Models", "header"), 39 | ("MODELS", "header"), 40 | ], 41 | ) 42 | def test_x12_ok_models(mock_x12_payload, api_test_client, header, expected_first_value): 43 | """ 44 | Tests the x12 models response with parameterized header and expected values. 45 | :param mock_x12_payload: The X12 request payload for the test 46 | :param api_test_client: The configured Fast API test client 47 | :param header: The parameterized header value 48 | :param expected_first_value: The parameterized first value 49 | """ 50 | api_response = api_test_client.post( 51 | "/x12", json=mock_x12_payload, headers={"LFH-X12-RESPONSE": header} 52 | ) 53 | assert api_response.status_code == 200 54 | assert expected_first_value in api_response.json()[0] 55 | 56 | 57 | @pytest.mark.skipif(is_fastapi_disabled, reason="X12 API endpoint is not enabled") 58 | @pytest.mark.parametrize( 59 | "header, expected_key", 60 | [ 61 | ("segments", "ISA01"), 62 | ("Segments", "ISA01"), 63 | ("SEGMENTS", "ISA01"), 64 | ], 65 | ) 66 | def test_x12_ok_segments(mock_x12_payload, api_test_client, header, expected_key): 67 | """ 68 | Tests the x12 segments response with parameterized header and expected values. 69 | :param mock_x12_payload: The X12 request payload for the test 70 | :param api_test_client: The configured Fast API test client 71 | :param header: The parameterized header value 72 | :param expected_key: The parameterized expected key 73 | """ 74 | api_response = api_test_client.post( 75 | "/x12", json=mock_x12_payload, headers={"LFH-X12-RESPONSE": header} 76 | ) 77 | assert api_response.status_code == 200 78 | assert expected_key in api_response.json()[0].keys() 79 | 80 | 81 | @pytest.mark.skipif(is_fastapi_disabled, reason="X12 API endpoint is not enabled") 82 | def test_x12_invalid_request(api_test_client, mock_x12_payload): 83 | """ 84 | Validates that invalid 85 | :param api_test_client: The configured Fast API test client 86 | :param mock_x12_payload: The X12 request payload for the test 87 | """ 88 | api_response = api_test_client.post("/x12", json={"data": mock_x12_payload}) 89 | assert api_response.status_code == 400 90 | 91 | invalid_x12 = list(mock_x12_payload.values())[0].replace( 92 | "NM1*IL*1*DOE*JOHN****MI*00000000001~", "NM1*FF*1*DOE*JOHN****MI*00000000001~" 93 | ) 94 | invalid_payload = {"x12": invalid_x12} 95 | api_response = api_test_client.post("/x12", json=invalid_payload) 96 | assert api_response.status_code == 400 97 | -------------------------------------------------------------------------------- /src/tests/test_common_validations.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_common_validations.py 3 | 4 | Tests common validations that are shared across X12 transaction sets. 5 | """ 6 | from linuxforhealth.x12.io import X12ModelReader 7 | import pytest 8 | 9 | 10 | def test_segment_footer_count(simple_270_with_new_lines): 11 | """Validates the total segment count validation raises an exception""" 12 | test_input = simple_270_with_new_lines.replace("SE*17*0001~", "SE*27*0001~") 13 | with pytest.raises(ValueError): 14 | with X12ModelReader(test_input) as r: 15 | for _ in r.models(): 16 | pass 17 | -------------------------------------------------------------------------------- /src/tests/test_create_parser.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_create_parser.py 3 | 4 | Tests the parser creation function. 5 | """ 6 | import pytest 7 | from linuxforhealth.x12.parsing import create_parser 8 | from linuxforhealth.x12.models import X12Delimiters 9 | 10 | 11 | @pytest.mark.parametrize( 12 | "transaction_code, implementation_version, class_name", 13 | [("270", "005010X279A1", "X12Parser")], 14 | ) 15 | def test_create_parser(transaction_code, implementation_version, class_name): 16 | parser = create_parser(transaction_code, implementation_version, X12Delimiters()) 17 | assert class_name == parser.__class__.__name__ 18 | 19 | assert "ST" in parser._loop_parsers 20 | assert "SE" in parser._loop_parsers 21 | assert len(parser._loop_parsers) > 2 22 | -------------------------------------------------------------------------------- /src/tests/test_encoding.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_encoding.py 3 | 4 | Tests the X12 Custom JSON Encoder 5 | """ 6 | from linuxforhealth.x12.encoding import X12JsonEncoder 7 | from decimal import Decimal 8 | import uuid 9 | import json 10 | import datetime 11 | 12 | 13 | def test_encoding(): 14 | input_data = { 15 | "product": "thing-a-magigs", 16 | "quantity": Decimal("4.89"), 17 | "order_date": datetime.date(2021, 7, 15), 18 | "id": uuid.UUID("11ae9671-f227-48e9-ad4c-565120b7fa8f"), 19 | } 20 | 21 | result: str = json.dumps(input_data, cls=X12JsonEncoder) 22 | # compare with "in" since order isn't guaranteed 23 | assert '"product": "thing-a-magigs"' in result 24 | assert '"quantity": 4.89' in result 25 | assert '"order_date": "2021-07-15"' in result 26 | assert '"id": "11ae9671-f227-48e9-ad4c-565120b7fa8f"' in result 27 | -------------------------------------------------------------------------------- /src/tests/test_parsing_matcher.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from typing import Callable, Dict 3 | from linuxforhealth.x12.parsing import X12ParserContext, match 4 | 5 | 6 | @pytest.fixture 7 | def segment_data(x12_delimiters) -> Dict: 8 | return { 9 | "delimiters": x12_delimiters.dict(), 10 | "segment_name": "ST", 11 | "transaction_set_identifier_code": "270", 12 | "transaction_set_control_number": "0001", 13 | "implementation_convention_reference": "005010X279A1", 14 | } 15 | 16 | 17 | @pytest.fixture 18 | def parser_function() -> Callable: 19 | def func(x12_parser_context: X12ParserContext, segment_data: Dict): 20 | x12_parser_context.parsed_loops.append("test_loop") 21 | 22 | return func 23 | 24 | 25 | def test_match_no_conditions(parser_function, segment_data, x12_parser_context): 26 | """ 27 | Tests the match decorator when no conditions are specified. 28 | """ 29 | wrapped_func = match("ST")(parser_function) 30 | wrapped_func(segment_data, x12_parser_context) 31 | assert x12_parser_context.loop_name == "test_loop" 32 | 33 | 34 | def test_single_match_condition(parser_function, segment_data, x12_parser_context): 35 | """ 36 | Tests the match decorator when a single condition is specified. 37 | """ 38 | wrapped_func = match("ST", conditions={"transaction_set_identifier_code": "270"})( 39 | parser_function 40 | ) 41 | wrapped_func(segment_data, x12_parser_context) 42 | assert x12_parser_context.loop_name == "test_loop" 43 | 44 | 45 | def test_multiple_match_condition(parser_function, segment_data, x12_parser_context): 46 | """ 47 | Tests the match decorator when multiple conditions are specified. 48 | """ 49 | wrapped_func = match( 50 | "ST", 51 | conditions={ 52 | "transaction_set_identifier_code": "270", 53 | "transaction_set_control_number": "0001", 54 | }, 55 | )(parser_function) 56 | wrapped_func(segment_data, x12_parser_context) 57 | assert x12_parser_context.loop_name == "test_loop" 58 | 59 | 60 | def test_list_match_condition(parser_function, segment_data, x12_parser_context): 61 | """ 62 | Tests the match decorator when a list/"one of" condition is specified. 63 | """ 64 | wrapped_func = match( 65 | "ST", conditions={"transaction_set_identifier_code": ["270", "276"]} 66 | )(parser_function) 67 | wrapped_func(segment_data, x12_parser_context) 68 | assert x12_parser_context.loop_name == "test_loop" 69 | 70 | 71 | def test_match_conditions_unmatched(parser_function, segment_data, x12_parser_context): 72 | """ 73 | Tests the match decorator when conditions are specified but they do not match the data_segment. 74 | """ 75 | wrapped_func = match("ST", conditions={"transaction_set_identifier_code": "911"})( 76 | parser_function 77 | ) 78 | wrapped_func(segment_data, x12_parser_context) 79 | assert x12_parser_context.loop_name is None 80 | -------------------------------------------------------------------------------- /src/tests/test_support.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_support.py 3 | 4 | Tests support functions. 5 | """ 6 | import pytest 7 | import datetime 8 | from linuxforhealth.x12.support import ( 9 | is_x12_data, 10 | is_x12_file, 11 | parse_x12_date, 12 | parse_interchange_date, 13 | count_segments, 14 | parse_x12_major_version, 15 | get_latest_implementation_version, 16 | ) 17 | from linuxforhealth.x12.io import X12ModelReader 18 | 19 | 20 | @pytest.mark.parametrize( 21 | "test_input, is_fixture, expected", 22 | [ 23 | ("simple_270_with_new_lines", True, True), 24 | ("simple_270_one_line", True, True), 25 | ("foo", False, False), 26 | ("", False, False), 27 | (None, False, False), 28 | ], 29 | ) 30 | def test_is_x12_data(request, test_input: str, is_fixture: bool, expected: bool): 31 | """ 32 | Tests is_x12_data with fixtures and literal values. 33 | :param request: The pytest request fixture. Used to lookup fixture values by name. 34 | :param test_input: The fixture name or the literal value. 35 | :param is_fixture: Indicates if test_input is a fixture name. 36 | :param expected: The expected test value 37 | """ 38 | 39 | input_value = request.getfixturevalue(test_input) if is_fixture else test_input 40 | assert is_x12_data(input_value) is expected 41 | 42 | 43 | @pytest.mark.parametrize( 44 | "test_input", ["simple_270_with_new_lines", "simple_270_one_line"] 45 | ) 46 | def test_is_x12_file_true(request, tmpdir, test_input: str): 47 | """ 48 | Tests is_x12_file where the expected result is True. 49 | :param request: The pytest request fixture. Used to lookup fixture values by name. 50 | :param tmpdir: The pytest tmpdir fixture. Used to create tmp directory and files. 51 | :param test_input: The fixture name. 52 | """ 53 | 54 | input_value = request.getfixturevalue(test_input) 55 | f = tmpdir.mkdir("x12-support").join("test.x12") 56 | f.write(input_value) 57 | 58 | assert is_x12_file(f) 59 | 60 | 61 | def test_is_x12_file_false(): 62 | assert is_x12_file("/home/not-a-real/file.txt") is False 63 | assert is_x12_file("") is False 64 | assert is_x12_file(None) is False 65 | 66 | 67 | def test_parser_interchange_date(): 68 | assert parse_interchange_date("131031") == datetime.date(2013, 10, 31) 69 | 70 | 71 | def test_parse_x12_date(): 72 | assert parse_x12_date("20120501") == datetime.date(2012, 5, 1) 73 | assert parse_x12_date("201205011010") == datetime.datetime(2012, 5, 1, 10, 10) 74 | assert parse_x12_date("") is None 75 | assert parse_x12_date(None) is None 76 | 77 | 78 | def test_count_segments(simple_270_with_new_lines): 79 | with X12ModelReader(simple_270_with_new_lines) as r: 80 | model = [m for m in r.models()][0] 81 | model_data = model.dict() 82 | segment_count: int = count_segments(model_data) 83 | assert segment_count == 17 84 | 85 | 86 | def test_parse_x12_major_version(): 87 | assert parse_x12_major_version("005010X279A1") == "5010" 88 | assert parse_x12_major_version("00501") == "" 89 | assert parse_x12_major_version(None) == "" 90 | 91 | 92 | def test_get_final_implementation_version(): 93 | assert get_latest_implementation_version("005010X222") == "005010X222A2" 94 | assert get_latest_implementation_version("005010X222A1") == "005010X222A2" 95 | assert get_latest_implementation_version("005010X222A2") == "005010X222A2" 96 | 97 | with pytest.raises(KeyError): 98 | get_latest_implementation_version("invalid-version") 99 | -------------------------------------------------------------------------------- /src/tests/test_x12_model_reader.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_x12_model_reader.py 3 | 4 | Supports general model streaming tests validating the number of models returned, expected payload, etc. 5 | """ 6 | from linuxforhealth.x12.io import X12ModelReader 7 | from linuxforhealth.x12.models import X12Delimiters, X12SegmentGroup 8 | from typing import Dict, List 9 | import pytest 10 | 11 | 12 | def test_multiple_transactions(large_x12_message): 13 | 14 | with X12ModelReader(large_x12_message) as r: 15 | model_result = [m for m in r.models()] 16 | assert len(model_result) == 10 17 | 18 | 19 | @pytest.mark.parametrize("output_delimiters", [True, False]) 20 | def test_custom_delimiters(x12_with_custom_delimiters, output_delimiters): 21 | """ 22 | Validates that custom delimiters are parsed correctly and generate expected x12 23 | 24 | :param x12_with_custom_delimiters: The X12 sample transaction 25 | :param output_delimiters: 26 | """ 27 | 28 | # remove control segments from the x12 transaction with custom delimiters 29 | control_segments = ("ISA", "GS", "GE", "IEA") 30 | expected_segments = [] 31 | x12_delimiters = X12Delimiters(element_separator="|", segment_terminator="?") 32 | 33 | for x in x12_with_custom_delimiters.split("\n"): 34 | if x.split("|")[0] in control_segments: 35 | continue 36 | expected_segments.append(x) 37 | 38 | expected_transaction = "\n".join(expected_segments) 39 | 40 | with X12ModelReader( 41 | x12_with_custom_delimiters, output_delimiters=output_delimiters 42 | ) as r: 43 | model_result = [m for m in r.models()] 44 | assert len(model_result) == 1 45 | model = model_result[0] 46 | assert model.x12(custom_delimiters=x12_delimiters) == expected_transaction 47 | 48 | # validate custom delimiter handling based on the output_delimiters flag 49 | st_segment = model.header.st_segment 50 | if output_delimiters: 51 | assert st_segment.delimiters.element_separator == "|" 52 | assert st_segment.delimiters.repetition_separator == "^" 53 | assert st_segment.delimiters.component_separator == ":" 54 | assert st_segment.delimiters.segment_terminator == "?" 55 | else: 56 | assert st_segment.delimiters is None 57 | 58 | 59 | def _assert_delimiters(data: Dict, delimiters_exist: bool): 60 | """ 61 | Parameterized helper function for test_output_delimiters. 62 | The function recursively examines a X12 transaction dictionary and executes 63 | assertions testing for the existence or absence of delimiters within a X12 segment dictionary. 64 | 65 | :param data: The X12 data dictionary 66 | :param delimiters_exist: When True assertions check for delimiter existence. 67 | """ 68 | for k, v in data.items(): 69 | if k.endswith("segment") and delimiters_exist: 70 | assert v["delimiters"] 71 | elif k.endswith("segment") and not delimiters_exist: 72 | assert v.get("delimiters") is None 73 | elif isinstance(v, dict): 74 | _assert_delimiters(v, delimiters_exist) 75 | 76 | 77 | @pytest.mark.parametrize("output_delimiters", [True, False]) 78 | def test_output_delimiters(simple_270_with_new_lines, output_delimiters): 79 | """Tests the X12ModelReader output_delimiter flag""" 80 | with X12ModelReader( 81 | simple_270_with_new_lines, output_delimiters=output_delimiters 82 | ) as r: 83 | model_result: List[X12SegmentGroup] = [m for m in r.models()] 84 | assert len(model_result) == 1 85 | 86 | model_data = model_result[0].dict() 87 | _assert_delimiters(model_data, output_delimiters) 88 | -------------------------------------------------------------------------------- /src/tests/test_x12_parser_context.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_x12_parser_context.py 3 | """ 4 | from linuxforhealth.x12.parsing import X12ParserContext 5 | 6 | 7 | def test_init(x12_parser_context: X12ParserContext): 8 | 9 | assert x12_parser_context.loop_name is None 10 | assert x12_parser_context.loop_container == {} 11 | 12 | assert len(x12_parser_context.transaction_data) == 2 13 | assert "header" in x12_parser_context.transaction_data 14 | assert "footer" in x12_parser_context.transaction_data 15 | 16 | assert x12_parser_context.is_transaction_complete is False 17 | 18 | 19 | def test_set_loop_context(x12_parser_context: X12ParserContext): 20 | 21 | x12_parser_context.set_loop_context( 22 | "header", x12_parser_context.transaction_data["header"] 23 | ) 24 | assert x12_parser_context.loop_name == "header" 25 | assert x12_parser_context.loop_container == {} 26 | 27 | 28 | def test_reset_transaction(x12_parser_context: X12ParserContext): 29 | x12_parser_context.reset_transaction() 30 | assert x12_parser_context.transaction_data == {"header": {}, "footer": {}} 31 | assert x12_parser_context.is_transaction_complete is False 32 | 33 | 34 | def test_mark_transaction_complete(x12_parser_context: X12ParserContext): 35 | x12_parser_context.mark_transaction_complete() 36 | assert x12_parser_context.is_transaction_complete is True 37 | -------------------------------------------------------------------------------- /src/tests/test_x12_segment_reader.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests LinuxForHealth X12SegmentReader 3 | """ 4 | import pytest 5 | 6 | import linuxforhealth.x12.io 7 | from linuxforhealth.x12.io import X12SegmentReader 8 | 9 | 10 | @pytest.mark.parametrize( 11 | "test_input", ["simple_270_with_new_lines", "simple_270_one_line"] 12 | ) 13 | def test_init(request, test_input: str): 14 | """ 15 | Tests X12SegmentReader initialization 16 | 17 | :param request: The pytest request fixture. Used to lookup fixture values by name. 18 | :param test_input: The fixture name. 19 | """ 20 | 21 | input_value = request.getfixturevalue(test_input) 22 | x12_reader = X12SegmentReader(input_value) 23 | assert x12_reader._x12_input 24 | assert x12_reader._buffer_size is None 25 | assert x12_reader._x12_stream is None 26 | assert x12_reader.delimiters is None 27 | 28 | 29 | @pytest.mark.parametrize( 30 | "test_input", ["simple_270_with_new_lines", "simple_270_one_line"] 31 | ) 32 | def test_segments_with_string_data(request, test_input: str): 33 | """ 34 | Test X12SegmentReader models with a x12 data/message input. 35 | 36 | :param request: The pytest request fixture. Used to lookup fixture values by name. 37 | :param test_input: The fixture name. 38 | """ 39 | 40 | input_value = request.getfixturevalue(test_input) 41 | 42 | with X12SegmentReader(input_value) as r: 43 | segment_count = 0 44 | 45 | assert r.delimiters.component_separator == ":" 46 | assert r.delimiters.element_separator == "*" 47 | assert r.delimiters.repetition_separator == "^" 48 | assert r.delimiters.segment_terminator == "~" 49 | 50 | for _ in r.segments(): 51 | segment_count += 1 52 | 53 | assert 21 == segment_count 54 | 55 | assert r._x12_stream.closed 56 | assert r.delimiters is None 57 | assert r._x12_input is None 58 | 59 | 60 | @pytest.mark.parametrize( 61 | "test_input", ["simple_270_with_new_lines", "simple_270_one_line"] 62 | ) 63 | def test_segments_with_file_path(request, tmpdir, test_input: str): 64 | """ 65 | Test X12SegmentReader models with a x12 file path input. 66 | 67 | :param request: The pytest request fixture. Used to lookup fixture values by name. 68 | :param tmpdir: Pytest fixture used to create temporary files and directories 69 | :param test_input: The fixture name. 70 | """ 71 | 72 | input_value = request.getfixturevalue(test_input) 73 | f = tmpdir.mkdir("x12-support").join("test.x12") 74 | f.write(input_value) 75 | 76 | with X12SegmentReader(f) as r: 77 | segment_count = 0 78 | version_key = None 79 | 80 | assert r.delimiters.component_separator == ":" 81 | assert r.delimiters.element_separator == "*" 82 | assert r.delimiters.repetition_separator == "^" 83 | assert r.delimiters.segment_terminator == "~" 84 | 85 | for _ in r.segments(): 86 | segment_count += 1 87 | 88 | assert 21 == segment_count 89 | 90 | assert r._x12_stream.closed 91 | assert r.delimiters is None 92 | assert r._x12_input is None 93 | 94 | 95 | def test_invalid_x12_data(simple_270_one_line): 96 | """ 97 | Tests an invalid x12 message input. 98 | :param simple_270_one_line: X12 Fixture 99 | """ 100 | 101 | invalid_x12 = simple_270_one_line.replace("ISA", "FOO") 102 | 103 | with pytest.raises(ValueError): 104 | with X12SegmentReader(invalid_x12) as r: 105 | for _ in r.segments(): 106 | assert False, "Expecting ValueError Exception" 107 | 108 | 109 | def test_invalid_x12_file(tmpdir, simple_270_one_line): 110 | """ 111 | Tests an invalid x12 file path input. 112 | :param tmpdir: Pytest fixture used to create temp files and directories. 113 | :param simple_270_one_line: X12 Fixture 114 | """ 115 | 116 | invalid_x12 = simple_270_one_line.replace("ISA", "FOO") 117 | f = tmpdir.mkdir("x12-support").join("test.x12") 118 | f.write(invalid_x12) 119 | 120 | with pytest.raises(ValueError): 121 | with X12SegmentReader(f.strpath) as r: 122 | for _ in r.segments(): 123 | assert False, "Expecting ValueError Exception" 124 | 125 | 126 | def test_large_x12_message(monkeypatch, large_x12_message, config): 127 | """ 128 | Tests a large x12 message to validate buffering. 129 | :param monkeypatch: Pytest fixture for monkeypatching/mocking code. 130 | :param large_x12_message: Large X12 message fixture 131 | :param config: X12 configuration fixture 132 | """ 133 | 134 | def mock_get_config(): 135 | return config 136 | 137 | with monkeypatch.context() as m: 138 | m.setattr(linuxforhealth.x12.io, "get_config", mock_get_config) 139 | 140 | segment_counter = 0 141 | with X12SegmentReader(large_x12_message) as r: 142 | for _ in r.segments(): 143 | segment_counter += 1 144 | 145 | assert r._x12_stream.closed 146 | assert segment_counter == 174 147 | --------------------------------------------------------------------------------