diff --git a/.github/workflows/format.yaml b/.github/workflows/format.yaml
new file mode 100644
index 0000000..2897c2e
--- /dev/null
+++ b/.github/workflows/format.yaml
@@ -0,0 +1,30 @@
+name: Check formatting
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [main]
+
+jobs:
+ black:
+ name: Black
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.x"
+
+ - name: Install pipx
+ run: sudo apt update && sudo apt install pipx && pipx ensurepath
+
+ - name: Install Black
+ run: pipx install --global black
+
+ - name: Check formatting
+ run: black --check --diff --include='.*\.py' ./service
diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml
index 710ab3d..db51e1b 100644
--- a/.github/workflows/unittest.yml
+++ b/.github/workflows/unittest.yml
@@ -4,10 +4,10 @@ name: Run Unittests
# Controls when the action will run.
on:
- push:
- paths: [ main ]
- pull_request:
- branches: [ main ]
+ # push:
+ # paths: [ main ]
+ # pull_request:
+ # branches: [ main ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 0b07798..8cf1d1e 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -13,7 +13,7 @@
"justMyCode": true,
"args": [
"--project-dir",
- "../../projects/erp",
+ "../../../structure-comparer-projects/erp",
"--html",
"--json"
],
diff --git a/service/README.md b/service/README.md
index fd60950..fd42ceb 100644
--- a/service/README.md
+++ b/service/README.md
@@ -16,6 +16,17 @@ From `service/` build and start the image with
docker compose up
```
+## CLI mode (WIP)
+The CLI mode is currently a work in progress. However, the following functionality is already available:
+
+### Generating a file containing a mapping
+(Currently only HTML is supported, but JSON support is coming soon)
+```bash
+python -m structure_comparer output --project-dir {project directory} --format html --mapping_id {mapping id}
+```
+Both --format and --mapping_id are optional.
+The default format is HTML. If --mapping_id is omitted, the tool will generate files for all the mappings contained in the project.
+
### Developers
The project uses _Poetry_ for the project set-up but can also be installed with plain `pip`.
diff --git a/service/src/mapper.py b/service/src/mapper.py
index ed7abbd..141b150 100644
--- a/service/src/mapper.py
+++ b/service/src/mapper.py
@@ -1,48 +1,56 @@
import json
+
def load_json_file(file_path):
"""
Lädt JSON-Daten aus einer Datei.
"""
- with open(file_path, 'r') as file:
+ with open(file_path, "r") as file:
return json.load(file)
+
def map_medication_code_coding(kbv_medication, epa_medication):
"""
Mappt das Medication.code.coding-Element von einem KBV-Profil zum ePA-Profil.
"""
- if 'code' in kbv_medication and 'coding' in kbv_medication['code']:
- epa_medication['code'] = {'coding': []}
- for coding in kbv_medication['code']['coding']:
- epa_medication['code']['coding'].append({
- 'system': coding.get('system', ''),
- 'code': coding.get('code', ''),
- 'display': coding.get('display', '')
- })
+ if "code" in kbv_medication and "coding" in kbv_medication["code"]:
+ epa_medication["code"] = {"coding": []}
+ for coding in kbv_medication["code"]["coding"]:
+ epa_medication["code"]["coding"].append(
+ {
+ "system": coding.get("system", ""),
+ "code": coding.get("code", ""),
+ "display": coding.get("display", ""),
+ }
+ )
+
def map_medication_amount(kbv_medication, epa_medication):
"""
Mappt das Medication.amount-Element von einem KBV-Profil zum ePA-Profil.
"""
- if 'amount' in kbv_medication:
- epa_medication['amount'] = {
- 'numerator': {
- 'value': kbv_medication['amount'].get('numerator', {}).get('value', ''),
- 'unit': kbv_medication['amount'].get('numerator', {}).get('unit', ''),
- 'system': 'http://unitsofmeasure.org',
- 'code': kbv_medication['amount'].get('numerator', {}).get('code', '')
+ if "amount" in kbv_medication:
+ epa_medication["amount"] = {
+ "numerator": {
+ "value": kbv_medication["amount"].get("numerator", {}).get("value", ""),
+ "unit": kbv_medication["amount"].get("numerator", {}).get("unit", ""),
+ "system": "http://unitsofmeasure.org",
+ "code": kbv_medication["amount"].get("numerator", {}).get("code", ""),
+ },
+ "denominator": {
+ "value": kbv_medication["amount"]
+ .get("denominator", {})
+ .get("value", ""),
+ "unit": kbv_medication["amount"].get("denominator", {}).get("unit", ""),
+ "system": "http://unitsofmeasure.org",
+ "code": kbv_medication["amount"].get("denominator", {}).get("code", ""),
},
- 'denominator': {
- 'value': kbv_medication['amount'].get('denominator', {}).get('value', ''),
- 'unit': kbv_medication['amount'].get('denominator', {}).get('unit', ''),
- 'system': 'http://unitsofmeasure.org',
- 'code': kbv_medication['amount'].get('denominator', {}).get('code', '')
- }
}
+
def main():
- kbv_file_path = 'data/Instances/KBV_PR_ERP_Medication.json'
- epa_file_path = 'data/Instances/example-epa-medication-2.json'
+ kbv_file_path = "data/Instances/KBV_PR_ERP_Medication.json"
+ epa_file_path = "data/Instances/example-epa-medication-2.json"
# Lade KBV- und ePA-Medikationsdaten
kbv_medication = load_json_file(kbv_file_path)
@@ -55,5 +63,6 @@ def main():
# Ergebnis ausgeben
print("Mapped ePA Medication:", json.dumps(epa_medication, indent=4))
+
if __name__ == "__main__":
main()
diff --git a/service/src/structure_comparer/__main__.py b/service/src/structure_comparer/__main__.py
index 0da0204..0147c1e 100644
--- a/service/src/structure_comparer/__main__.py
+++ b/service/src/structure_comparer/__main__.py
@@ -1,14 +1,39 @@
import argparse
+from pathlib import Path
from .serve import serve
+from .output import output
parser = argparse.ArgumentParser(description="Compare profiles and generate mapping")
-subparsers = parser.add_subparsers(dest="cmd")
+subparsers = parser.add_subparsers(dest="cmd", required=True)
parser_serve = subparsers.add_parser("serve", help="start the server")
-args = parser.parse_args()
+parser_output = subparsers.add_parser("output", help="generate output files")
+parser_output.add_argument(
+ "--project-dir",
+ type=Path,
+ required=True,
+ help="The project directory containing the profiles and config",
+)
+parser_output.add_argument(
+ "--format",
+ choices=["json", "html"],
+ default="html",
+ help="The output format (default: html)",
+)
+parser_output.add_argument(
+ "--mapping_id",
+ type=str,
+ default=None,
+ help="The ID of the mapping to generate output for (default: all mappings)",
+)
+args = parser.parse_args()
if args.cmd == "serve":
serve()
+elif args.cmd == "output":
+ output(args.project_dir, args.format, args.mapping_id)
+else:
+ parser.print_help()
diff --git a/service/src/structure_comparer/data/profile.py b/service/src/structure_comparer/data/profile.py
index b954c02..a4c578a 100644
--- a/service/src/structure_comparer/data/profile.py
+++ b/service/src/structure_comparer/data/profile.py
@@ -165,7 +165,7 @@ def ref_types(self) -> list[str]:
[
p
for t in self.__data.type
- if t.code == "Reference"
+ if t.code == "Reference" and t.targetProfile is not None
for p in t.targetProfile
]
if self.__data.type is not None
diff --git a/service/src/structure_comparer/files/template.html.j2 b/service/src/structure_comparer/files/template.html.j2
index bfcec08..6b65537 100644
--- a/service/src/structure_comparer/files/template.html.j2
+++ b/service/src/structure_comparer/files/template.html.j2
@@ -2,16 +2,18 @@
- Mapping: {% for profile in source_profiles %}{{ profile['key'] }}{% if not loop.last %}, {% endif %}{% endfor %} in {{ target_profile['key'] }}
-
+ Mapping: {% for profile in source_profiles %}{{ profile['key'] }}{% if not loop.last %}, {% endif %}{% endfor %} in {{ target_profile['key'] }}
+
-
Mapping: {% for profile in source_profiles %}{{ profile['key'] }}{% if not loop.last %}, {% endif %}{% endfor %} in {{ target_profile['key'] }}
+
Mapping: {% for profile in source_profiles %}{{ profile['name'] ~ "|" ~ profile['version'] }}{% if not loop.last %}, {% endif %}{% endfor %} in {{ target_profile['name'] ~ "|" ~ target_profile['version'] }}