oddb2xml 3.0.26 → 3.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CLAUDE.md +1 -1
- data/Gemfile.lock +1 -1
- data/History.txt +3 -0
- data/README.md +16 -0
- data/lib/oddb2xml/builder.rb +22 -0
- data/lib/oddb2xml/version.rb +1 -1
- data/oddb2xml.xsd +15 -0
- data/spec/fhir_spec.rb +52 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4aa1328e4844d47543cea04ab6ab5832900bd1bdc1611b1a96d969a71632ff18
|
|
4
|
+
data.tar.gz: e592e5253f0ff09a18e7a515b4b4689484ddc61ba2969a5221bdd3864ebafa74
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30aa032317390a02cd39b1b281897618bd59c51fffb7f793a30dd9caf97798866b8b2deb585e0e877fe0704a2b329c1b3526aaf3ef9e323adfa54e8dfdc05945
|
|
7
|
+
data.tar.gz: 1aeb220381cfd66043a5ca4e695a5c24a349642ca28c44794908c73ec164d5c3b18c3fce92acae6227694c5e68b00fb58e5c292b08aaf1c68f4d81af6697b7f0
|
data/CLAUDE.md
CHANGED
|
@@ -47,7 +47,7 @@ The system follows a **download → extract → build → compress** pipeline:
|
|
|
47
47
|
|
|
48
48
|
6. **Compressor** (`lib/oddb2xml/compressor.rb`) — Optional ZIP/TAR.GZ output compression.
|
|
49
49
|
|
|
50
|
-
7. **FHIR support** (`lib/oddb2xml/fhir_support.rb`) — Self-contained module providing `FhirDownloader` and FHIR NDJSON parsing. Activated via `--fhir` (or `--fhir-url=<URL>`). Downloads per-language NDJSON files (`foph-sl-export-latest-{de,fr,it}.ndjson`) from `epl.bag.admin.ch` to populate French and Italian product names/descriptions. Maps legal status codes `756005022007` and `756005022008` to Swissmedic category D. Reads the BAG **Indikationscode** (`XXXXX.NN`) from the explicit `indicationCode` extension on each `RegulatedAuthorization.indication[].extension[regulatedAuthorization-limitation]` (BAG SL FHIR export >= v2.0.5; handled from 3.0.10). The BAG changelog states the limitation code (`ClinicalUseDefinition.id`) and the indication code are **independent** fields, so the older derivation — combining each indication CUD's `.NN` id-suffix with the reimbursement RA's `FOPHDossierNumber` — is kept only as a fallback for feeds lacking the extension. Exposed as `item[:indication_codes]` and per-package `:indication_codes` (each entry a `{code:, cud_id:, text:}` hash, where `cud_id` is the `limitationIndication` CUD reference used to resolve the text). From 3.0.7 onwards, `Builder#build_product` emits one `<INDICATION_CODE code="XXXXX.NN" cud_id="DRUG.NN">limitation text</INDICATION_CODE>` child per indication on every `<PRD>` in `oddb_product.xml`; live feed numbers: 539 products / 1,293 codes / 100 % with non-empty indication text. Mandatory on prescriptions/invoices for SL price-model drugs from 2026-07-01 — see issue [#113](https://github.com/zdavatz/oddb2xml/issues/113). **Limitation texts** (3.0.8 onwards): the `regulatedAuthorization-limitation` extension has no inline `limitationText` in the live BAG feed — it carries a `limitationIndication` reference to a `ClinicalUseDefinition` whose `indication.diseaseSymptomProcedure.concept.text` is the actual text. The parser stores the ref as `cud_ref` on each Limitation, `Bundle#cud_text_by_id` resolves DE, and `merge_language` propagates FR/IT from the per-language NDJSON files via the same CUD id. Coverage on the live feed jumped from 0 / 9'108 to 9'108 / 9'108 (issue [#116](https://github.com/zdavatz/oddb2xml/issues/116)). **Limitation code / LIMNAMEBAG** (3.0.12 onwards): FHIR has no native BAG limitation code (LIMCD), so `create_limitations_for_package` sets `LimitationCode = cud_ref` (the `limitationIndication` CUD id) instead of `""`. Without this, every FHIR limitation shared an empty `:code`; `Builder#build_artikelstamm` groups its `<LIMITATIONS>` section by code, so all of them collapsed into a single `<LIMITATION>` with an empty `<LIMNAMEBAG>` and only one text survived. Using the CUD id as the key makes each distinct limitation emit and be referenced from its `<PRODUCT>`. The downstream `bin/check_artikelstamm` (`semantic_check.rb`) also crashed on the lone-element output because Ox `:hash_no_attrs` collapses a one-child section into a Hash (and an empty one into nil) — `SemanticCheckXML#get_items` now normalises every section to an Array. **v6 Artikelstamm / per-article INDC (3.0.26 onwards):** `--artikelstamm` now emits the **Elexis Artikelstamm v6** format (namespace `http://elexis.ch/Elexis_Artikelstamm_v6`, file `artikelstamm_DDMMYYYY_v6.xml`/`.csv`, validated against the bundled `Elexis_Artikelstamm_v6.xsd`) — replacing v5. The new piece is a per-`<ITEM>` `<ARTSL>` block carrying the BAG Indikationscodes (issue [#113](https://github.com/zdavatz/oddb2xml/issues/113)): `<PM>true</PM>` plus one `<ARTLIM>` per limitation with `<LIMCD>` (= `cud_ref`, the BAG limitation code), `<INDCD>` (the `XXXXX.NN` indication code from the `indicationCode` extension), and `<VDAT>`/`<VTDAT>` (period start/end). To feed it, `create_limitations_for_package` now also carries `IndicationCode` (→ per-package `:indcd`) and `ValidThruDate` (→ `:vtdate`) on each limitation; `Builder#append_artsl`/`elexis_datetime` emit one `<ARTLIM>` per limitation that has a non-empty `:indcd` (so non-price-model items get no `<ARTSL>`). `PM` is always `true` here because the indication code is required only for SL price-model drugs, which is exactly the set of items that reach this block. The bundled `Elexis_Artikelstamm_v6.xsd` is the canonical MEDEVIT schema extended with oddb2xml's historical Italian elements (`DSCRI` on PRODUCT/LIMITATION/ITEM, `DOSAGE_FORMI` on ITEM) so the output still validates. The legacy `--no-fhir` path emits no `<ARTSL>` (no FHIR limitations).
|
|
50
|
+
7. **FHIR support** (`lib/oddb2xml/fhir_support.rb`) — Self-contained module providing `FhirDownloader` and FHIR NDJSON parsing. Activated via `--fhir` (or `--fhir-url=<URL>`). Downloads per-language NDJSON files (`foph-sl-export-latest-{de,fr,it}.ndjson`) from `epl.bag.admin.ch` to populate French and Italian product names/descriptions. Maps legal status codes `756005022007` and `756005022008` to Swissmedic category D. Reads the BAG **Indikationscode** (`XXXXX.NN`) from the explicit `indicationCode` extension on each `RegulatedAuthorization.indication[].extension[regulatedAuthorization-limitation]` (BAG SL FHIR export >= v2.0.5; handled from 3.0.10). The BAG changelog states the limitation code (`ClinicalUseDefinition.id`) and the indication code are **independent** fields, so the older derivation — combining each indication CUD's `.NN` id-suffix with the reimbursement RA's `FOPHDossierNumber` — is kept only as a fallback for feeds lacking the extension. Exposed as `item[:indication_codes]` and per-package `:indication_codes` (each entry a `{code:, cud_id:, text:}` hash, where `cud_id` is the `limitationIndication` CUD reference used to resolve the text). From 3.0.7 onwards, `Builder#build_product` emits one `<INDICATION_CODE code="XXXXX.NN" cud_id="DRUG.NN">limitation text</INDICATION_CODE>` child per indication on every `<PRD>` in `oddb_product.xml`; live feed numbers: 539 products / 1,293 codes / 100 % with non-empty indication text. Mandatory on prescriptions/invoices for SL price-model drugs from 2026-07-01 — see issue [#113](https://github.com/zdavatz/oddb2xml/issues/113). **Limitation texts** (3.0.8 onwards): the `regulatedAuthorization-limitation` extension has no inline `limitationText` in the live BAG feed — it carries a `limitationIndication` reference to a `ClinicalUseDefinition` whose `indication.diseaseSymptomProcedure.concept.text` is the actual text. The parser stores the ref as `cud_ref` on each Limitation, `Bundle#cud_text_by_id` resolves DE, and `merge_language` propagates FR/IT from the per-language NDJSON files via the same CUD id. Coverage on the live feed jumped from 0 / 9'108 to 9'108 / 9'108 (issue [#116](https://github.com/zdavatz/oddb2xml/issues/116)). **Limitation code / LIMNAMEBAG** (3.0.12 onwards): FHIR has no native BAG limitation code (LIMCD), so `create_limitations_for_package` sets `LimitationCode = cud_ref` (the `limitationIndication` CUD id) instead of `""`. Without this, every FHIR limitation shared an empty `:code`; `Builder#build_artikelstamm` groups its `<LIMITATIONS>` section by code, so all of them collapsed into a single `<LIMITATION>` with an empty `<LIMNAMEBAG>` and only one text survived. Using the CUD id as the key makes each distinct limitation emit and be referenced from its `<PRODUCT>`. The downstream `bin/check_artikelstamm` (`semantic_check.rb`) also crashed on the lone-element output because Ox `:hash_no_attrs` collapses a one-child section into a Hash (and an empty one into nil) — `SemanticCheckXML#get_items` now normalises every section to an Array. **v6 Artikelstamm / per-article INDC (3.0.26 onwards):** `--artikelstamm` now emits the **Elexis Artikelstamm v6** format (namespace `http://elexis.ch/Elexis_Artikelstamm_v6`, file `artikelstamm_DDMMYYYY_v6.xml`/`.csv`, validated against the bundled `Elexis_Artikelstamm_v6.xsd`) — replacing v5. The new piece is a per-`<ITEM>` `<ARTSL>` block carrying the BAG Indikationscodes (issue [#113](https://github.com/zdavatz/oddb2xml/issues/113)): `<PM>true</PM>` plus one `<ARTLIM>` per limitation with `<LIMCD>` (= `cud_ref`, the BAG limitation code), `<INDCD>` (the `XXXXX.NN` indication code from the `indicationCode` extension), and `<VDAT>`/`<VTDAT>` (period start/end). To feed it, `create_limitations_for_package` now also carries `IndicationCode` (→ per-package `:indcd`) and `ValidThruDate` (→ `:vtdate`) on each limitation; `Builder#append_artsl`/`elexis_datetime` emit one `<ARTLIM>` per limitation that has a non-empty `:indcd` (so non-price-model items get no `<ARTSL>`). `PM` is always `true` here because the indication code is required only for SL price-model drugs, which is exactly the set of items that reach this block. The bundled `Elexis_Artikelstamm_v6.xsd` is the canonical MEDEVIT schema extended with oddb2xml's historical Italian elements (`DSCRI` on PRODUCT/LIMITATION/ITEM, `DOSAGE_FORMI` on ITEM) so the output still validates. The legacy `--no-fhir` path emits no `<ARTSL>` (no FHIR limitations). **Per-article INDC in the `-e`/`-b` feeds (3.0.27 onwards):** the same indication codes are also emitted per `<ART>` in `oddb_article.xml` via `Builder#append_indication_codes` — one `<INDICATION_CODE code="XXXXX.NN" cud_id="DRUG.NN" limcd="DRUG.NN" vdat=… vtdat=…>limitation text</INDICATION_CODE>` per limitation that carries an `:indcd` (sourced from the article's `pac[:limitations]`). This reuses the flat `<INDICATION_CODE>` element already emitted on `<PRD>` in `oddb_product.xml` (since 3.0.7), enriched with the limitation code and validity dates so it carries the full `<ARTSL>` payload. The bundled `oddb2xml.xsd` now defines `<INDICATION_CODE>` (simpleContent + `code`/`cud_id`/`limcd`/`vdat`/`vtdat` attributes) and references it from both `<ART>` and `<PRD>` — the `<PRD>` reference had been missing since the 3.0.7 addition, so the FHIR product feed only validated once this was added.
|
|
51
51
|
|
|
52
52
|
8. **Refdata cleanup** (`lib/oddb2xml/refdata_cleanup.rb`) — Compensates for known data-quality issues in upstream Refdata.Articles.xml before they reach the output. Each fix is guarded by a Swissmedic-side heuristic (e.g. comma in `substance_swissmedic` to distinguish mono products from real combinations). Currently fixes (a) the doubled-dose template bug (`X mg / X mg / Stk`, `fix_double_dose`, guarded by `single_substance?`); (b) the spelled-out German galenic form `Retardtabletten` → house-style abbreviation `Ret Tabl` (`normalize_galenic_form` / `GALENIC_NORMALISATIONS`, issue #112 case #13, e.g. RINVOQ — a narrow word-boundary substitution that leaves legitimate brand suffixes like `TRAMAL retard` and Mepha's `Lactab` untouched); and (c) dose info Refdata dropped from `<FullName>`, sourced from the Swissmedic composition string `pack[:composition_swissmedic]` — `fix_missing_combo_dose` (#6, appends a combination's 2nd component strength), `fix_missing_dose` (#4, inserts a mono product's missing strength before the pack count), `fix_missing_volume` (#7, appends an injectable's per-pen volume); and (d) 50-char-truncation repairs — `fix_truncated_metoject` (#1, rebuilds METOJECT Autoinjektor names from the intact `<brand> Autoinjektor <dose>/<vol>` prefix + Swissmedic `size`, localised DE/FR/IT) and `fix_truncated_volume_unit` (#3, restores the cut `ml` of the VERACTIV Vitamin D3 drops). The (c) and (d) fixes are scoped to explicit IKSNR allow-lists (`COMBO_DOSE_IKSNR`/`MISSING_DOSE_IKSNR`/`MISSING_VOLUME_IKSNR`/`METOJECT_IKSNR`/`VERACTIV_VITD3_IKSNR`): a dry run proved a blanket heuristic mis-fires on hundreds of legitimate names (sodium counter-ion doses, strength-less phyto/powder products, concentration names like `CIMZIA 200 mg/ml`), so only catalogued registrations are touched — add an IKSNR to grow coverage. Called from `Builder#apply_refdata_description_cleanups!` at the start of `prepare_articles`. See GitHub issue #112 for the catalogue.
|
|
53
53
|
|
data/Gemfile.lock
CHANGED
data/History.txt
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
=== 3.0.27 / 29.06.2026
|
|
2
|
+
* New (-e/--extended, -b/--firstbase): carry the BAG Indikationscode (INDC) per article in oddb_article.xml as well. Each SL price-model <ART> now gets one <INDICATION_CODE code="XXXXX.NN" cud_id="DRUG.NN" limcd="DRUG.NN" vdat="..." vtdat="...">limitation text</INDICATION_CODE> child per indication -- the same data as the v6 Artikelstamm <ARTSL> block (3.0.26), but in the flat <INDICATION_CODE> shape already emitted on <PRD> in oddb_product.xml, enriched with the limitation code (limcd) and validity dates (vdat/vtdat). The bundled oddb2xml.xsd now defines <INDICATION_CODE> and references it from both <ART> and <PRD> (the <PRD> reference was missing since the 3.0.7 product-feed addition). Only emitted in --fhir mode (the default), where limitations carry an indication code. See issue #113.
|
|
3
|
+
|
|
1
4
|
=== 3.0.26 / 29.06.2026
|
|
2
5
|
* New (--artikelstamm): emit the Elexis Artikelstamm v6 format with per-article BAG Indikationscodes (INDC). The output bumps from v5 to v6 -- namespace http://elexis.ch/Elexis_Artikelstamm_v6, file artikelstamm_DDMMYYYY_v6.xml/.csv, validated against the new bundled Elexis_Artikelstamm_v6.xsd -- and every SL price-model <ITEM> now carries an <ARTSL> block: <PM>true</PM> plus one <ARTLIM> per limitation with <LIMCD> (BAG limitation code), <INDCD> (the Indikationscode XXXXX.NN), and the validity dates <VDAT>/<VTDAT>. The indication codes were already read from the BAG SL FHIR feed's indicationCode extension (used since 3.0.7 for oddb_product.xml's <INDICATION_CODE>); they are now also carried per package limitation and grouped onto each article. Mandatory on prescriptions/invoices for SL price-model drugs from 2026-07-01 (issue #113). The v6 XSD is the canonical MEDEVIT schema extended with oddb2xml's historical Italian elements (DSCRI / DOSAGE_FORMI) so the output keeps validating. Consumers must switch from the v5 to the v6 file.
|
|
3
6
|
|
data/README.md
CHANGED
|
@@ -371,6 +371,22 @@ The output bumps from Artikelstamm v5 to **v6** (namespace
|
|
|
371
371
|
`artikelstamm_DDMMYYYY_v6.xml`, validated against the bundled
|
|
372
372
|
`Elexis_Artikelstamm_v6.xsd`); consumers must switch to the v6 file.
|
|
373
373
|
|
|
374
|
+
Since 3.0.27 the same indication codes are also carried per article in
|
|
375
|
+
the `-e`/`--extended` and `-b`/`--firstbase` feeds: each SL price-model
|
|
376
|
+
`<ART>` in `oddb_article.xml` gets one `<INDICATION_CODE>` child per
|
|
377
|
+
indication — the flat shape already used on `<PRD>` in
|
|
378
|
+
`oddb_product.xml`, enriched with the limitation code and validity
|
|
379
|
+
dates:
|
|
380
|
+
|
|
381
|
+
```xml
|
|
382
|
+
<ART DT="...">
|
|
383
|
+
...
|
|
384
|
+
<INDICATION_CODE code="17079.01" cud_id="MABTHERA.01"
|
|
385
|
+
limcd="MABTHERA.01" vdat="2023-05-01T00:00:00"
|
|
386
|
+
vtdat="">In Kombination ...</INDICATION_CODE>
|
|
387
|
+
</ART>
|
|
388
|
+
```
|
|
389
|
+
|
|
374
390
|
## Limitation texts in `--fhir` mode
|
|
375
391
|
|
|
376
392
|
In 3.0.8 we fixed empty `<DescriptionDe/Fr/It>` on every `<Limitation>`
|
data/lib/oddb2xml/builder.rb
CHANGED
|
@@ -1190,6 +1190,9 @@ module Oddb2xml
|
|
|
1190
1190
|
xml.NINCD nincd
|
|
1191
1191
|
}
|
|
1192
1192
|
end
|
|
1193
|
+
# BAG Indikationscodes for SL price-model drugs (issue #113),
|
|
1194
|
+
# mirroring the v6 Artikelstamm <ARTSL> data in oddb_article.xml.
|
|
1195
|
+
append_indication_codes(xml, pac && pac[:limitations])
|
|
1193
1196
|
end
|
|
1194
1197
|
end
|
|
1195
1198
|
xml.RESULT {
|
|
@@ -1600,6 +1603,25 @@ module Oddb2xml
|
|
|
1600
1603
|
end
|
|
1601
1604
|
end
|
|
1602
1605
|
|
|
1606
|
+
# Emit per-article BAG Indikationscodes for the -e/--extended and
|
|
1607
|
+
# -b/--firstbase article feed (oddb_article.xml), one <INDICATION_CODE> per
|
|
1608
|
+
# limitation that carries an INDCD. Same data as the v6 <ARTSL> block, but
|
|
1609
|
+
# in the flat <INDICATION_CODE> shape already used on <PRD> in
|
|
1610
|
+
# oddb_product.xml — enriched here with the limitation code (LIMCD) and the
|
|
1611
|
+
# validity dates (VDAT/VTDAT). See issue #113.
|
|
1612
|
+
def append_indication_codes(xml, limitations)
|
|
1613
|
+
ics = (limitations || []).select { |lim| lim[:indcd] && !lim[:indcd].to_s.empty? }
|
|
1614
|
+
ics = ics.uniq { |lim| [lim[:code], lim[:indcd]] }
|
|
1615
|
+
ics.each do |lim|
|
|
1616
|
+
xml.INDICATION_CODE lim[:desc_de].to_s,
|
|
1617
|
+
code: lim[:indcd].to_s,
|
|
1618
|
+
cud_id: lim[:cud_ref].to_s,
|
|
1619
|
+
limcd: lim[:code].to_s,
|
|
1620
|
+
vdat: elexis_datetime(lim[:vdate]) || "",
|
|
1621
|
+
vtdat: elexis_datetime(lim[:vtdate]) || ""
|
|
1622
|
+
end
|
|
1623
|
+
end
|
|
1624
|
+
|
|
1603
1625
|
def build_artikelstamm
|
|
1604
1626
|
@@emitted_v6_gtins = []
|
|
1605
1627
|
@csv_file = CSV.open(File.join(WORK_DIR, "artikelstamm_#{Date.today.strftime("%d%m%Y")}_v6.csv"), "w+")
|
data/lib/oddb2xml/version.rb
CHANGED
data/oddb2xml.xsd
CHANGED
|
@@ -169,11 +169,25 @@
|
|
|
169
169
|
<xs:element ref="ns1:ARTBAR"/>
|
|
170
170
|
<xs:element minOccurs="0" maxOccurs="unbounded" ref="ns1:ARTPRI"/>
|
|
171
171
|
<xs:element minOccurs="0" ref="ns1:ARTINS"/>
|
|
172
|
+
<xs:element minOccurs="0" maxOccurs="unbounded" ref="ns1:INDICATION_CODE"/>
|
|
172
173
|
</xs:sequence>
|
|
173
174
|
<xs:attribute name="DT" use="required"/>
|
|
174
175
|
<xs:attribute type="xs:string" name="SHA256" use="required"/>
|
|
175
176
|
</xs:complexType>
|
|
176
177
|
</xs:element>
|
|
178
|
+
<xs:element name="INDICATION_CODE">
|
|
179
|
+
<xs:complexType>
|
|
180
|
+
<xs:simpleContent>
|
|
181
|
+
<xs:extension base="xs:string">
|
|
182
|
+
<xs:attribute name="code" type="xs:string"/>
|
|
183
|
+
<xs:attribute name="cud_id" type="xs:string"/>
|
|
184
|
+
<xs:attribute name="limcd" type="xs:string"/>
|
|
185
|
+
<xs:attribute name="vdat" type="xs:string"/>
|
|
186
|
+
<xs:attribute name="vtdat" type="xs:string"/>
|
|
187
|
+
</xs:extension>
|
|
188
|
+
</xs:simpleContent>
|
|
189
|
+
</xs:complexType>
|
|
190
|
+
</xs:element>
|
|
177
191
|
<xs:element name="PHAR" type="xs:integer"/>
|
|
178
192
|
<xs:element name="SMCAT">
|
|
179
193
|
<xs:simpleType>
|
|
@@ -853,6 +867,7 @@
|
|
|
853
867
|
<xs:element minOccurs="0" ref="ns1:IT"/>
|
|
854
868
|
<xs:element minOccurs="0" ref="ns1:ORPH"/>
|
|
855
869
|
<xs:element ref="ns1:CPT"/>
|
|
870
|
+
<xs:element minOccurs="0" maxOccurs="unbounded" ref="ns1:INDICATION_CODE"/>
|
|
856
871
|
<xs:element minOccurs="0" ref="ns1:PackGrSwissmedic"/>
|
|
857
872
|
<xs:element minOccurs="0" ref="ns1:EinheitSwissmedic"/>
|
|
858
873
|
<xs:element minOccurs="0" ref="ns1:SubstanceSwissmedic"/>
|
data/spec/fhir_spec.rb
CHANGED
|
@@ -256,4 +256,56 @@ describe "FHIR Indikationscode support" do
|
|
|
256
256
|
expect(artsl_xml(nil)).not_to include("<ARTSL>")
|
|
257
257
|
end
|
|
258
258
|
end
|
|
259
|
+
|
|
260
|
+
describe Oddb2xml::Builder, "per-article INDICATION_CODE (-e / -b feed)" do
|
|
261
|
+
def indication_xml(limitations)
|
|
262
|
+
builder = described_class.new
|
|
263
|
+
Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
|
|
264
|
+
xml.ART do
|
|
265
|
+
builder.send(:append_indication_codes, xml, limitations)
|
|
266
|
+
end
|
|
267
|
+
end.to_xml
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "emits one <INDICATION_CODE> per indication with limcd + validity dates" do
|
|
271
|
+
data = Oddb2xml::FhirExtractor.new(cyramza_fixture).to_hash
|
|
272
|
+
lims = data.values.first[:packages].values.first[:limitations]
|
|
273
|
+
xml = indication_xml(lims)
|
|
274
|
+
|
|
275
|
+
expect(xml.scan("<INDICATION_CODE").size).to eq(2)
|
|
276
|
+
expect(xml).to include('code="20403.01"')
|
|
277
|
+
expect(xml).to include('cud_id="CYRAMZA.01"')
|
|
278
|
+
expect(xml).to include('limcd="CYRAMZA.01"')
|
|
279
|
+
expect(xml).to include('vdat="2024-10-01T00:00:00"')
|
|
280
|
+
# CYRAMZA.02 has an end date -> non-empty vtdat; CYRAMZA.01 has none.
|
|
281
|
+
expect(xml).to include('vtdat="2027-09-30T00:00:00"')
|
|
282
|
+
expect(xml).to include('vtdat=""')
|
|
283
|
+
# The limitation text travels in the element body.
|
|
284
|
+
expect(xml).to include("In Kombination mit Paclitaxel")
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "emits nothing when no limitation carries an indication code" do
|
|
288
|
+
expect(indication_xml([{code: "X", indcd: "", vdate: "2020-01-01"}])).not_to include("<INDICATION_CODE")
|
|
289
|
+
expect(indication_xml(nil)).not_to include("<INDICATION_CODE")
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "produces an oddb_article.xml that validates against oddb2xml.xsd" do
|
|
293
|
+
items = Oddb2xml::FhirExtractor.new(cyramza_fixture).to_hash
|
|
294
|
+
builder = described_class.new
|
|
295
|
+
{
|
|
296
|
+
"@items" => items, "@refdata" => {}, "@packs" => {}, "@migel" => {},
|
|
297
|
+
"@interactions" => [], "@flags" => {}, "@orphan" => [], "@firstbase" => {},
|
|
298
|
+
"@substances" => [], "@codes" => {}, "@missing" => [], "@tag_suffix" => nil,
|
|
299
|
+
"@infos_zur_rose" => {}, "@lppvs" => {}, "@articles" => nil, "@weleda_sl" => {}
|
|
300
|
+
}.each { |k, v| builder.instance_variable_set(k.to_sym, v) }
|
|
301
|
+
|
|
302
|
+
xml = builder.send(:build_article)
|
|
303
|
+
expect(xml.scan("<INDICATION_CODE").size).to be >= 1
|
|
304
|
+
|
|
305
|
+
xsd_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "oddb2xml.xsd"))
|
|
306
|
+
xsd = Nokogiri::XML::Schema(File.read(xsd_path))
|
|
307
|
+
errors = xsd.validate(Nokogiri::XML(xml))
|
|
308
|
+
expect(errors.map(&:message)).to eq([])
|
|
309
|
+
end
|
|
310
|
+
end
|
|
259
311
|
end
|