Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c5bf5d3752 | |||
| 7d48b4c838 |
@@ -61,8 +61,8 @@ android {
|
|||||||
// im gesamten Projekt spürbar.
|
// im gesamten Projekt spürbar.
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 5
|
||||||
versionName = "1.0"
|
versionName = "1.5"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "APK",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "de.medapp.wunddoku",
|
||||||
|
"variantName": "release",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "SINGLE",
|
||||||
|
"filters": [],
|
||||||
|
"attributes": [],
|
||||||
|
"versionCode": 5,
|
||||||
|
"versionName": "1.5",
|
||||||
|
"outputFile": "app-release.apk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"elementType": "File",
|
||||||
|
"baselineProfiles": [
|
||||||
|
{
|
||||||
|
"minApi": 28,
|
||||||
|
"maxApi": 30,
|
||||||
|
"baselineProfiles": [
|
||||||
|
"baselineProfiles/1/app-release.dm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"minApi": 31,
|
||||||
|
"maxApi": 2147483647,
|
||||||
|
"baselineProfiles": [
|
||||||
|
"baselineProfiles/0/app-release.dm"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minSdkVersionForDexing": 26
|
||||||
|
}
|
||||||
@@ -28,11 +28,11 @@ import de.medapp.wunddoku.domain.model.InputSpec
|
|||||||
* Abschnitt 2.3b.
|
* Abschnitt 2.3b.
|
||||||
*
|
*
|
||||||
* [CATALOG_VERSION] wird beim Erstellen einer neuen Dokumentation als rein informatives
|
* [CATALOG_VERSION] wird beim Erstellen einer neuen Dokumentation als rein informatives
|
||||||
* Metadatum in Documentation.catalogVersion übernommen. Auf 5 erhöht (Decubitus als einfache Checkbox, Umbau "Empfohlene Wundversorgung").
|
* Metadatum in Documentation.catalogVersion übernommen. Auf 6 erhöht (Wundart/Wundgrund geteilt, Wundrandschutz neu geordnet, Granudacyn und Freitext entkoppelt).
|
||||||
*/
|
*/
|
||||||
object DocumentationCatalog {
|
object DocumentationCatalog {
|
||||||
|
|
||||||
const val CATALOG_VERSION: Int = 5
|
const val CATALOG_VERSION: Int = 6
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Label der automatisch an jeden Block angehängten Freitext-Option. Zentral hier definiert,
|
* Label der automatisch an jeden Block angehängten Freitext-Option. Zentral hier definiert,
|
||||||
@@ -65,30 +65,31 @@ object DocumentationCatalog {
|
|||||||
CheckItemDefinition(id = "wundart_ulcus_cruris_arteriosum", label = "Ulcus Cruris art.", order = 6),
|
CheckItemDefinition(id = "wundart_ulcus_cruris_arteriosum", label = "Ulcus Cruris art.", order = 6),
|
||||||
CheckItemDefinition(id = "wundart_ulcus_cruris_venosum_arteriosum", label = "Ulcus Cruris ven.-art.", order = 7),
|
CheckItemDefinition(id = "wundart_ulcus_cruris_venosum_arteriosum", label = "Ulcus Cruris ven.-art.", order = 7),
|
||||||
CheckItemDefinition(id = "wundart_diabetisches_fusssyndrom", label = "Diab. Fuß Syndrom", order = 8),
|
CheckItemDefinition(id = "wundart_diabetisches_fusssyndrom", label = "Diab. Fuß Syndrom", order = 8),
|
||||||
CheckItemDefinition(id = "wundart_post_operative_wundheilungsstoerung", label = "Post-operative Wundheilungsstörung / Dehiszenz", order = 9),
|
CheckItemDefinition(id = "wundart_post_operative_wundheilungsstoerung", label = "Post-operative Wundheilungsstörung", order = 9),
|
||||||
CheckItemDefinition(id = "wundart_schuerfwunde", label = "Schürfwunde", order = 10),
|
CheckItemDefinition(id = "wundart_dehiszenz", label = "Dehiszenz", order = 10),
|
||||||
CheckItemDefinition(id = "wundart_intertrigo", label = "Intertrigo / Wunde nach Intertrigo", order = 11),
|
CheckItemDefinition(id = "wundart_schuerfwunde", label = "Schürfwunde", order = 11),
|
||||||
CheckItemDefinition(id = "wundart_iad", label = "IAD (Inkontinenz-assoziierte Dermatitis) / Wunde nach IAD", order = 12),
|
CheckItemDefinition(id = "wundart_intertrigo", label = "Intertrigo / Wunde nach Intertrigo", order = 12),
|
||||||
CheckItemDefinition(id = "wundart_amputationswunde", label = "Amputationswunde", order = 13),
|
CheckItemDefinition(id = "wundart_iad", label = "IAD (Inkontinenz-assoziierte Dermatitis) / Wunde nach IAD", order = 13),
|
||||||
CheckItemDefinition(id = "wundart_spalthautentnahmestelle", label = "Spalthautentnahmestelle", order = 14),
|
CheckItemDefinition(id = "wundart_amputationswunde", label = "Amputationswunde", order = 14),
|
||||||
|
CheckItemDefinition(id = "wundart_spalthautentnahmestelle", label = "Spalthautentnahmestelle", order = 15),
|
||||||
CheckItemDefinition(
|
CheckItemDefinition(
|
||||||
id = "wundart_transplantatverlust",
|
id = "wundart_transplantatverlust",
|
||||||
label = "Wunde nach Transplantatverlust",
|
label = "Wunde nach Transplantatverlust",
|
||||||
order = 15,
|
order = 16,
|
||||||
inputSpec = InputSpec(
|
inputSpec = InputSpec(
|
||||||
pdfTemplate = "Wunde nach Transplantatverlust, Spalthautdeckung ca. {0}%",
|
pdfTemplate = "Wunde nach Transplantatverlust, Spalthautdeckung ca. {0}%",
|
||||||
fields = listOf(InputFieldDef.Number(label = "Spalthautdeckung ca. (%)", maxLength = 3)),
|
fields = listOf(InputFieldDef.Number(label = "Spalthautdeckung ca. (%)", maxLength = 3)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CheckItemDefinition(id = "wundart_sekundaer_heilende_wunde", label = "Sekundär heilende Wunde", order = 16),
|
CheckItemDefinition(id = "wundart_sekundaer_heilende_wunde", label = "Sekundär heilende Wunde", order = 17),
|
||||||
CheckItemDefinition(id = "wundart_tumorwunde", label = "Tumorwunde", order = 17),
|
CheckItemDefinition(id = "wundart_tumorwunde", label = "Tumorwunde", order = 18),
|
||||||
CheckItemDefinition(id = "wundart_wunde_nach_abszess", label = "Wunde nach Abszess", order = 18),
|
CheckItemDefinition(id = "wundart_wunde_nach_abszess", label = "Wunde nach Abszess", order = 19),
|
||||||
CheckItemDefinition(id = "wundart_verbrennung_verbruehung", label = "Verbrennung / Verbrühung", order = 19),
|
CheckItemDefinition(id = "wundart_verbrennung_verbruehung", label = "Verbrennung / Verbrühung", order = 20),
|
||||||
CheckItemDefinition(id = "wundart_platzwunde", label = "Platzwunde", order = 20),
|
CheckItemDefinition(id = "wundart_platzwunde", label = "Platzwunde", order = 21),
|
||||||
CheckItemDefinition(id = "wundart_schnittwunde", label = "Schnittwunde", order = 21),
|
CheckItemDefinition(id = "wundart_schnittwunde", label = "Schnittwunde", order = 22),
|
||||||
CheckItemDefinition(id = "wundart_bisswunde", label = "Bisswunde", order = 22),
|
CheckItemDefinition(id = "wundart_bisswunde", label = "Bisswunde", order = 23),
|
||||||
CheckItemDefinition(id = "wundart_chemisch_veraetzung", label = "Chemisch hervorgerufene Wunde / Verätzung", order = 23),
|
CheckItemDefinition(id = "wundart_chemisch_veraetzung", label = "Chemisch hervorgerufene Wunde / Verätzung", order = 24),
|
||||||
CheckItemDefinition(id = "wundart_strahlenschaden", label = "Strahlenschaden", order = 24),
|
CheckItemDefinition(id = "wundart_strahlenschaden", label = "Strahlenschaden", order = 25),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlockDefinition(
|
BlockDefinition(
|
||||||
@@ -165,24 +166,25 @@ object DocumentationCatalog {
|
|||||||
items = listOf(
|
items = listOf(
|
||||||
CheckItemDefinition(id = "wundgrund_wie_ausgestanzt", label = "Wie ausgestanzt", order = 1),
|
CheckItemDefinition(id = "wundgrund_wie_ausgestanzt", label = "Wie ausgestanzt", order = 1),
|
||||||
CheckItemDefinition(id = "wundgrund_kraterfoermig", label = "Kraterförmig", order = 2),
|
CheckItemDefinition(id = "wundgrund_kraterfoermig", label = "Kraterförmig", order = 2),
|
||||||
CheckItemDefinition(id = "wundgrund_unregelmaessig_landkartenartig", label = "Unregelmäßig (landkartenartig/amorph)", order = 3),
|
CheckItemDefinition(id = "wundgrund_unregelmaessig", label = "Unregelmäßig", order = 3),
|
||||||
CheckItemDefinition(id = "wundgrund_linear_spaltfoermig", label = "Linear/spaltförmig", order = 4),
|
CheckItemDefinition(id = "wundgrund_landkartenartig_amorph", label = "Landkartenartig/amorph", order = 4),
|
||||||
CheckItemDefinition(id = "wundgrund_rund", label = "Rund", order = 5),
|
CheckItemDefinition(id = "wundgrund_linear_spaltfoermig", label = "Linear/spaltförmig", order = 5),
|
||||||
CheckItemDefinition(id = "wundgrund_oval_elliptisch", label = "Oval/elliptisch", order = 6),
|
CheckItemDefinition(id = "wundgrund_rund", label = "Rund", order = 6),
|
||||||
CheckItemDefinition(id = "wundgrund_quadrangulaer", label = "Quadrangulär", order = 7),
|
CheckItemDefinition(id = "wundgrund_oval_elliptisch", label = "Oval/elliptisch", order = 7),
|
||||||
CheckItemDefinition(id = "wundgrund_eben", label = "Eben", order = 8),
|
CheckItemDefinition(id = "wundgrund_quadrangulaer", label = "Quadrangulär", order = 8),
|
||||||
CheckItemDefinition(id = "wundgrund_auf_niveau", label = "Auf Niveau", order = 9),
|
CheckItemDefinition(id = "wundgrund_eben", label = "Eben", order = 9),
|
||||||
CheckItemDefinition(id = "wundgrund_ueber_niveau", label = "Über Niveau", order = 10),
|
CheckItemDefinition(id = "wundgrund_auf_niveau", label = "Auf Niveau", order = 10),
|
||||||
CheckItemDefinition(id = "wundgrund_glaenzend", label = "Glänzend", order = 11),
|
CheckItemDefinition(id = "wundgrund_ueber_niveau", label = "Über Niveau", order = 11),
|
||||||
CheckItemDefinition(id = "wundgrund_grob", label = "Grob", order = 12),
|
CheckItemDefinition(id = "wundgrund_glaenzend", label = "Glänzend", order = 12),
|
||||||
CheckItemDefinition(id = "wundgrund_fein", label = "Fein", order = 13),
|
CheckItemDefinition(id = "wundgrund_grob", label = "Grob", order = 13),
|
||||||
CheckItemDefinition(id = "wundgrund_glatt", label = "Glatt", order = 14),
|
CheckItemDefinition(id = "wundgrund_fein", label = "Fein", order = 14),
|
||||||
CheckItemDefinition(id = "wundgrund_rot", label = "Rot", order = 15),
|
CheckItemDefinition(id = "wundgrund_glatt", label = "Glatt", order = 15),
|
||||||
CheckItemDefinition(id = "wundgrund_blass", label = "Blass", order = 16),
|
CheckItemDefinition(id = "wundgrund_rot", label = "Rot", order = 16),
|
||||||
CheckItemDefinition(id = "wundgrund_knochen_sehnen", label = "Knochen/Sehnen", order = 17),
|
CheckItemDefinition(id = "wundgrund_blass", label = "Blass", order = 17),
|
||||||
CheckItemDefinition(id = "wundgrund_haemorrhagie", label = "Hämorrhagie", order = 18),
|
CheckItemDefinition(id = "wundgrund_knochen_sehnen", label = "Knochen/Sehnen", order = 18),
|
||||||
CheckItemDefinition(id = "wundgrund_nicht_kaum_einsehbar", label = "Nicht/kaum einsehbar", order = 19),
|
CheckItemDefinition(id = "wundgrund_haemorrhagie", label = "Hämorrhagie", order = 19),
|
||||||
CheckItemDefinition(id = "wundgrund_erscheinung_erscheinung", label = "Erscheinung", order = 20, isFreeText = true),
|
CheckItemDefinition(id = "wundgrund_nicht_kaum_einsehbar", label = "Nicht/kaum einsehbar", order = 20),
|
||||||
|
CheckItemDefinition(id = "wundgrund_erscheinung_erscheinung", label = "Erscheinung", order = 21, isFreeText = true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlockDefinition(
|
BlockDefinition(
|
||||||
@@ -498,61 +500,61 @@ object DocumentationCatalog {
|
|||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_sterile_kompresse", label = "Sterile Kompresse", order = 2),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_sterile_kompresse", label = "Sterile Kompresse", order = 2),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_nacl", label = "NaCl 0,9%", order = 3),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_nacl", label = "NaCl 0,9%", order = 3),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_octenisept", label = "Octenisept", order = 4),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_octenisept", label = "Octenisept", order = 4),
|
||||||
// Granudacyn: Checkbox + direkt folgendes Freitextfeld, das nur bei angehakter
|
// Granudacyn: einfache Checkbox. Der Freitext ist ein eigener, separat
|
||||||
// Checkbox aktiv ist (= vorhandenes isFreeText-Verhalten, s. FreeTextCheckItemRow).
|
// anzuhakender Punkt direkt darunter (Bezeichnung "Freitext" wird in PDF/JPG
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_granudacyn", label = "Granudacyn", order = 5, isFreeText = true),
|
// und, sobald angehakt, auch in der App nicht angezeigt).
|
||||||
|
CheckItemDefinition(id = "empfohlene_wundversorgung_granudacyn", label = "Granudacyn", order = 5),
|
||||||
|
CheckItemDefinition(id = "empfohlene_wundversorgung_granudacyn_freitext", label = FREE_TEXT_LABEL, order = 6, isFreeText = true),
|
||||||
CheckItemDefinition(
|
CheckItemDefinition(
|
||||||
id = "empfohlene_wundversorgung_getraenkte_kompresse",
|
id = "empfohlene_wundversorgung_getraenkte_kompresse",
|
||||||
label = "Getränkte Kompresse",
|
label = "Getränkte Kompresse",
|
||||||
order = 6,
|
order = 7,
|
||||||
inputSpec = InputSpec(
|
inputSpec = InputSpec(
|
||||||
pdfTemplate = "Getränkte Kompresse für ca. {0} Min. auflegen",
|
pdfTemplate = "Getränkte Kompresse für ca. {0} Min. auflegen",
|
||||||
fields = listOf(InputFieldDef.Choice(label = "Minuten", options = MINUTE_1_TO_15_OPTIONS)),
|
fields = listOf(InputFieldDef.Choice(label = "Minuten", options = MINUTE_1_TO_15_OPTIONS)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_tupfend", label = "Tupfend", order = 7),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_tupfend", label = "Tupfend", order = 8),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_wischend", label = "Wischend", order = 8),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_wischend", label = "Wischend", order = 9),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_nachspuelen_nacl", label = "Nachspülen mit NaCl 0,9%", order = 9),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_nachspuelen_nacl", label = "Nachspülen mit NaCl 0,9%", order = 10),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_umgebung_trocken_tupfen", label = "Umgebung trocken tupfen", order = 10),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_umgebung_trocken_tupfen", label = "Umgebung trocken tupfen", order = 11),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_primaer_abdecken_austamponieren", label = "Primär Wunde abdecken/austamponieren", order = 11),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_primaer_abdecken_austamponieren", label = "Primär Wunde abdecken/austamponieren", order = 12),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_ueber_wundrand_hinaus", label = "Über Wundrand hinaus", order = 12),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_ueber_wundrand_hinaus", label = "Über Wundrand hinaus", order = 13),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_nicht_ueber_wundrand_mit", label = "Nicht über Wundrand mit", order = 13),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_nicht_ueber_wundrand_mit", label = "Nicht über Wundrand mit", order = 14),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_nicht_ueber_wundrand_mit_freitext", label = FREE_TEXT_LABEL, order = 14, isFreeText = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_nicht_ueber_wundrand_mit_freitext", label = FREE_TEXT_LABEL, order = 15, isFreeText = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_hinweis_wundrandschutz", label = "Wundrandschutz:", order = 15, isStaticHint = true),
|
// Wundrandschutz: EINE Checkbox mit eigenem Freitextfeld (kein Ja/Nein mehr).
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_wundrandschutz_ja", label = "Ja", order = 16),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_wundrandschutz", label = "Wundrandschutz", order = 16, isFreeText = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_wundrandschutz_nein", label = "Nein", order = 17),
|
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_wundrandschutz_freitext", label = FREE_TEXT_LABEL, order = 18, isFreeText = true),
|
|
||||||
// "Wie oft pro Woche": eigene Checkbox; die Auswahl (1-7x) ist erst nach dem
|
// "Wie oft pro Woche": eigene Checkbox; die Auswahl (1-7x) ist erst nach dem
|
||||||
// Anhaken aktiv (InputSpec.requiresOwnCheckbox).
|
// Anhaken aktiv (InputSpec.requiresOwnCheckbox).
|
||||||
CheckItemDefinition(
|
CheckItemDefinition(
|
||||||
id = "empfohlene_wundversorgung_wundrandschutz_tage_pro_woche",
|
id = "empfohlene_wundversorgung_wundrandschutz_tage_pro_woche",
|
||||||
label = "Wie oft pro Woche",
|
label = "Wie oft pro Woche",
|
||||||
order = 19,
|
order = 17,
|
||||||
inputSpec = InputSpec(
|
inputSpec = InputSpec(
|
||||||
pdfTemplate = "{0}x pro Woche",
|
pdfTemplate = "{0}x pro Woche",
|
||||||
fields = listOf(InputFieldDef.Choice(label = "Tage pro Woche", options = WEEKDAY_COUNT_OPTIONS)),
|
fields = listOf(InputFieldDef.Choice(label = "Tage pro Woche", options = WEEKDAY_COUNT_OPTIONS)),
|
||||||
requiresOwnCheckbox = true,
|
requiresOwnCheckbox = true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_hinweis_sekundaere_wundauflage", label = "Sekundäre Wundauflage:", order = 20, isStaticHint = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_hinweis_sekundaere_wundauflage", label = "Sekundäre Wundauflage:", order = 18, isStaticHint = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_sekundaer_sterile_kompresse", label = "Sterile Kompresse", order = 21),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_sekundaer_sterile_kompresse", label = "Sterile Kompresse", order = 19),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_saugkompresse", label = "Saugkompresse", order = 22),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_saugkompresse", label = "Saugkompresse", order = 20),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_sonstige_wundauflage", label = "Sonstiges (Wundauflage)", order = 23, isFreeText = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_sonstige_wundauflage", label = "Sonstiges (Wundauflage)", order = 21, isFreeText = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_hinweis_fixieren_mit", label = "Fixieren mit:", order = 24, isStaticHint = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_hinweis_fixieren_mit", label = "Fixieren mit:", order = 22, isStaticHint = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_mullbinde", label = "Mullbinde", order = 25),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_mullbinde", label = "Mullbinde", order = 23),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_klebevlies", label = "Klebevlies", order = 26),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_klebevlies", label = "Klebevlies", order = 24),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_folienverband", label = "Folienverband", order = 27),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_folienverband", label = "Folienverband", order = 25),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_schlauchverband", label = "Schlauchverband", order = 28),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_schlauchverband", label = "Schlauchverband", order = 26),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_kohaesive_fixierbinde", label = "Kohäsive Fixierbinde", order = 29),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_kohaesive_fixierbinde", label = "Kohäsive Fixierbinde", order = 27),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_kohaesive_fixierbinde_freitext", label = FREE_TEXT_LABEL, order = 30, isFreeText = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_kohaesive_fixierbinde_freitext", label = FREE_TEXT_LABEL, order = 28, isFreeText = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_kompressionsverband_system", label = "Kompressionsverband / System", order = 31),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_kompressionsverband_system", label = "Kompressionsverband / System", order = 29),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_kompressionsverband_system_freitext", label = FREE_TEXT_LABEL, order = 32, isFreeText = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_kompressionsverband_system_freitext", label = FREE_TEXT_LABEL, order = 30, isFreeText = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_wechselintervall", label = "Wechselintervall", order = 33, isFreeText = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_wechselintervall", label = "Wechselintervall", order = 31, isFreeText = true),
|
||||||
CheckItemDefinition(id = "empfohlene_wundversorgung_hinweis_bedarf", label = "+ bei Bedarf", order = 34, isStaticHint = true),
|
CheckItemDefinition(id = "empfohlene_wundversorgung_hinweis_bedarf", label = "+ bei Bedarf", order = 32, isStaticHint = true),
|
||||||
CheckItemDefinition(
|
CheckItemDefinition(
|
||||||
id = "empfohlene_wundversorgung_hinweis_abklaerung",
|
id = "empfohlene_wundversorgung_hinweis_abklaerung",
|
||||||
label = "Generell: bei akuter Verschlechterung sofort ärztliche Abklärung",
|
label = "Generell: bei akuter Verschlechterung sofort ärztliche Abklärung",
|
||||||
order = 35,
|
order = 33,
|
||||||
isStaticHint = true,
|
isStaticHint = true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -571,9 +573,8 @@ object DocumentationCatalog {
|
|||||||
CheckItemDefinition(id = "ziel_abheilung", label = "Abheilung", order = 7),
|
CheckItemDefinition(id = "ziel_abheilung", label = "Abheilung", order = 7),
|
||||||
CheckItemDefinition(id = "ziel_geruchsreduzierung", label = "Geruchsreduzierung", order = 8),
|
CheckItemDefinition(id = "ziel_geruchsreduzierung", label = "Geruchsreduzierung", order = 8),
|
||||||
CheckItemDefinition(id = "ziel_einfache_durchfuehrung", label = "Einfache Durchführung", order = 9),
|
CheckItemDefinition(id = "ziel_einfache_durchfuehrung", label = "Einfache Durchführung", order = 9),
|
||||||
CheckItemDefinition(id = "ziel_wundrandschutz", label = "Wundrandschutz", order = 10),
|
CheckItemDefinition(id = "ziel_aufbruch_vorhandenes_material", label = "Aufbruch des vorhandenen Materials", order = 10),
|
||||||
CheckItemDefinition(id = "ziel_aufbruch_vorhandenes_material", label = "Aufbruch des vorhandenen Materials", order = 11),
|
CheckItemDefinition(id = "ziel_selbstversorgung_foerdern", label = "Selbstversorgung der Wunde durch Patient/Angehörige unterstützen/fördern", order = 11),
|
||||||
CheckItemDefinition(id = "ziel_selbstversorgung_foerdern", label = "Selbstversorgung der Wunde durch Patient/Angehörige unterstützen/fördern", order = 12),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlockDefinition(
|
BlockDefinition(
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ package de.medapp.wunddoku.pdf
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.pdf.PdfDocument
|
import android.graphics.pdf.PdfDocument
|
||||||
|
import android.text.Layout
|
||||||
|
import android.text.StaticLayout
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
import de.medapp.wunddoku.domain.error.FailureCategory
|
import de.medapp.wunddoku.domain.error.FailureCategory
|
||||||
import de.medapp.wunddoku.domain.model.InputSpecCodec
|
import de.medapp.wunddoku.domain.model.InputSpecCodec
|
||||||
@@ -66,6 +69,8 @@ class AndroidPdfDocumentExporter(
|
|||||||
private const val ITEM_TEXT_SIZE = 11f
|
private const val ITEM_TEXT_SIZE = 11f
|
||||||
private const val FREE_TEXT_TEXT_SIZE = 10.5f
|
private const val FREE_TEXT_TEXT_SIZE = 10.5f
|
||||||
private const val FREE_TEXT_INDENT = 20f
|
private const val FREE_TEXT_INDENT = 20f
|
||||||
|
private const val RUNNING_HEADER_TEXT_SIZE = 9.5f
|
||||||
|
private const val RUNNING_HEADER_SPACING_AFTER = 10f
|
||||||
|
|
||||||
// PDF-003: Signaturbereich. Fachlich handschriftliche Unterschriften, keine
|
// PDF-003: Signaturbereich. Fachlich handschriftliche Unterschriften, keine
|
||||||
// kryptographische PDF-Signatur (s. Aufgabenstellung Abschnitt 5).
|
// kryptographische PDF-Signatur (s. Aufgabenstellung Abschnitt 5).
|
||||||
@@ -160,6 +165,9 @@ class AndroidPdfDocumentExporter(
|
|||||||
marginRight = MARGIN,
|
marginRight = MARGIN,
|
||||||
marginTop = MARGIN,
|
marginTop = MARGIN,
|
||||||
marginBottom = MARGIN,
|
marginBottom = MARGIN,
|
||||||
|
pageHeaderDrawer = PageHeaderDrawer { canvas, pageNumber, left, top, width ->
|
||||||
|
drawRunningHeader(canvas, pageNumber, left, top, width, model, paints)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
drawHeader(cursor, model, paints)
|
drawHeader(cursor, model, paints)
|
||||||
@@ -243,6 +251,32 @@ class AndroidPdfDocumentExporter(
|
|||||||
textSize = FREE_TEXT_TEXT_SIZE
|
textSize = FREE_TEXT_TEXT_SIZE
|
||||||
color = Color.DKGRAY
|
color = Color.DKGRAY
|
||||||
}
|
}
|
||||||
|
// Zwischenüberschriften innerhalb eines Blocks: kursiv + unterstrichen.
|
||||||
|
val itemSubheading = TextPaint().apply {
|
||||||
|
isAntiAlias = true
|
||||||
|
textSize = ITEM_TEXT_SIZE
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT, Typeface.ITALIC)
|
||||||
|
isUnderlineText = true
|
||||||
|
color = Color.BLACK
|
||||||
|
}
|
||||||
|
// Wichtiger Hinweis: fett + unterstrichen.
|
||||||
|
val itemWarning = TextPaint().apply {
|
||||||
|
isAntiAlias = true
|
||||||
|
textSize = ITEM_TEXT_SIZE
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
|
||||||
|
isUnderlineText = true
|
||||||
|
color = Color.BLACK
|
||||||
|
}
|
||||||
|
// Seitenkopf ab Seite 2 (Patient + Erstelldatum).
|
||||||
|
val runningHeader = TextPaint().apply {
|
||||||
|
isAntiAlias = true
|
||||||
|
textSize = RUNNING_HEADER_TEXT_SIZE
|
||||||
|
color = Color.DKGRAY
|
||||||
|
}
|
||||||
|
val runningHeaderLine = Paint().apply {
|
||||||
|
color = Color.LTGRAY
|
||||||
|
strokeWidth = 1f
|
||||||
|
}
|
||||||
|
|
||||||
// PDF-003: Signaturbereich.
|
// PDF-003: Signaturbereich.
|
||||||
val signatureLabel = TextPaint().apply {
|
val signatureLabel = TextPaint().apply {
|
||||||
@@ -286,6 +320,37 @@ class AndroidPdfDocumentExporter(
|
|||||||
cursor.drawDivider(spacingAfter = 12f)
|
cursor.drawDivider(spacingAfter = 12f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seitenkopf für alle Seiten AB Seite 2 (Änderungswunsch: auf jeder Seite müssen Name des
|
||||||
|
* Patienten und Erstellungsdatum stehen): Seite 1 trägt bereits den großen Dokumentkopf
|
||||||
|
* ([drawHeader]). Gilt auch für Unterschriften- und Fotoseiten. Verwendet ausschließlich
|
||||||
|
* Snapshot-Daten aus dem [PdfExportModel]. Liefert die belegte Höhe zurück.
|
||||||
|
*/
|
||||||
|
private fun drawRunningHeader(
|
||||||
|
canvas: Canvas,
|
||||||
|
pageNumber: Int,
|
||||||
|
left: Float,
|
||||||
|
top: Float,
|
||||||
|
width: Float,
|
||||||
|
model: PdfExportModel,
|
||||||
|
paints: ExportPaints,
|
||||||
|
): Float {
|
||||||
|
if (pageNumber <= 1) return 0f
|
||||||
|
val text = "Patient: ${model.patientFullName}, geb. ${model.patientBirthDate.format(HEADER_DATE_FORMATTER)}" +
|
||||||
|
" · ${model.patientDisplayAddress} · Erstellt am: ${model.createdAt.format(HEADER_DATE_FORMATTER)}"
|
||||||
|
val layout = StaticLayout.Builder.obtain(text, 0, text.length, paints.runningHeader, width.toInt().coerceAtLeast(1))
|
||||||
|
.setAlignment(Layout.Alignment.ALIGN_NORMAL)
|
||||||
|
.setIncludePad(false)
|
||||||
|
.build()
|
||||||
|
canvas.save()
|
||||||
|
canvas.translate(left, top)
|
||||||
|
layout.draw(canvas)
|
||||||
|
canvas.restore()
|
||||||
|
val lineY = top + layout.height + 4f
|
||||||
|
canvas.drawLine(left, lineY, left + width, lineY, paints.runningHeaderLine)
|
||||||
|
return layout.height + 4f + 1f + RUNNING_HEADER_SPACING_AFTER
|
||||||
|
}
|
||||||
|
|
||||||
/** Überschriften erscheinen im PDF immer mit abschließendem Doppelpunkt (kein doppelter
|
/** Überschriften erscheinen im PDF immer mit abschließendem Doppelpunkt (kein doppelter
|
||||||
* Doppelpunkt, falls der Titel bereits mit einem endet). */
|
* Doppelpunkt, falls der Titel bereits mit einem endet). */
|
||||||
private fun headingText(title: String): String {
|
private fun headingText(title: String): String {
|
||||||
@@ -294,6 +359,8 @@ class AndroidPdfDocumentExporter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun drawBlock(cursor: PdfPageCursor, block: PdfExportBlock, paints: ExportPaints) {
|
private fun drawBlock(cursor: PdfPageCursor, block: PdfExportBlock, paints: ExportPaints) {
|
||||||
|
// Änderungswunsch: "Empfohlene Wundversorgung" beginnt immer auf einer eigenen Seite.
|
||||||
|
if (block.startsOnNewPage) cursor.startNewPageUnlessEmpty()
|
||||||
cursor.drawText(headingText(block.title), paints.blockTitle, spacingAfter = 6f)
|
cursor.drawText(headingText(block.title), paints.blockTitle, spacingAfter = 6f)
|
||||||
|
|
||||||
for (item in block.items) {
|
for (item in block.items) {
|
||||||
@@ -330,14 +397,37 @@ class AndroidPdfDocumentExporter(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generische "Freitext"-Einträge (Änderungswunsch): Bezeichnung wird NICHT gedruckt, nur
|
||||||
|
// der eingegebene Text (eingerückt unter dem vorhergehenden Eintrag). Ein angehakter,
|
||||||
|
// aber leerer Freitext erzeugt keine Ausgabe.
|
||||||
|
if (!item.showLabel) {
|
||||||
|
if (item.freeTextValue.isNotBlank()) {
|
||||||
|
cursor.drawText(
|
||||||
|
text = item.freeTextValue,
|
||||||
|
paint = paints.item,
|
||||||
|
indent = FREE_TEXT_INDENT,
|
||||||
|
spacingAfter = 6f,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Die Freitext-Option bekommt einen abschließenden Doppelpunkt, sofern tatsächlich Text
|
// Die Freitext-Option bekommt einen abschließenden Doppelpunkt, sofern tatsächlich Text
|
||||||
// folgt (z. B. "Granudacyn" ohne Text bleibt ohne hängenden Doppelpunkt), normale
|
// folgt (z. B. "Granudacyn" ohne Text bleibt ohne hängenden Doppelpunkt), normale
|
||||||
// Optionen nie.
|
// Optionen nie.
|
||||||
val labelText = if (item.isFreeText && item.freeTextValue.isNotBlank()) "${item.label}:" else item.label
|
val baseLabel = if (item.isFreeText && item.freeTextValue.isNotBlank()) "${item.label}:" else item.label
|
||||||
|
|
||||||
|
// Änderungswunsch: Zwischenüberschriften kursiv + unterstrichen, wichtiger Hinweis fett +
|
||||||
|
// unterstrichen mit Ausrufezeichen davor und dahinter.
|
||||||
|
val (labelText, labelPaint) = when (item.style) {
|
||||||
|
PdfItemStyle.SUBHEADING -> baseLabel to paints.itemSubheading
|
||||||
|
PdfItemStyle.WARNING -> "! $baseLabel !" to paints.itemWarning
|
||||||
|
PdfItemStyle.NORMAL -> baseLabel to paints.item
|
||||||
|
}
|
||||||
|
|
||||||
cursor.drawText(
|
cursor.drawText(
|
||||||
text = labelText,
|
text = labelText,
|
||||||
paint = paints.item,
|
paint = labelPaint,
|
||||||
indent = ITEM_INDENT,
|
indent = ITEM_INDENT,
|
||||||
spacingAfter = 3f,
|
spacingAfter = 3f,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package de.medapp.wunddoku.pdf
|
package de.medapp.wunddoku.pdf
|
||||||
|
|
||||||
|
import de.medapp.wunddoku.domain.catalog.DocumentationCatalog
|
||||||
|
import de.medapp.wunddoku.domain.model.CheckItem
|
||||||
import de.medapp.wunddoku.domain.model.Documentation
|
import de.medapp.wunddoku.domain.model.Documentation
|
||||||
|
import de.medapp.wunddoku.domain.model.DocumentationBlock
|
||||||
import de.medapp.wunddoku.domain.usecase.BlockEditedPolicy
|
import de.medapp.wunddoku.domain.usecase.BlockEditedPolicy
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
|
|
||||||
@@ -27,20 +30,22 @@ object DocumentationToPdfExportModelMapper {
|
|||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
.map { block ->
|
.map { block ->
|
||||||
PdfExportBlock(
|
PdfExportBlock(
|
||||||
|
definitionId = block.definitionId,
|
||||||
title = block.title,
|
title = block.title,
|
||||||
// Änderungswunsch: nur angehakte Optionen erscheinen im PDF - nicht
|
startsOnNewPage = block.definitionId in BLOCKS_ON_OWN_PAGE,
|
||||||
// angehakte Checkboxen werden komplett weggelassen (nicht nur unausgefüllt
|
// Nur angehakte Optionen erscheinen im PDF. Hinweistexte (isStaticHint) sind
|
||||||
// dargestellt). Ein leeres Ergebnis ist hier ausgeschlossen: BlockEditedPolicy
|
// technisch immer angehakt und werden gruppenabhängig gefiltert, s.
|
||||||
|
// [exportedItems]. Ein leeres Ergebnis ist ausgeschlossen: BlockEditedPolicy
|
||||||
// (Filter oben) lässt nur Blöcke mit mindestens einer angehakten Option durch.
|
// (Filter oben) lässt nur Blöcke mit mindestens einer angehakten Option durch.
|
||||||
items = block.items
|
items = exportedItems(block).map { item ->
|
||||||
.filter { it.checked }
|
|
||||||
.sortedBy { it.order }
|
|
||||||
.map { item ->
|
|
||||||
PdfExportItem(
|
PdfExportItem(
|
||||||
label = item.label,
|
label = item.label,
|
||||||
isFreeText = item.isFreeText,
|
isFreeText = item.isFreeText,
|
||||||
freeTextValue = item.freeTextValue,
|
freeTextValue = item.freeTextValue,
|
||||||
inputSpec = item.inputSpec,
|
inputSpec = item.inputSpec,
|
||||||
|
// Generische "Freitext"-Bezeichnung nie drucken, nur den Text.
|
||||||
|
showLabel = !(item.isFreeText && item.label == DocumentationCatalog.FREE_TEXT_LABEL),
|
||||||
|
style = styleFor(item),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -80,4 +85,67 @@ object DocumentationToPdfExportModelMapper {
|
|||||||
photos = photos,
|
photos = photos,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Blöcke, die im PDF/JPG immer auf einer neuen Seite beginnen. */
|
||||||
|
private val BLOCKS_ON_OWN_PAGE: Set<String> = setOf("empfohlene_wundversorgung")
|
||||||
|
|
||||||
|
/** Zwischenüberschriften (kursiv + unterstrichen), anhand der stabilen Definitions-IDs. */
|
||||||
|
private val SUBHEADING_DEFINITION_IDS: Set<String> = setOf(
|
||||||
|
"empfohlene_wundversorgung_hinweis_reinigen_mit",
|
||||||
|
"empfohlene_wundversorgung_primaer_abdecken_austamponieren",
|
||||||
|
"empfohlene_wundversorgung_wundrandschutz",
|
||||||
|
"empfohlene_wundversorgung_hinweis_sekundaere_wundauflage",
|
||||||
|
"empfohlene_wundversorgung_hinweis_fixieren_mit",
|
||||||
|
"empfohlene_wundversorgung_wechselintervall",
|
||||||
|
)
|
||||||
|
|
||||||
|
/** Wichtige Hinweise (fett + unterstrichen, mit Ausrufezeichen). */
|
||||||
|
private val WARNING_DEFINITION_IDS: Set<String> = setOf(
|
||||||
|
"empfohlene_wundversorgung_hinweis_abklaerung",
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun styleFor(item: CheckItem): PdfItemStyle = when (item.definitionId) {
|
||||||
|
in WARNING_DEFINITION_IDS -> PdfItemStyle.WARNING
|
||||||
|
in SUBHEADING_DEFINITION_IDS -> PdfItemStyle.SUBHEADING
|
||||||
|
else -> PdfItemStyle.NORMAL
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bestimmt die zu exportierenden Einträge eines Blocks (sortiert nach order):
|
||||||
|
* - normale Einträge: nur wenn angehakt
|
||||||
|
* - Hinweistexte (isStaticHint, technisch immer angehakt): Ein Hinweis, dem im Block
|
||||||
|
* eigene Einträge folgen (bis zum nächsten Hinweis), ist eine Gruppenüberschrift und
|
||||||
|
* wird nur gedruckt, wenn mindestens einer dieser Einträge angehakt ist (z. B. "Zu
|
||||||
|
* versorgendes Areal" bei Größe). Hinweise ohne folgende Einträge ("+ bei Bedarf",
|
||||||
|
* "Generell: ...") bleiben immer erhalten. Der automatisch angehängte generische
|
||||||
|
* Freitext eines Blocks gehört zu keiner Gruppe. Trägt der erste angehakte Eintrag der
|
||||||
|
* Gruppe dieselbe Bezeichnung wie der Hinweis, entfällt der Hinweis (keine Doppelung).
|
||||||
|
*
|
||||||
|
* Ausschließlich Snapshot-Daten, kein Zugriff auf den aktuellen Katalog.
|
||||||
|
*/
|
||||||
|
private fun exportedItems(block: DocumentationBlock): List<CheckItem> {
|
||||||
|
val sorted = block.items.sortedBy { it.order }
|
||||||
|
val genericFreeTextId = "${block.definitionId}_freetext"
|
||||||
|
val result = mutableListOf<CheckItem>()
|
||||||
|
for ((index, item) in sorted.withIndex()) {
|
||||||
|
if (!item.checked) continue
|
||||||
|
if (!item.isStaticHint) {
|
||||||
|
result.add(item)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val groupItems = sorted
|
||||||
|
.drop(index + 1)
|
||||||
|
.takeWhile { !it.isStaticHint }
|
||||||
|
.filter { it.definitionId != genericFreeTextId }
|
||||||
|
val keep = when {
|
||||||
|
groupItems.isEmpty() -> true
|
||||||
|
else -> {
|
||||||
|
val firstChecked = groupItems.firstOrNull { it.checked }
|
||||||
|
firstChecked != null && !firstChecked.label.trim().equals(item.label.trim(), ignoreCase = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keep) result.add(item)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,12 @@ data class PdfExportModel(
|
|||||||
)
|
)
|
||||||
|
|
||||||
data class PdfExportBlock(
|
data class PdfExportBlock(
|
||||||
|
/** Stabile Definitions-ID des Blocks (z. B. "empfohlene_wundversorgung"). */
|
||||||
|
val definitionId: String = "",
|
||||||
val title: String,
|
val title: String,
|
||||||
|
/** `true`: der Block beginnt im PDF/JPG zwingend auf einer neuen Seite (Änderungswunsch:
|
||||||
|
* "Empfohlene Wundversorgung" auf eigener Seite). */
|
||||||
|
val startsOnNewPage: Boolean = false,
|
||||||
/** Bereits gefiltert (NUR angehakte Optionen, s. Mapper - Änderungswunsch) und sortiert
|
/** Bereits gefiltert (NUR angehakte Optionen, s. Mapper - Änderungswunsch) und sortiert
|
||||||
* (itemOrder). Nicht angehakte Optionen erscheinen im PDF überhaupt nicht mehr. */
|
* (itemOrder). Nicht angehakte Optionen erscheinen im PDF überhaupt nicht mehr. */
|
||||||
val items: List<PdfExportItem>,
|
val items: List<PdfExportItem>,
|
||||||
@@ -45,8 +50,23 @@ data class PdfExportItem(
|
|||||||
val isFreeText: Boolean,
|
val isFreeText: Boolean,
|
||||||
val freeTextValue: String,
|
val freeTextValue: String,
|
||||||
val inputSpec: String = "",
|
val inputSpec: String = "",
|
||||||
|
/** `false`: die Bezeichnung wird nicht gedruckt, nur der eingegebene Text (generische
|
||||||
|
* "Freitext"-Einträge, Änderungswunsch: Schriftzug "Freitext" im PDF/JPG nicht anzeigen). */
|
||||||
|
val showLabel: Boolean = true,
|
||||||
|
val style: PdfItemStyle = PdfItemStyle.NORMAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** Darstellung der Bezeichnung eines Eintrags im PDF (rein layoutbezogen). */
|
||||||
|
enum class PdfItemStyle {
|
||||||
|
NORMAL,
|
||||||
|
|
||||||
|
/** Zwischenüberschrift innerhalb eines Blocks: kursiv und unterstrichen. */
|
||||||
|
SUBHEADING,
|
||||||
|
|
||||||
|
/** Wichtiger Hinweis: fett, unterstrichen, mit Ausrufezeichen davor und dahinter. */
|
||||||
|
WARNING,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimale, für den Fotoanhang benötigte Referenz. Enthält bewusst nur [fileName] -
|
* Minimale, für den Fotoanhang benötigte Referenz. Enthält bewusst nur [fileName] -
|
||||||
* `documentationId` steht bereits am [PdfExportModel] selbst zur Verfügung (nötig, um über
|
* `documentationId` steht bereits am [PdfExportModel] selbst zur Verfügung (nötig, um über
|
||||||
|
|||||||
@@ -10,6 +10,15 @@ import android.text.Layout
|
|||||||
import android.text.StaticLayout
|
import android.text.StaticLayout
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zeichnet den Seitenkopf einer (neuen) Seite und liefert die dafür belegte Höhe zurück
|
||||||
|
* (0f, wenn auf dieser Seite kein Seitenkopf gezeichnet wird, z. B. Seite 1 mit dem großen
|
||||||
|
* Dokumentkopf). [left]/[top] sind die obere linke Ecke des Inhaltsbereichs, [width] dessen Breite.
|
||||||
|
*/
|
||||||
|
internal fun interface PageHeaderDrawer {
|
||||||
|
fun draw(canvas: Canvas, pageNumber: Int, left: Float, top: Float, width: Float): Float
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verwaltet Seiten, Zeichenfläche und die aktuelle vertikale Schreibposition ("Cursor") beim
|
* Verwaltet Seiten, Zeichenfläche und die aktuelle vertikale Schreibposition ("Cursor") beim
|
||||||
* Erzeugen eines [PdfDocument]. Kapselt die komplette Seitenumbruch-Logik an einer Stelle, damit
|
* Erzeugen eines [PdfDocument]. Kapselt die komplette Seitenumbruch-Logik an einer Stelle, damit
|
||||||
@@ -33,8 +42,13 @@ internal class PdfPageCursor(
|
|||||||
private val marginRight: Float,
|
private val marginRight: Float,
|
||||||
private val marginTop: Float,
|
private val marginTop: Float,
|
||||||
private val marginBottom: Float,
|
private val marginBottom: Float,
|
||||||
|
/** Optionaler Seitenkopf, der auf JEDER neu begonnenen Seite gezeichnet wird (Änderungswunsch:
|
||||||
|
* Patientenname und Erstellungsdatum auf jeder Seite). */
|
||||||
|
private val pageHeaderDrawer: PageHeaderDrawer? = null,
|
||||||
) {
|
) {
|
||||||
private var pageNumber = 0
|
private var pageNumber = 0
|
||||||
|
/** Y-Position, ab der auf der aktuellen Seite Inhalt beginnt (nach einem evtl. Seitenkopf). */
|
||||||
|
private var pageContentTop: Float = marginTop
|
||||||
private var currentPage: PdfDocument.Page? = null
|
private var currentPage: PdfDocument.Page? = null
|
||||||
private var canvas: Canvas? = null
|
private var canvas: Canvas? = null
|
||||||
private var cursorY: Float = marginTop
|
private var cursorY: Float = marginTop
|
||||||
@@ -74,7 +88,15 @@ internal class PdfPageCursor(
|
|||||||
val page = pdfDocument.startPage(info)
|
val page = pdfDocument.startPage(info)
|
||||||
currentPage = page
|
currentPage = page
|
||||||
canvas = page.canvas
|
canvas = page.canvas
|
||||||
cursorY = marginTop
|
val headerHeight = pageHeaderDrawer?.draw(
|
||||||
|
canvas = page.canvas,
|
||||||
|
pageNumber = pageNumber,
|
||||||
|
left = marginLeft,
|
||||||
|
top = marginTop,
|
||||||
|
width = pageWidth - marginLeft - marginRight,
|
||||||
|
) ?: 0f
|
||||||
|
pageContentTop = marginTop + headerHeight
|
||||||
|
cursorY = pageContentTop
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun finishCurrentPageIfOpen() {
|
private fun finishCurrentPageIfOpen() {
|
||||||
@@ -98,6 +120,15 @@ internal class PdfPageCursor(
|
|||||||
startNewPage()
|
startNewPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Beginnt eine neue Seite, außer die aktuelle Seite ist noch völlig leer (Cursor steht am
|
||||||
|
* Inhaltsanfang) - so entstehen keine Leerseiten, wenn ein Block, der immer auf einer
|
||||||
|
* eigenen Seite beginnt, ohnehin ganz oben stünde.
|
||||||
|
*/
|
||||||
|
fun startNewPageUnlessEmpty() {
|
||||||
|
if (currentPage == null || cursorY > pageContentTop) startNewPage()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeichnet [bitmap] proportional eingepasst (kein Zuschneiden, keine Verzerrung) horizontal
|
* Zeichnet [bitmap] proportional eingepasst (kein Zuschneiden, keine Verzerrung) horizontal
|
||||||
* über die volle Inhaltsbreite und vertikal zentriert im aktuell verbleibenden Platz der
|
* über die volle Inhaltsbreite und vertikal zentriert im aktuell verbleibenden Platz der
|
||||||
|
|||||||
+9
-2
@@ -85,6 +85,7 @@ import androidx.lifecycle.compose.LocalLifecycleOwner
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import de.medapp.wunddoku.R
|
import de.medapp.wunddoku.R
|
||||||
|
import de.medapp.wunddoku.domain.catalog.DocumentationCatalog
|
||||||
import de.medapp.wunddoku.domain.model.CheckItem
|
import de.medapp.wunddoku.domain.model.CheckItem
|
||||||
import de.medapp.wunddoku.domain.model.InputFieldDef
|
import de.medapp.wunddoku.domain.model.InputFieldDef
|
||||||
import de.medapp.wunddoku.domain.model.InputSpecCodec
|
import de.medapp.wunddoku.domain.model.InputSpecCodec
|
||||||
@@ -907,19 +908,25 @@ private fun FreeTextCheckItemRow(
|
|||||||
onCheckedChanged: (checkItemStateId: String, checked: Boolean) -> Unit,
|
onCheckedChanged: (checkItemStateId: String, checked: Boolean) -> Unit,
|
||||||
onFreeTextChanged: (checkItemStateId: String, text: String) -> Unit,
|
onFreeTextChanged: (checkItemStateId: String, text: String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
// Änderungswunsch: Ist ein generischer "Freitext"-Eintrag angehakt, wird der Schriftzug
|
||||||
|
// "Freitext" nicht mehr angezeigt (nur Häkchenkästchen + Eingabefeld). Fachlich benannte
|
||||||
|
// Freitext-Einträge (z. B. "Wundrandschutz", "Wechselintervall") behalten ihre Bezeichnung.
|
||||||
|
val hideName = item.checked && item.label == DocumentationCatalog.FREE_TEXT_LABEL
|
||||||
|
val fieldLabel: (@Composable () -> Unit)? =
|
||||||
|
if (hideName) null else ({ Text(stringResource(R.string.documentation_edit_free_text_label)) })
|
||||||
Column {
|
Column {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Checkbox(
|
Checkbox(
|
||||||
checked = item.checked,
|
checked = item.checked,
|
||||||
onCheckedChange = { checked -> onCheckedChanged(item.checkItemStateId, checked) },
|
onCheckedChange = { checked -> onCheckedChanged(item.checkItemStateId, checked) },
|
||||||
)
|
)
|
||||||
Text(item.label)
|
if (!hideName) Text(item.label)
|
||||||
}
|
}
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = item.freeTextValue,
|
value = item.freeTextValue,
|
||||||
onValueChange = { text -> onFreeTextChanged(item.checkItemStateId, text) },
|
onValueChange = { text -> onFreeTextChanged(item.checkItemStateId, text) },
|
||||||
enabled = item.checked,
|
enabled = item.checked,
|
||||||
label = { Text(stringResource(R.string.documentation_edit_free_text_label)) },
|
label = fieldLabel,
|
||||||
modifier = Modifier.fillMaxWidth().padding(start = 40.dp),
|
modifier = Modifier.fillMaxWidth().padding(start = 40.dp),
|
||||||
minLines = 2,
|
minLines = 2,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package de.medapp.wunddoku.domain.catalog
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertNotNull
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strukturprüfungen für den statischen Katalog sowie die fachlichen Änderungswünsche
|
||||||
|
* (Wundart/Wundgrund geteilt, Wundrandschutz, Granudacyn).
|
||||||
|
*/
|
||||||
|
class DocumentationCatalogTest {
|
||||||
|
|
||||||
|
private fun items(blockId: String) = DocumentationCatalog.findBlock(blockId)!!.items
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun alle_checkitem_ids_sind_katalogweit_eindeutig() {
|
||||||
|
val ids = DocumentationCatalog.blocks.flatMap { b -> b.items.map { it.id } }
|
||||||
|
assertEquals(ids.size, ids.toSet().size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun order_ist_je_block_eindeutig_und_aufsteigend() {
|
||||||
|
for (block in DocumentationCatalog.blocks) {
|
||||||
|
val orders = block.items.map { it.order }
|
||||||
|
assertEquals("Block ${block.id}", orders.sorted(), orders)
|
||||||
|
assertEquals("Block ${block.id}", orders.size, orders.toSet().size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wundart_postoperativ_und_dehiszenz_sind_getrennte_punkte() {
|
||||||
|
val wundart = items("wundart")
|
||||||
|
assertEquals("Post-operative Wundheilungsstörung", wundart.single { it.id == "wundart_post_operative_wundheilungsstoerung" }.label)
|
||||||
|
assertEquals("Dehiszenz", wundart.single { it.id == "wundart_dehiszenz" }.label)
|
||||||
|
assertTrue(wundart.none { it.label.contains("/ Dehiszenz") })
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wundgrund_unregelmaessig_und_landkartenartig_sind_getrennte_punkte() {
|
||||||
|
val wundgrund = items("wundgrund_erscheinung")
|
||||||
|
assertEquals("Unregelmäßig", wundgrund.single { it.id == "wundgrund_unregelmaessig" }.label)
|
||||||
|
assertEquals("Landkartenartig/amorph", wundgrund.single { it.id == "wundgrund_landkartenartig_amorph" }.label)
|
||||||
|
assertNull(wundgrund.firstOrNull { it.id == "wundgrund_unregelmaessig_landkartenartig" })
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wundrandschutz_ist_aus_ziel_entfernt() {
|
||||||
|
assertTrue(items("ziel").none { it.label.contains("Wundrandschutz") })
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wundrandschutz_ist_eine_einzelne_freitext_box_ohne_ja_nein() {
|
||||||
|
val ev = items("empfohlene_wundversorgung")
|
||||||
|
val wrs = ev.single { it.id == "empfohlene_wundversorgung_wundrandschutz" }
|
||||||
|
assertEquals("Wundrandschutz", wrs.label)
|
||||||
|
assertTrue(wrs.isFreeText)
|
||||||
|
assertNull(ev.firstOrNull { it.id == "empfohlene_wundversorgung_hinweis_wundrandschutz" })
|
||||||
|
assertNull(ev.firstOrNull { it.id == "empfohlene_wundversorgung_wundrandschutz_ja" })
|
||||||
|
assertNull(ev.firstOrNull { it.id == "empfohlene_wundversorgung_wundrandschutz_nein" })
|
||||||
|
// "Wie oft pro Woche" bleibt als eigene Checkbox erhalten.
|
||||||
|
assertNotNull(ev.firstOrNull { it.id == "empfohlene_wundversorgung_wundrandschutz_tage_pro_woche" })
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun granudacyn_ist_einfache_checkbox_und_freitext_ein_eigener_punkt_direkt_darunter() {
|
||||||
|
val ev = items("empfohlene_wundversorgung")
|
||||||
|
val granudacyn = ev.single { it.id == "empfohlene_wundversorgung_granudacyn" }
|
||||||
|
val freitext = ev.single { it.id == "empfohlene_wundversorgung_granudacyn_freitext" }
|
||||||
|
|
||||||
|
assertFalse(granudacyn.isFreeText)
|
||||||
|
assertTrue(freitext.isFreeText)
|
||||||
|
assertEquals(DocumentationCatalog.FREE_TEXT_LABEL, freitext.label)
|
||||||
|
assertEquals(granudacyn.order + 1, freitext.order)
|
||||||
|
}
|
||||||
|
}
|
||||||
+147
-1
@@ -172,10 +172,156 @@ class DocumentationToPdfExportModelMapperTest {
|
|||||||
|
|
||||||
val items = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items
|
val items = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items
|
||||||
|
|
||||||
assertEquals(PdfExportItem("Freitext", isFreeText = true, freeTextValue = "Rötung", inputSpec = ""), items[0])
|
// Generischer "Freitext": Bezeichnung wird nicht gedruckt (showLabel = false).
|
||||||
|
assertEquals(
|
||||||
|
PdfExportItem("Freitext", isFreeText = true, freeTextValue = "Rötung", inputSpec = "", showLabel = false),
|
||||||
|
items[0],
|
||||||
|
)
|
||||||
assertEquals(PdfExportItem("Maße", isFreeText = false, freeTextValue = "3|4", inputSpec = "SPEC"), items[1])
|
assertEquals(PdfExportItem("Maße", isFreeText = false, freeTextValue = "3|4", inputSpec = "SPEC"), items[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Änderungswünsche: Freitext, Hinweisgruppen, Stile, eigene Seite ------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun benannter_freitext_behaelt_seine_bezeichnung() {
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("a", 1, items = listOf(
|
||||||
|
item("w", 1, checked = true, label = "Wundrandschutz", isFreeText = true, freeTextValue = "Cavilon"),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertTrue(DocumentationToPdfExportModelMapper.map(doc).blocks.single().items.single().showLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun gruppenhinweis_ohne_angehakten_eintrag_der_gruppe_entfaellt() {
|
||||||
|
// Größe: "Zu versorgendes Areal" darf nicht erscheinen, wenn nur die Maße ausgefüllt sind.
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("groesse", 1, items = listOf(
|
||||||
|
item("h_masse", 1, checked = true, label = "Maße", isStaticHint = true),
|
||||||
|
item("masse", 2, checked = true, label = "Maße (Länge / Breite / Tiefe)", freeTextValue = "3|4|1", inputSpec = "SPEC"),
|
||||||
|
item("h_areal", 3, checked = true, label = "Zu versorgendes Areal", isStaticHint = true),
|
||||||
|
item("areal", 4, checked = false, label = "Zu versorgendes Areal"),
|
||||||
|
item("areal_ft", 5, checked = false, label = "Freitext für zu versorgendes Areal", isFreeText = true),
|
||||||
|
// generischer Freitext des Blocks gehört zu keiner Gruppe
|
||||||
|
item("groesse_freetext", 6, checked = false, label = "Freitext", isFreeText = true),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val labels = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items.map { it.label }
|
||||||
|
|
||||||
|
assertEquals(listOf("Maße", "Maße (Länge / Breite / Tiefe)"), labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun generischer_freitext_laesst_gruppenhinweis_nicht_erscheinen() {
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("groesse", 1, items = listOf(
|
||||||
|
item("masse", 1, checked = true, label = "Maße", freeTextValue = "3|4|1", inputSpec = "SPEC"),
|
||||||
|
item("h_areal", 2, checked = true, label = "Zu versorgendes Areal", isStaticHint = true),
|
||||||
|
item("areal", 3, checked = false, label = "Areal"),
|
||||||
|
item("groesse_freetext", 4, checked = true, label = "Freitext", isFreeText = true, freeTextValue = "x"),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val labels = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items.map { it.label }
|
||||||
|
|
||||||
|
assertEquals(listOf("Maße", "Freitext"), labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun gruppenhinweis_mit_angehaktem_eintrag_bleibt_erhalten() {
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("a", 1, items = listOf(
|
||||||
|
item("h", 1, checked = true, label = "Fixieren mit:", isStaticHint = true),
|
||||||
|
item("m", 2, checked = true, label = "Mullbinde"),
|
||||||
|
item("k", 3, checked = false, label = "Klebevlies"),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val labels = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items.map { it.label }
|
||||||
|
|
||||||
|
assertEquals(listOf("Fixieren mit:", "Mullbinde"), labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun gruppenhinweis_mit_gleichnamigem_angehaktem_eintrag_wird_nicht_doppelt_gedruckt() {
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("a", 1, items = listOf(
|
||||||
|
item("h", 1, checked = true, label = "Zu versorgendes Areal", isStaticHint = true),
|
||||||
|
item("areal", 2, checked = true, label = "Zu versorgendes Areal"),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val labels = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items.map { it.label }
|
||||||
|
|
||||||
|
assertEquals(listOf("Zu versorgendes Areal"), labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun abschliessende_hinweise_ohne_folgende_eintraege_bleiben_immer_erhalten() {
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("empfohlene_wundversorgung", 1, items = listOf(
|
||||||
|
item("x", 1, checked = true, label = "Mullbinde"),
|
||||||
|
item("empfohlene_wundversorgung_hinweis_bedarf", 2, checked = true, label = "+ bei Bedarf", isStaticHint = true),
|
||||||
|
item("empfohlene_wundversorgung_hinweis_abklaerung", 3, checked = true, label = "Generell: ...", isStaticHint = true),
|
||||||
|
item("empfohlene_wundversorgung_freetext", 4, checked = false, label = "Freitext", isFreeText = true),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val labels = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items.map { it.label }
|
||||||
|
|
||||||
|
assertEquals(listOf("Mullbinde", "+ bei Bedarf", "Generell: ..."), labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun stile_werden_anhand_der_definitions_id_vergeben() {
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("empfohlene_wundversorgung", 1, items = listOf(
|
||||||
|
item("empfohlene_wundversorgung_hinweis_reinigen_mit", 1, checked = true, label = "Reinigen mit:", isStaticHint = true),
|
||||||
|
item("empfohlene_wundversorgung_nacl", 2, checked = true, label = "NaCl 0,9%"),
|
||||||
|
item("empfohlene_wundversorgung_primaer_abdecken_austamponieren", 3, checked = true, label = "Primär Wunde abdecken/austamponieren"),
|
||||||
|
item("empfohlene_wundversorgung_hinweis_abklaerung", 4, checked = true, label = "Generell: ...", isStaticHint = true),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val styles = DocumentationToPdfExportModelMapper.map(doc).blocks.single().items.map { it.style }
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
listOf(PdfItemStyle.SUBHEADING, PdfItemStyle.NORMAL, PdfItemStyle.SUBHEADING, PdfItemStyle.WARNING),
|
||||||
|
styles,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun empfohlene_wundversorgung_beginnt_auf_eigener_seite_andere_bloecke_nicht() {
|
||||||
|
val doc = documentation(
|
||||||
|
listOf(
|
||||||
|
block("weitere_ueberlegung", 1, items = listOf(item("a", 1, checked = true))),
|
||||||
|
block("empfohlene_wundversorgung", 2, items = listOf(item("b", 1, checked = true))),
|
||||||
|
block("ziel", 3, items = listOf(item("c", 1, checked = true))),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val blocks = DocumentationToPdfExportModelMapper.map(doc).blocks
|
||||||
|
|
||||||
|
assertEquals(listOf(false, true, false), blocks.map { it.startsOnNewPage })
|
||||||
|
}
|
||||||
|
|
||||||
// --- Sortierung ----------------------------------------------------------------------
|
// --- Sortierung ----------------------------------------------------------------------
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user