# 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). |
