fhir_to_pad_converter.py working
This commit is contained in:
153
CLAUDE.md
Normal file
153
CLAUDE.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
FHIR_PAD is a Python-based converter that transforms FHIR JSON bundles into PADneXt 2.12 XML format (German healthcare billing standard). The converter validates both input FHIR data and output PAD XML, producing detailed diagnostic reports.
|
||||
|
||||
## Core Architecture
|
||||
|
||||
### Main Components
|
||||
|
||||
1. **fhir_to_pad_converter.py** - Primary converter with validation pipeline
|
||||
* Validates FHIR JSON bundles (schema-based or structural checks)
|
||||
* Groups FHIR resources by patient/encounter or by `Claim` resource.
|
||||
* Maps FHIR resources to PAD billing positions
|
||||
* Generates PADneXt 2.12 compliant XML
|
||||
* Validates output against XSD schemas
|
||||
* Produces JSON diagnostic reports
|
||||
* Outputs declarative `AUF` (order) information to the console.
|
||||
|
||||
2. **validate_padnext.py** - Standalone PADneXt XML validator
|
||||
* Validates PADneXt 2.12 ADL/AUF XML files against XSD schemas
|
||||
* Accepts multiple XML/XSD pairs for batch validation
|
||||
|
||||
3. **utils.py** - Utility functions
|
||||
* Contains helper functions for date parsing, reference extraction, and other common tasks.
|
||||
|
||||
4. **validation.py** - Validation framework
|
||||
* Provides a framework for semantic and business rule validation of FHIR data.
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
FHIR JSON Bundle → Validation → Resource Grouping → Mapping → PAD XML Generation → XSD Validation → Report
|
||||
```
|
||||
|
||||
**Resource Grouping**: If `Claim` resources are present, FHIR entries are grouped by `(patient_id, claim_id)`. Otherwise, they are grouped by `(patient_id, encounter_id)`. Each group becomes one `<Rechnung>` (invoice) in the PAD output.
|
||||
|
||||
**Resource Mapping**:
|
||||
* If a `Claim` resource is present, its `item` entries are mapped to `<goziffer>` positions.
|
||||
* If no `Claim` is present, the following FHIR resources are converted to billing positions:
|
||||
- `Observation`, `MedicationAdministration`, `Procedure`, `ServiceRequest`, `DiagnosticReport`
|
||||
* `ExplanationOfBenefit` resources are used to enrich the JSON report with adjudication details.
|
||||
|
||||
**Date Handling**: Effective dates extracted from FHIR fields (`effectiveDateTime`, `issued`, `authoredOn`, `date`, `meta.lastUpdated`) determine the `zeitraum` (time period) for each billing case.
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Convert FHIR to PAD XML
|
||||
|
||||
Basic conversion:
|
||||
```bash
|
||||
python3 fhir_to_pad_converter.py \
|
||||
--input-json Input.json \
|
||||
--output-xml output.xml
|
||||
```
|
||||
|
||||
With validation and report:
|
||||
```bash
|
||||
python3 fhir_to_pad_converter.py \
|
||||
--input-json samples/fhir/sample_1/226844_1240059013-KaBr.json \
|
||||
--output-xml output.xml \
|
||||
--report-json report.json \
|
||||
--pad-xsd specs/padnext/padx_adl_v2.12.xsd
|
||||
```
|
||||
|
||||
With header configuration:
|
||||
```bash
|
||||
python3 fhir_to_pad_converter.py \
|
||||
--input-json Input.json \
|
||||
--output-xml output.xml \
|
||||
--header-cfg header_config.json
|
||||
```
|
||||
|
||||
### Validate PADneXt XML
|
||||
|
||||
Single file:
|
||||
```bash
|
||||
python3 validate_padnext.py \
|
||||
samples/padnext/sample_1/00209999_20250805_ADL_000087_padx.xml \
|
||||
specs/padnext/padx_adl_v2.12.xsd
|
||||
```
|
||||
|
||||
Multiple files:
|
||||
```bash
|
||||
python3 validate_padnext.py \
|
||||
file1.xml schema1.xsd \
|
||||
file2.xml schema2.xsd
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Python 3.11+**
|
||||
- **Required**: `lxml` (XSD validation), `jsonschema` (FHIR validation)
|
||||
- **Built-in**: `xml.etree.ElementTree`, `argparse`, `json`, `datetime`, `random`
|
||||
|
||||
Install dependencies:
|
||||
```bash
|
||||
pip3 install lxml jsonschema
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
samples/
|
||||
fhir/sample_1/ - Example FHIR JSON bundles
|
||||
fhir/sample_2/ - Example FHIR JSON bundle with Claim resource
|
||||
padnext/sample_1/ - Example PADneXt XML outputs (ADL/AUF)
|
||||
specs/
|
||||
padnext/ - PADneXt 2.12 XSD schemas and documentation
|
||||
padx_adl_v2.12.xsd - ADL (billing) schema
|
||||
padx_auf_v2.12.xsd - AUF (order) schema
|
||||
padx_basis_v2.12.xsd - Base types
|
||||
padx_enums_v2.12.xsd - Enumerations
|
||||
documentation_de/ - German specification PDFs
|
||||
```
|
||||
|
||||
## Key Implementation Details
|
||||
|
||||
### PAD Namespace
|
||||
All PAD XML elements use namespace `http://padinfo.de/ns/pad`
|
||||
|
||||
### Claim-driven Conversion
|
||||
If a FHIR `Claim` resource is present in the input bundle, it is used as the primary source of information for generating the PADneXt `<Rechnung>`. The `Claim.item` entries are converted to billing positions, and information about the provider, insurer, and patient is extracted from the `Claim` and its referenced resources.
|
||||
|
||||
### Header Configuration
|
||||
Header fields (billing entity, service provider, recipient) can be configured via `--header-cfg` JSON. If a `Claim` resource is present, the information from the `Claim` will override the `header_cfg`.
|
||||
|
||||
### Validation Modes
|
||||
- **FHIR**: JSON Schema validation (if schema provided) or structural checks. A new validation framework in `validation.py` allows for custom semantic and business rule validation.
|
||||
- **PAD**: XSD validation (if XSD provided) or well-formedness checks.
|
||||
|
||||
### Report Structure
|
||||
JSON reports contain:
|
||||
- `input.schema_validation_ok` - FHIR validation status
|
||||
- `input.stats` - Resource counts, date ranges, warnings, and `ExplanationOfBenefit` stats.
|
||||
- `output.schema_validation_ok` - PAD validation status
|
||||
- `output.stats` - Invoice counts, position counts, warnings.
|
||||
- `validation_warnings` - A list of warnings from the custom validation framework.
|
||||
|
||||
### AUF Log Output
|
||||
The converter prints declarative information to the console that would be contained in a `pad_auf.xml` file, such as sender, recipient, and the number of invoices.
|
||||
|
||||
### Important Functions
|
||||
|
||||
- `group_entries()` - Groups FHIR resources by `(patient_id, claim_id)` if a `Claim` is present, otherwise by `(patient_id, encounter_id)`.
|
||||
- `claim_item_to_position()` - Maps a `Claim.item` to a PAD billing position.
|
||||
- `claim_to_rechnung_header()` - Extracts header information from a `Claim` resource.
|
||||
- `resource_to_position()` - Maps other FHIR resources to a PAD billing position (fallback).
|
||||
- `build_pad_xml()` - Main XML generation logic, now with support for `Claim`-driven conversion.
|
||||
- `run_validation()` (in `validation.py`) - Runs all custom validation checks.
|
||||
- `find_resource_by_ref()` (in `utils.py`) - Helper function to resolve references within a FHIR bundle.
|
||||
153
GEMINI.MD
Normal file
153
GEMINI.MD
Normal file
@@ -0,0 +1,153 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
FHIR_PAD is a Python-based converter that transforms FHIR JSON bundles into PADneXt 2.12 XML format (German healthcare billing standard). The converter validates both input FHIR data and output PAD XML, producing detailed diagnostic reports.
|
||||
|
||||
## Core Architecture
|
||||
|
||||
### Main Components
|
||||
|
||||
1. **fhir_to_pad_converter.py** - Primary converter with validation pipeline
|
||||
* Validates FHIR JSON bundles (schema-based or structural checks)
|
||||
* Groups FHIR resources by patient/encounter or by `Claim` resource.
|
||||
* Maps FHIR resources to PAD billing positions
|
||||
* Generates PADneXt 2.12 compliant XML
|
||||
* Validates output against XSD schemas
|
||||
* Produces JSON diagnostic reports
|
||||
* Outputs declarative `AUF` (order) information to the console.
|
||||
|
||||
2. **validate_padnext.py** - Standalone PADneXt XML validator
|
||||
* Validates PADneXt 2.12 ADL/AUF XML files against XSD schemas
|
||||
* Accepts multiple XML/XSD pairs for batch validation
|
||||
|
||||
3. **utils.py** - Utility functions
|
||||
* Contains helper functions for date parsing, reference extraction, and other common tasks.
|
||||
|
||||
4. **validation.py** - Validation framework
|
||||
* Provides a framework for semantic and business rule validation of FHIR data.
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
FHIR JSON Bundle → Validation → Resource Grouping → Mapping → PAD XML Generation → XSD Validation → Report
|
||||
```
|
||||
|
||||
**Resource Grouping**: If `Claim` resources are present, FHIR entries are grouped by `(patient_id, claim_id)`. Otherwise, they are grouped by `(patient_id, encounter_id)`. Each group becomes one `<Rechnung>` (invoice) in the PAD output.
|
||||
|
||||
**Resource Mapping**:
|
||||
* If a `Claim` resource is present, its `item` entries are mapped to `<goziffer>` positions.
|
||||
* If no `Claim` is present, the following FHIR resources are converted to billing positions:
|
||||
- `Observation`, `MedicationAdministration`, `Procedure`, `ServiceRequest`, `DiagnosticReport`
|
||||
* `ExplanationOfBenefit` resources are used to enrich the JSON report with adjudication details.
|
||||
|
||||
**Date Handling**: Effective dates extracted from FHIR fields (`effectiveDateTime`, `issued`, `authoredOn`, `date`, `meta.lastUpdated`) determine the `zeitraum` (time period) for each billing case.
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Convert FHIR to PAD XML
|
||||
|
||||
Basic conversion:
|
||||
```bash
|
||||
python3 fhir_to_pad_converter.py \
|
||||
--input-json Input.json \
|
||||
--output-xml output.xml
|
||||
```
|
||||
|
||||
With validation and report:
|
||||
```bash
|
||||
python3 fhir_to_pad_converter.py \
|
||||
--input-json samples/fhir/sample_1/226844_1240059013-KaBr.json \
|
||||
--output-xml output.xml \
|
||||
--report-json report.json \
|
||||
--pad-xsd specs/padnext/padx_adl_v2.12.xsd
|
||||
```
|
||||
|
||||
With header configuration:
|
||||
```bash
|
||||
python3 fhir_to_pad_converter.py \
|
||||
--input-json Input.json \
|
||||
--output-xml output.xml \
|
||||
--header-cfg header_config.json
|
||||
```
|
||||
|
||||
### Validate PADneXt XML
|
||||
|
||||
Single file:
|
||||
```bash
|
||||
python3 validate_padnext.py \
|
||||
samples/padnext/sample_1/00209999_20250805_ADL_000087_padx.xml \
|
||||
specs/padnext/padx_adl_v2.12.xsd
|
||||
```
|
||||
|
||||
Multiple files:
|
||||
```bash
|
||||
python3 validate_padnext.py \
|
||||
file1.xml schema1.xsd \
|
||||
file2.xml schema2.xsd
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Python 3.11+**
|
||||
- **Required**: `lxml` (XSD validation), `jsonschema` (FHIR validation)
|
||||
- **Built-in**: `xml.etree.ElementTree`, `argparse`, `json`, `datetime`, `random`
|
||||
|
||||
Install dependencies:
|
||||
```bash
|
||||
pip3 install lxml jsonschema
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
samples/
|
||||
fhir/sample_1/ - Example FHIR JSON bundles
|
||||
fhir/sample_2/ - Example FHIR JSON bundle with Claim resource
|
||||
padnext/sample_1/ - Example PADneXt XML outputs (ADL/AUF)
|
||||
specs/
|
||||
padnext/ - PADneXt 2.12 XSD schemas and documentation
|
||||
padx_adl_v2.12.xsd - ADL (billing) schema
|
||||
padx_auf_v2.12.xsd - AUF (order) schema
|
||||
padx_basis_v2.12.xsd - Base types
|
||||
padx_enums_v2.12.xsd - Enumerations
|
||||
documentation_de/ - German specification PDFs
|
||||
```
|
||||
|
||||
## Key Implementation Details
|
||||
|
||||
### PAD Namespace
|
||||
All PAD XML elements use namespace `http://padinfo.de/ns/pad`
|
||||
|
||||
### Claim-driven Conversion
|
||||
If a FHIR `Claim` resource is present in the input bundle, it is used as the primary source of information for generating the PADneXt `<Rechnung>`. The `Claim.item` entries are converted to billing positions, and information about the provider, insurer, and patient is extracted from the `Claim` and its referenced resources.
|
||||
|
||||
### Header Configuration
|
||||
Header fields (billing entity, service provider, recipient) can be configured via `--header-cfg` JSON. If a `Claim` resource is present, the information from the `Claim` will override the `header_cfg`.
|
||||
|
||||
### Validation Modes
|
||||
- **FHIR**: JSON Schema validation (if schema provided) or structural checks. A new validation framework in `validation.py` allows for custom semantic and business rule validation.
|
||||
- **PAD**: XSD validation (if XSD provided) or well-formedness checks.
|
||||
|
||||
### Report Structure
|
||||
JSON reports contain:
|
||||
- `input.schema_validation_ok` - FHIR validation status
|
||||
- `input.stats` - Resource counts, date ranges, warnings, and `ExplanationOfBenefit` stats.
|
||||
- `output.schema_validation_ok` - PAD validation status
|
||||
- `output.stats` - Invoice counts, position counts, warnings.
|
||||
- `validation_warnings` - A list of warnings from the custom validation framework.
|
||||
|
||||
### AUF Log Output
|
||||
The converter prints declarative information to the console that would be contained in a `pad_auf.xml` file, such as sender, recipient, and the number of invoices.
|
||||
|
||||
### Important Functions
|
||||
|
||||
- `group_entries()` - Groups FHIR resources by `(patient_id, claim_id)` if a `Claim` is present, otherwise by `(patient_id, encounter_id)`.
|
||||
- `claim_item_to_position()` - Maps a `Claim.item` to a PAD billing position.
|
||||
- `claim_to_rechnung_header()` - Extracts header information from a `Claim` resource.
|
||||
- `resource_to_position()` - Maps other FHIR resources to a PAD billing position (fallback).
|
||||
- `build_pad_xml()` - Main XML generation logic, now with support for `Claim`-driven conversion.
|
||||
- `run_validation()` (in `validation.py`) - Runs all custom validation checks.
|
||||
- `find_resource_by_ref()` (in `utils.py`) - Helper function to resolve references within a FHIR bundle.
|
||||
BIN
__pycache__/utils.cpython-311.pyc
Normal file
BIN
__pycache__/utils.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/validation.cpython-311.pyc
Normal file
BIN
__pycache__/validation.cpython-311.pyc
Normal file
Binary file not shown.
BIN
_archived/.DS_Store
vendored
Normal file
BIN
_archived/.DS_Store
vendored
Normal file
Binary file not shown.
65
_archived/validate_padnext.py
Normal file
65
_archived/validate_padnext.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
# validate_padnext_2_12.py
|
||||
# Validate PADneXt 2.12 ADL and AUF XML files against XSDs using lxml.
|
||||
# Usage:
|
||||
# python validate_padnext_2_12.py <XML_FILE> <XSD_FILE> [<XML_FILE> <XSD_FILE> ...]
|
||||
|
||||
from lxml import etree
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
def load_schema(xsd_path: Path) -> etree.XMLSchema:
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
doc = etree.parse(str(xsd_path), parser)
|
||||
return etree.XMLSchema(doc)
|
||||
|
||||
def validate(xml_path: Path, schema: etree.XMLSchema):
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
doc = etree.parse(str(xml_path), parser)
|
||||
ok = schema.validate(doc)
|
||||
return ok, schema.error_log
|
||||
|
||||
def main(argv):
|
||||
if len(argv) < 3 or len(argv[1:]) % 2 != 0:
|
||||
print("Usage: python validate_padnext_2_12.py <XML_FILE> <XSD_FILE> [<XML_FILE> <XSD_FILE> ...]")
|
||||
return 2
|
||||
|
||||
# Process pairs
|
||||
for i in range(1, len(argv), 2):
|
||||
xml_path = Path(argv[i])
|
||||
xsd_path = Path(argv[i+1])
|
||||
|
||||
print(f"— Validate —")
|
||||
print(f" XML: {xml_path}")
|
||||
print(f" XSD: {xsd_path}")
|
||||
|
||||
try:
|
||||
schema = load_schema(xsd_path)
|
||||
except Exception as e:
|
||||
print(" ❌ Failed to load schema:")
|
||||
print(textwrap.indent(str(e), " "))
|
||||
print()
|
||||
continue
|
||||
|
||||
try:
|
||||
ok, log = validate(xml_path, schema)
|
||||
except Exception as e:
|
||||
print(" ❌ Exception during validation:")
|
||||
print(textwrap.indent(str(e), " "))
|
||||
print()
|
||||
continue
|
||||
|
||||
if ok:
|
||||
print(" ✅ VALID\n")
|
||||
else:
|
||||
print(" ❌ NOT VALID")
|
||||
for entry in log:
|
||||
loc = f"{Path(entry.filename).name if entry.filename else xml_path.name}:{entry.line}:{entry.column}"
|
||||
print(f" - {loc}: {entry.message}")
|
||||
print()
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
BIN
docs/.DS_Store
vendored
Normal file
BIN
docs/.DS_Store
vendored
Normal file
Binary file not shown.
66
docs/FHIR_to_PADneXt_Mapping.md
Normal file
66
docs/FHIR_to_PADneXt_Mapping.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# FHIR to PADneXt Mapping
|
||||
|
||||
This document outlines the mapping from FHIR resources to the PADneXt 2.12 XML format, as implemented in the `fhir_to_pad_converter.py` script.
|
||||
|
||||
## General Mapping Strategy
|
||||
|
||||
The conversion process groups FHIR resources into PADneXt `<Rechnung>` (invoice) elements. The grouping strategy depends on the presence of `Claim` resources in the input FHIR bundle:
|
||||
|
||||
- **Claim-based Grouping:** If `Claim` resources are present, each unique combination of `(patient_id, claim_id)` forms a separate `<Rechnung>`. This is the primary and most structured mapping approach.
|
||||
- **Encounter-based Grouping:** If no `Claim` resources are found, the script falls back to grouping resources by `(patient_id, encounter_id)`. Each of these groups becomes a `<Rechnung>`.
|
||||
|
||||
## Header Mapping
|
||||
|
||||
The PADneXt header elements are populated from a combination of a configuration file (`--header-cfg`) and data extracted from FHIR resources. If a `Claim` resource is present, its data overrides the configuration file.
|
||||
|
||||
| PADneXt Element | FHIR Resource & Field | Description |
|
||||
|---|---|---|
|
||||
| `<rechnungsersteller>` | (from `header_cfg.json`) | Information about the entity creating the invoice. |
|
||||
| `<leistungserbringer>` | `Claim.provider` -> `Organization.name` | The healthcare provider who delivered the services. |
|
||||
| `<rechnungsempfaenger>` | `Claim.insurer` -> `Organization.name` | The recipient of the invoice, typically an insurance company. |
|
||||
|
||||
## Patient and Case Mapping
|
||||
|
||||
Patient and billing case information is mapped as follows:
|
||||
|
||||
| PADneXt Element | FHIR Resource & Field | Description |
|
||||
|---|---|---|
|
||||
| `<behandelter>` (Patient) | `Claim.patient` -> `Patient` | The patient who received the care. |
|
||||
| `behandelter.vorname` | `Patient.name.given` | Patient's given name. |
|
||||
| `behandelter.name` | `Patient.name.family` | Patient's family name. |
|
||||
| `behandelter.gebdatum` | `Patient.birthDate` | Patient's date of birth. |
|
||||
| `<abrechnungsfall>` | (Generated for each group) | Represents a billing case. |
|
||||
| `zeitraum.startdatum` | `min(effective dates)` | The earliest date found across all `effectiveDateTime`, `issued`, `authoredOn`, `date`, and `meta.lastUpdated` fields in the resource group. |
|
||||
| `zeitraum.endedatum` | `max(effective dates)` | The latest date found across the same date fields. |
|
||||
| `diagnose.text` | `Claim.diagnosis.diagnosisCodeableConcept.coding.display` | The primary diagnosis for the claim. |
|
||||
| `diagnose.datum` | `Claim.created` | The creation date of the claim. |
|
||||
|
||||
## Billing Position Mapping (`<goziffer>`)
|
||||
|
||||
Billing positions are created within the `<positionen>` element of each `<abrechnungsfall>`. The mapping logic differs based on whether a `Claim` resource is present.
|
||||
|
||||
### Claim-based Position Mapping
|
||||
|
||||
When a `Claim` resource is available, its `item` entries are mapped directly to `<goziffer>` elements.
|
||||
|
||||
| PADneXt `<goziffer>` Attribute | FHIR `Claim.item` Field | Description |
|
||||
|---|---|---|
|
||||
| `id` | `sequence` | The sequence number of the item in the claim. |
|
||||
| `ziffer` | `productOrService.coding.code` | The billing code for the service or product. |
|
||||
| `datum` | `servicedDate` | The date the service was provided. |
|
||||
| `text` | `productOrService.coding.display` | The display name of the service or product. |
|
||||
| `anzahl` | "1" (hardcoded) | The quantity of the service (currently hardcoded to 1). |
|
||||
|
||||
### Resource-based Position Mapping (Fallback)
|
||||
|
||||
If no `Claim` resource is present, the script iterates through other resources and maps them to billing positions. This is a fallback mechanism.
|
||||
|
||||
**Mappable FHIR Resources:** `Observation`, `MedicationAdministration`, `Procedure`, `ServiceRequest`, `DiagnosticReport`
|
||||
|
||||
| PADneXt `<goziffer>` Attribute | FHIR Field | Description |
|
||||
|---|---|---|
|
||||
| `id` | `id` | The ID of the FHIR resource. |
|
||||
| `ziffer` | `code.coding.code` | The primary code from the resource's `code` element. |
|
||||
| `datum` | `effectiveDateTime`, `issued`, `authoredOn`, `date`, or `meta.lastUpdated` | The first available date from a prioritized list of date fields. |
|
||||
| `text` | `code.coding.display` or `resourceType` | The display text for the code, or the resource type if no display is available. |
|
||||
| `anzahl` | "1" (hardcoded) | The quantity (hardcoded to 1). |
|
||||
1386
fhir_to_pad_converter.py
Normal file
1386
fhir_to_pad_converter.py
Normal file
File diff suppressed because it is too large
Load Diff
82
placeholder_config.json
Normal file
82
placeholder_config.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"_comment": "Placeholder values for required PADneXt fields when FHIR data is incomplete",
|
||||
"_usage": "Use different config files for different FHIR sources with: --placeholder-cfg placeholder_config.json",
|
||||
|
||||
"rechnungsersteller": {
|
||||
"name": "UNKNOWN",
|
||||
"plz": "00000",
|
||||
"ort": "UNKNOWN",
|
||||
"strasse": "UNKNOWN"
|
||||
},
|
||||
|
||||
"leistungserbringer": {
|
||||
"vorname": "UNKNOWN",
|
||||
"name": "UNKNOWN",
|
||||
"titel": null,
|
||||
"_comment_titel": "null means skip optional field if missing"
|
||||
},
|
||||
|
||||
"empfaenger": {
|
||||
"anrede": "Ohne Anrede",
|
||||
"vorname": "UNKNOWN",
|
||||
"name": "UNKNOWN",
|
||||
"plz": "00000",
|
||||
"ort": "UNKNOWN",
|
||||
"strasse": "UNKNOWN",
|
||||
"gebdatum": "1900-01-01",
|
||||
"geschlecht": "u",
|
||||
"_comment_geschlecht": "Valid values: m (male), w (female), u (unknown)"
|
||||
},
|
||||
|
||||
"behandelter": {
|
||||
"anrede": null,
|
||||
"vorname": "UNKNOWN",
|
||||
"name": "UNKNOWN",
|
||||
"gebdatum": "1900-01-01",
|
||||
"geschlecht": "u",
|
||||
"_comment_behandelter": "Behandelter does NOT have anschrift field"
|
||||
},
|
||||
|
||||
"versicherter": {
|
||||
"anrede": "Ohne Anrede",
|
||||
"vorname": "UNKNOWN",
|
||||
"name": "UNKNOWN",
|
||||
"gebdatum": "1900-01-01",
|
||||
"geschlecht": "u",
|
||||
"_comment_versicherter": "Versicherter has all person fields including geschlecht"
|
||||
},
|
||||
|
||||
"rechnung": {
|
||||
"eabgabe": null,
|
||||
"aisaktenzeichen": null,
|
||||
"aisendbetrag": null,
|
||||
"_comment_attributes": "null means skip optional attribute if missing"
|
||||
},
|
||||
|
||||
"abrechnungsfall": {
|
||||
"behandlungsart": "0",
|
||||
"vertragsart": "1",
|
||||
"_comment_behandlungsart": "Valid values: 0 (ambulant), 1 (stationär), 2 (stationär Mitbehandlung), 3 (vorstationär), 4 (nachstationär), 5 (konsiliar)",
|
||||
"_comment_vertragsart": "1-3 digit positive integer representing contract type"
|
||||
},
|
||||
|
||||
"zeitraum": {
|
||||
"startdatum": "1900-01-01",
|
||||
"endedatum": "1900-01-01",
|
||||
"_comment": "Placeholder dates when no dates found in FHIR data"
|
||||
},
|
||||
|
||||
"goziffer": {
|
||||
"go": "EBM",
|
||||
"ziffer": "99999",
|
||||
"datum": "1900-01-01",
|
||||
"_comment_go": "Valid values: GOAE (physician fee schedule), UVGOAE (accident insurance), EBM (uniform assessment standard). Using EBM as default for general medical services.",
|
||||
"_comment_ziffer": "Placeholder billing code (max 8 chars) when FHIR code is missing or too long",
|
||||
"_comment_datum": "Placeholder date when service date is missing"
|
||||
},
|
||||
|
||||
"diagnose": {
|
||||
"datum": "1900-01-01",
|
||||
"_comment": "Placeholder date when diagnosis date is missing"
|
||||
}
|
||||
}
|
||||
BIN
ressources/.DS_Store
vendored
Normal file
BIN
ressources/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
ressources/GOÄ/GOÄ.pdf
Normal file
BIN
ressources/GOÄ/GOÄ.pdf
Normal file
Binary file not shown.
BIN
samples/.DS_Store
vendored
Normal file
BIN
samples/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
samples/fhir/.DS_Store
vendored
Normal file
BIN
samples/fhir/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
samples/fhir/sample_1/.DS_Store
vendored
Normal file
BIN
samples/fhir/sample_1/.DS_Store
vendored
Normal file
Binary file not shown.
269263
samples/fhir/sample_1/226844_1240059013-KaBr.json
Normal file
269263
samples/fhir/sample_1/226844_1240059013-KaBr.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
samples/fhir/sample_1/helpers/226844_1240059013-KaBr.xlsx
Normal file
BIN
samples/fhir/sample_1/helpers/226844_1240059013-KaBr.xlsx
Normal file
Binary file not shown.
3289
samples/fhir/sample_1/helpers/226844_Brück__Karola_Jul24-1.pdf
Normal file
3289
samples/fhir/sample_1/helpers/226844_Brück__Karola_Jul24-1.pdf
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
204
samples/fhir/sample_2/claim-sample.json
Normal file
204
samples/fhir/sample_2/claim-sample.json
Normal file
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"resourceType": "Bundle",
|
||||
"type": "collection",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "urn:uuid:45673360-9b71-1f40-0184-888d6ea4f9c4",
|
||||
"resource": {
|
||||
"resourceType": "Patient",
|
||||
"id": "patient-1",
|
||||
"name": [
|
||||
{
|
||||
"family": "Brück",
|
||||
"given": [
|
||||
"Karola"
|
||||
]
|
||||
}
|
||||
],
|
||||
"gender": "female",
|
||||
"birthDate": "1958-07-08"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:26c65f6a-9e4b-5bc1-6f0b-aca5b2f71a7a",
|
||||
"resource": {
|
||||
"resourceType": "Encounter",
|
||||
"id": "encounter-1",
|
||||
"status": "finished",
|
||||
"class": {
|
||||
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
|
||||
"code": "IMP",
|
||||
"display": "inpatient encounter"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "Patient/patient-1"
|
||||
},
|
||||
"period": {
|
||||
"start": "2024-07-08T10:00:00+02:00",
|
||||
"end": "2024-07-18T14:00:00+02:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:0003706f-ddaf-d3a7-b792-907d47519157",
|
||||
"resource": {
|
||||
"resourceType": "Observation",
|
||||
"id": "obs-1",
|
||||
"status": "final",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "26515-7",
|
||||
"display": "Thrombozyten"
|
||||
}
|
||||
],
|
||||
"text": "Thrombozyten"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "Patient/patient-1"
|
||||
},
|
||||
"encounter": {
|
||||
"reference": "Encounter/encounter-1"
|
||||
},
|
||||
"effectiveDateTime": "2024-07-18T11:49:00+02:00",
|
||||
"valueQuantity": {
|
||||
"value": 385,
|
||||
"unit": "10^3/uL",
|
||||
"system": "http://unitsofmeasure.org",
|
||||
"code": "10*3/uL"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:claim-1",
|
||||
"resource": {
|
||||
"resourceType": "Claim",
|
||||
"id": "claim-1",
|
||||
"status": "active",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://terminology.hl7.org/CodeSystem/claim-type",
|
||||
"code": "institutional"
|
||||
}
|
||||
]
|
||||
},
|
||||
"use": "claim",
|
||||
"patient": {
|
||||
"reference": "Patient/patient-1"
|
||||
},
|
||||
"created": "2024-07-20T10:00:00+02:00",
|
||||
"provider": {
|
||||
"reference": "Organization/provider-org-1"
|
||||
},
|
||||
"insurer": {
|
||||
"reference": "Organization/insurer-org-1"
|
||||
},
|
||||
"priority": {
|
||||
"coding": [
|
||||
{
|
||||
"code": "normal"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosis": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"diagnosisCodeableConcept": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://hl7.org/fhir/sid/icd-10-gm",
|
||||
"code": "J44.0",
|
||||
"display": "Chronische obstruktive Lungenkrankheit mit akuter Infektion der unteren Atemwege"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"item": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"servicedDate": "2024-07-18",
|
||||
"productOrService": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "26515-7",
|
||||
"display": "Thrombozyten"
|
||||
}
|
||||
]
|
||||
},
|
||||
"encounter": [
|
||||
{
|
||||
"reference": "Encounter/encounter-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:eob-1",
|
||||
"resource": {
|
||||
"resourceType": "ExplanationOfBenefit",
|
||||
"id": "eob-1",
|
||||
"status": "active",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://terminology.hl7.org/CodeSystem/claim-type",
|
||||
"code": "institutional"
|
||||
}
|
||||
]
|
||||
},
|
||||
"use": "claim",
|
||||
"patient": {
|
||||
"reference": "Patient/patient-1"
|
||||
},
|
||||
"created": "2024-07-25T10:00:00+02:00",
|
||||
"insurer": {
|
||||
"reference": "Organization/insurer-org-1"
|
||||
},
|
||||
"provider": {
|
||||
"reference": "Organization/provider-org-1"
|
||||
},
|
||||
"claim": {
|
||||
"reference": "Claim/claim-1"
|
||||
},
|
||||
"outcome": "complete",
|
||||
"total": [
|
||||
{
|
||||
"category": {
|
||||
"coding": [
|
||||
{
|
||||
"code": "submitted"
|
||||
}
|
||||
]
|
||||
},
|
||||
"amount": {
|
||||
"value": 100.0,
|
||||
"currency": "EUR"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:provider-org-1",
|
||||
"resource": {
|
||||
"resourceType": "Organization",
|
||||
"id": "provider-org-1",
|
||||
"name": "Dr. med. Max Mustermann"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:insurer-org-1",
|
||||
"resource": {
|
||||
"resourceType": "Organization",
|
||||
"id": "insurer-org-1",
|
||||
"name": "PVS Rhein-Ruhr GmbH"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
samples/padnext/.DS_Store
vendored
Normal file
BIN
samples/padnext/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="iso-8859-15"?>
|
||||
<Auftrag xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" erstellungsdatum="2025-08-05T14:11:25.0752082Z" transfernr="87" echtdaten="true" dateianzahl="1" xmlns="http://padinfo.de/ns/pad">
|
||||
<empfaenger>
|
||||
<logisch pvsid="2100" iknr="999999999">PVS Rhein-Ruhr GmbH</logisch>
|
||||
<physikalisch pvsid="2100" iknr="999999999">PVS Rhein-Ruhr GmbH</physikalisch>
|
||||
</empfaenger>
|
||||
<absender>
|
||||
<logisch pvskundennr="209999">Dr. med. Max Mustermann</logisch>
|
||||
<physikalisch pvskundennr="209999">Dr. med. Max Mustermann</physikalisch>
|
||||
</absender>
|
||||
<nachrichtentyp version="01.10">ADL</nachrichtentyp>
|
||||
<system>
|
||||
<produkt>iSOFT Billing</produkt>
|
||||
<version>1.0</version>
|
||||
<hersteller>iSOFT Health GmbH</hersteller>
|
||||
</system>
|
||||
<verschluesselung verfahren="1" />
|
||||
<empfangsquittung>false</empfangsquittung>
|
||||
<datei id="f6bc38e5-0458-4857-a955-16c8aea89c1b" erstellungsdatum="2025-08-05T14:11:15.8876479Z">
|
||||
<dokumententyp>PADx</dokumententyp>
|
||||
<name>00209999_20250805_ADL_000087_padx.xml</name>
|
||||
<dateilaenge laenge="167131" pruefsumme="0d924f9f2bed8f69191640963601a988740d58ce" />
|
||||
</datei>
|
||||
</Auftrag>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="iso-8859-15"?>
|
||||
<Rechnungen xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" anzahl="50" xmlns="http://padinfo.de/ns/pad">
|
||||
<nachrichtentyp version="01.10">ADL</nachrichtentyp>
|
||||
<rechnungsersteller>
|
||||
<name>Dr. med. Max Mustermann</name>
|
||||
<pvskundennr>209999</pvskundennr>
|
||||
<anschrift>
|
||||
<strasse>Musterstrasse 1</strasse>
|
||||
<hausnr>2</hausnr>
|
||||
<plz>99999</plz>
|
||||
<ort>Musterhausen</ort>
|
||||
<land>D</land>
|
||||
</anschrift>
|
||||
<iknr>207450</iknr>
|
||||
</rechnungsersteller>
|
||||
<leistungserbringer id="00001">
|
||||
<titel>Dr. med.</titel>
|
||||
<vorname>Max</vorname>
|
||||
<name>Mustermann</name>
|
||||
</leistungserbringer>
|
||||
<Rechnung id="1cc6f678-5d27-4ef9-ba76-1c1d84aa9f80" eabgabe="false" aisaktenzeichen="SVA551681" aisendbetrag="30.83">
|
||||
<rechnungsempfaenger>
|
||||
<person>
|
||||
<anrede>Herr</anrede>
|
||||
<vorname>Max</vorname>
|
||||
<name>Muster</name>
|
||||
<anschrift>
|
||||
<strasse>Musterstrasse 2</strasse>
|
||||
<hausnr>2</hausnr>
|
||||
<plz>99999</plz>
|
||||
<ort>Musterhausen</ort>
|
||||
<land>D</land>
|
||||
</anschrift>
|
||||
</person>
|
||||
</rechnungsempfaenger>
|
||||
<abrechnungsfall>
|
||||
<behandelter aisid="5014547">
|
||||
<anrede>Herr</anrede>
|
||||
<vorname>Max</vorname>
|
||||
<name>Muster</name>
|
||||
<gebdatum>1953-05-12</gebdatum>
|
||||
<geschlecht>m</geschlecht>
|
||||
</behandelter>
|
||||
<versicherter>
|
||||
<anrede>Herr</anrede>
|
||||
<vorname>Max</vorname>
|
||||
<name>Muster</name>
|
||||
<gebdatum>1953-05-12</gebdatum>
|
||||
<geschlecht>m</geschlecht>
|
||||
<anschrift>
|
||||
<strasse>Musterstrasse</strasse>
|
||||
<hausnr>2</hausnr>
|
||||
<plz>99999</plz>
|
||||
<ort>Musterhausen</ort>
|
||||
<land>D</land>
|
||||
</anschrift>
|
||||
</versicherter>
|
||||
<zeitraum>
|
||||
<startdatum>2025-07-03</startdatum>
|
||||
<endedatum>2025-07-03</endedatum>
|
||||
</zeitraum>
|
||||
<behandlungsart>0</behandlungsart>
|
||||
<vertragsart>1</vertragsart>
|
||||
<aktenzeichen>227205</aktenzeichen>
|
||||
<diagnose>
|
||||
<text>springender Finger D3 links</text>
|
||||
<datum>2025-07-03</datum>
|
||||
</diagnose>
|
||||
<positionen posanzahl="2">
|
||||
<goziffer id="2759969" go="GOAE" ziffer="3">
|
||||
<datum>2025-07-03</datum>
|
||||
<anzahl>1</anzahl>
|
||||
<text>Eingehende Beratung mind. 10 min.</text>
|
||||
<faktor>2.3</faktor>
|
||||
<umsatzsteuer>0</umsatzsteuer>
|
||||
<minderungssatz>0</minderungssatz>
|
||||
<aisbewertung>
|
||||
<punktwert>0.0582873</punktwert>
|
||||
<punktzahl>150</punktzahl>
|
||||
<einzelbetrag>20.11</einzelbetrag>
|
||||
</aisbewertung>
|
||||
</goziffer>
|
||||
<goziffer id="2759970" go="GOAE" ziffer="5">
|
||||
<datum>2025-07-03</datum>
|
||||
<anzahl>1</anzahl>
|
||||
<text>Untersuchung, symptombezogen</text>
|
||||
<faktor>2.3</faktor>
|
||||
<umsatzsteuer>0</umsatzsteuer>
|
||||
<minderungssatz>0</minderungssatz>
|
||||
<aisbewertung>
|
||||
<punktwert>0.0582873</punktwert>
|
||||
<punktzahl>80</punktzahl>
|
||||
<einzelbetrag>10.72</einzelbetrag>
|
||||
</aisbewertung>
|
||||
</goziffer>
|
||||
</positionen>
|
||||
</abrechnungsfall>
|
||||
</Rechnung>
|
||||
</Rechnungen>
|
||||
BIN
specs/.DS_Store
vendored
Normal file
BIN
specs/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
specs/padnext/.DS_Store
vendored
Normal file
BIN
specs/padnext/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
specs/padnext/documentation_de/padnext_v2.12-1.pdf
Normal file
BIN
specs/padnext/documentation_de/padnext_v2.12-1.pdf
Normal file
Binary file not shown.
23
specs/padnext/padx_adl_v2.12.xsd
Normal file
23
specs/padnext/padx_adl_v2.12.xsd
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Mit XMLSpy v2015 rel. 4 sp1 (x64) (http://www.altova.com) von Jan Brötzmann (quadcore GmbH) bearbeitet -->
|
||||
<xs:schema xmlns:pad="http://padinfo.de/ns/pad" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:altova="http://www.altova.com/xml-schema-extensions" targetNamespace="http://padinfo.de/ns/pad" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.12">
|
||||
<xs:include schemaLocation="padx_basis_v2.12.xsd"/>
|
||||
<xs:element name="rechnungen" type="pad:Rechnung.Liste">
|
||||
<xs:unique name="Rechnung.Key">
|
||||
<xs:selector xpath="pad:rechnung"/>
|
||||
<xs:field xpath="@id"/>
|
||||
</xs:unique>
|
||||
<xs:key name="LE.Key">
|
||||
<xs:selector xpath="pad:leistungserbringer"/>
|
||||
<xs:field xpath="@id"/>
|
||||
</xs:key>
|
||||
<xs:keyref name="LEAbrechnung.Ref" refer="pad:LE.Key">
|
||||
<xs:selector xpath="pad:rechnung/pad:abrechnungsfall/*"/>
|
||||
<xs:field xpath="pad:leistungserbringerid"/>
|
||||
</xs:keyref>
|
||||
<xs:keyref name="LEGO.Ref" refer="pad:LE.Key">
|
||||
<xs:selector xpath="pad:rechnung/pad:abrechnungsfall/*/pad:positionen/*"/>
|
||||
<xs:field xpath="pad:leistungserbringerid"/>
|
||||
</xs:keyref>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
216
specs/padnext/padx_auf_v2.12.xsd
Normal file
216
specs/padnext/padx_auf_v2.12.xsd
Normal file
@@ -0,0 +1,216 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- Mit XMLSpy v2015 rel. 4 sp1 (x64) (http://www.altova.com) von Jan Brötzmann (quadcore GmbH) bearbeitet -->
|
||||
<xsd:schema xmlns="http://padinfo.de/ns/pad" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pad="http://padinfo.de/ns/pad" xmlns:altova="http://www.altova.com/xml-schema-extensions" targetNamespace="http://padinfo.de/ns/pad" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.12">
|
||||
<xsd:include schemaLocation="padx_basis_v2.12.xsd"/>
|
||||
<xsd:element name="auftrag">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="empfaenger" type="Teilnehmer.Typ">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Empfänger der Datenlieferung.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="absender" type="pad:Teilnehmer.Typ">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Absender der Datenlieferung.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="nachrichtentyp" type="pad:Nachrichtentyp.Typ"/>
|
||||
<xsd:element name="system">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Angaben über das System, dass die Daten erstellt hat.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="produkt">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<altova:exampleValues>
|
||||
<altova:example value="PAD Comfort"/>
|
||||
</altova:exampleValues>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="40"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
<xsd:element name="version">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<altova:exampleValues>
|
||||
<altova:example value="1.00"/>
|
||||
</altova:exampleValues>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="20"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
<xsd:element name="hersteller">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<altova:exampleValues>
|
||||
<altova:example value="PVS"/>
|
||||
</altova:exampleValues>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="40"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
<xsd:element name="zertifizierungsnr" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Diese Nummer wird beim Zertifizierungsprozess für das jeweilige System vergeben.</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<altova:exampleValues>
|
||||
<altova:example value="PADx-AIS-2009-001"/>
|
||||
</altova:exampleValues>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="20"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="verschluesselung">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="verfahren" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>PKCS7, keine.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:decimal">
|
||||
<xsd:totalDigits value="1"/>
|
||||
<xsd:enumeration value="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Keine Verschlüsselung.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>PKCS#7 Verfahren.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="idcert" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Kennung für Empfänger Zertifikat (enthält öffentlichen Schlüssel).</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="128"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="empfangsquittung">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Ist eine Empfangsbestätigung für diese Datenlieferung erwünscht? Mit email Adresse.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:boolean">
|
||||
<xsd:attribute name="email">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="100"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="datei" type="pad:Datei.Typ" maxOccurs="9999">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Informationen über alle Nutzdateien der Datenlieferung.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="erstellungsdatum" type="xsd:dateTime" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Erstellungsdatum mit Uhrzeit des Auftrages.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="transfernr" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Pro Empfänger wird eine laufende Nummer hochgezählt</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:positiveInteger">
|
||||
<xsd:totalDigits value="6"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="echtdaten" type="xsd:boolean" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Kennug, ob es sich um Echt- oder Testdaten handelt.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="dateianzahl" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Anzahl der Dateien pro Datenlieferung (ohne Auftragsdatei).</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:positiveInteger">
|
||||
<xsd:totalDigits value="4"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
<xsd:unique name="Datei.Key">
|
||||
<xsd:selector xpath="pad:datei"/>
|
||||
<xsd:field xpath="@id"/>
|
||||
</xsd:unique>
|
||||
</xsd:element>
|
||||
<xsd:complexType name="Datei.Typ">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="dokumententyp" type="pad:Dokumenttyp.Typ"/>
|
||||
<xsd:element name="name">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Dateiname, ohne Pfadangaben.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="40"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
<xsd:element name="beschreibung" minOccurs="0">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="60"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
<xsd:element name="dateilaenge" type="pad:Dateilaenge.Typ">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Dateigröße unverschlüsselt und unkomprimiert.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="pad:Id.Typ" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Eindeutige Identifikation für Datei innerhalb einer Datenlieferung.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="erstellungsdatum" type="xsd:dateTime" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Erstellungsdatum mit Uhrzeit der Datei.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
3296
specs/padnext/padx_basis_v2.12.xsd
Normal file
3296
specs/padnext/padx_basis_v2.12.xsd
Normal file
File diff suppressed because it is too large
Load Diff
1490
specs/padnext/padx_enums_v2.12.xsd
Normal file
1490
specs/padnext/padx_enums_v2.12.xsd
Normal file
File diff suppressed because it is too large
Load Diff
50
specs/padnext/padx_qadl_v2.12.xsd
Normal file
50
specs/padnext/padx_qadl_v2.12.xsd
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Mit XMLSpy v2015 rel. 4 sp1 (x64) (http://www.altova.com) von Jan Brötzmann (quadcore GmbH) bearbeitet -->
|
||||
<xs:schema xmlns:pad="http://padinfo.de/ns/pad" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://padinfo.de/ns/pad" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.12">
|
||||
<xs:include schemaLocation="padx_basis_v2.12.xsd"/>
|
||||
<xs:element name="Quittung">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Quittungsinformationen für eine Datenlieferung</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="nachrichtentyp" type="pad:Nachrichtentyp.Typ" fixed="QADL"/>
|
||||
<xs:element name="eingangsdatum" type="xs:dateTime">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Eingangsdatum mit Uhrzeit der Datenlieferung bei der PVS.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="status" type="xs:positiveInteger">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Verarbeitungsstatus der gesamten Datenlieferung.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="fehler" type="pad:Fehler.Typ" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Fehlerangabe für die gesamte Datenlieferung.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="datenlieferung" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Enthält die Transfernummer der zu quittierenden Datenlieferung und gibt den Inhalt des Feldes aus der Auftragsdatei an.</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:positiveInteger">
|
||||
<xs:totalDigits value="6"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="dateianzahl" type="xs:positiveInteger" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Anzahl der eingegangenen Dateien innerhalb der Datenlieferung.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="rechnungsanzahl" type="xs:nonNegativeInteger" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Anzahl der Rechnungen innerhalb der Datenlieferung.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
46
utils.py
Normal file
46
utils.py
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Utility functions for the FHIR to PAD converter.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
def parse_iso_date(s: str) -> Optional[datetime]:
|
||||
try:
|
||||
return datetime.fromisoformat(s.replace("Z", "+00:00"))
|
||||
except (ValueError, TypeError):
|
||||
try:
|
||||
return datetime.fromisoformat(s)
|
||||
except (ValueError, TypeError):
|
||||
return None
|
||||
|
||||
def format_iso_date(d: datetime) -> str:
|
||||
return d.date().isoformat()
|
||||
|
||||
def get_ref_id(ref: Optional[str]) -> Optional[str]:
|
||||
if not ref or "/" not in ref:
|
||||
return None
|
||||
return ref.split("/")[-1] or None
|
||||
|
||||
def ensure_text(el: Optional[ET.Element], default: str = "") -> str:
|
||||
if el is None:
|
||||
return default
|
||||
return (el.text or "").strip()
|
||||
|
||||
def collect_effective_dates(resource: Dict[str, Any]) -> List[datetime]:
|
||||
dates: List[datetime] = []
|
||||
for key in ["effectiveDateTime", "issued", "authoredOn", "date"]:
|
||||
val = resource.get(key)
|
||||
if isinstance(val, str):
|
||||
d = parse_iso_date(val)
|
||||
if d:
|
||||
dates.append(d)
|
||||
meta = resource.get("meta", {})
|
||||
if isinstance(meta, dict) and isinstance(meta.get("lastUpdated"), str):
|
||||
d = parse_iso_date(meta["lastUpdated"])
|
||||
if d:
|
||||
dates.append(d)
|
||||
return dates
|
||||
36
validation.py
Normal file
36
validation.py
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Validation rules for the FHIR to PAD converter.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List
|
||||
from utils import collect_effective_dates
|
||||
|
||||
def validate_temporal_consistency(grouped_resources: List[Dict[str, Any]]) -> List[str]:
|
||||
"""Checks for temporal consistency within a group of resources."""
|
||||
warnings = []
|
||||
now = datetime.now()
|
||||
for resource in grouped_resources:
|
||||
dates = collect_effective_dates(resource)
|
||||
for d in dates:
|
||||
if d.timestamp() > now.timestamp():
|
||||
warnings.append(f"Resource {resource.get('id')} has an effective date in the future: {d.isoformat()}")
|
||||
return warnings
|
||||
|
||||
def validate_codes(grouped_resources: List[Dict[str, Any]]) -> List[str]:
|
||||
"""Checks for the validity of codes (e.g., ICD-10, GOÄ)."""
|
||||
warnings = []
|
||||
# Placeholder for code validation logic
|
||||
return warnings
|
||||
|
||||
def run_validation(grouped_resources: List[Dict[str, Any]]) -> List[str]:
|
||||
"""Runs all validation checks on a group of resources."""
|
||||
all_warnings = []
|
||||
all_warnings.extend(validate_temporal_consistency(grouped_resources))
|
||||
all_warnings.extend(validate_codes(grouped_resources))
|
||||
return all_warnings
|
||||
Reference in New Issue
Block a user