oddb2xml 3.0.5 → 3.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad986fc08f7abf1826b696378727e91dcb94cc53d5cdcdc2e0d009b755b92410
4
- data.tar.gz: 7df4f478dc0cb3cfbd2dfcb796b87ad047aadfdbc37bc9eab80a58b9943078b1
3
+ metadata.gz: 8b3a91c4a9ff36983011294c705fd882a5cf2a7f60f972cd1e2de61877e353db
4
+ data.tar.gz: 7eb411ee5192d1a1eec417536e62761c5cbb833a075221ae283f1de577f5a4f6
5
5
  SHA512:
6
- metadata.gz: 9b7a3266179a31992706cd2d3c999cc73b94cacf293617935475d801c1cc00ed5d23ed91daec53cf2c4f4a234d7057dfe82390980465f9b5e7a19bbff6bcca6c
7
- data.tar.gz: d223b395fa978c6361c3f6c76ab2111558b029f97e9fad09b2c53d379f24f42f46c9b667da531c7505bcf7c121b5bd21cdd588ec64b530e80c718654c605a27f
6
+ metadata.gz: 92721b900cb1f754d87463c8a22fd552eabceee1ec12e16aca202084bfd18fa03f4def7ea3c2232ba4598d225c49f165a9c49cf995aae54f9a655d8551cb7267
7
+ data.tar.gz: ef7383d72a3535996c70d9d723b12649b09927cff97b9575e49f15553c87c92d142c940eded2fd22d4ef8399bf6f7d2538c72e413623485150837bfa43d0faf1
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oddb2xml (3.0.4)
4
+ oddb2xml (3.0.6)
5
+ csv
5
6
  htmlentities
6
7
  httpi
7
8
  mechanize (>= 2.8.5)
@@ -43,6 +44,7 @@ GEM
43
44
  crack (1.0.1)
44
45
  bigdecimal
45
46
  rexml
47
+ csv (3.3.5)
46
48
  diff-lcs (1.6.2)
47
49
  domain_name (0.6.20240107)
48
50
  flexmock (3.0.2)
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ === 3.0.6 / 06.05.2026
2
+ * FHIR: extract Indikationscode (XXXXX.NN) from ClinicalUseDefinition resources by combining FOPHDossierNumber with each CUD's .NN id-suffix; expose as item[:indication_codes] (and per package) so downstream builders can include it on prescriptions and invoices as required by BAG from 2026-07-01 (issue #113)
3
+ * Declare csv as a runtime dependency in the gemspec (csv was removed from Ruby's default gems in 3.4)
4
+
5
+ === 3.0.5 / 25.04.2026
6
+ * Refdata cleanup: compensate the doubled-dose template bug in Refdata.Articles.xml (e.g. "30 mg / 30 mg / 100 Tablette") by collapsing to a single token. Guarded by a Swissmedic-side comma check so real combination products are untouched (issue #112)
7
+
1
8
  === 3.0.4 / 24.04.2026
2
9
  * Firstbase: switch -b/--firstbase from the deprecated pillbox.oddb.org XLSX to the GS1 Switzerland CSV at https://id.gs1.ch/01/07612345000961 (full firstbase barcode registry, ~189k items). Downloaded file is now firstbase.csv; FirstbaseExtractor now parses CSV with headers instead of XLSX.
3
10
 
@@ -159,7 +159,7 @@ module Oddb2xml
159
159
  module FHIR
160
160
  # Bundle represents one line in the NDJSON file
161
161
  class Bundle
162
- attr_reader :medicinal_product, :packages, :authorizations, :ingredients
162
+ attr_reader :medicinal_product, :packages, :authorizations, :ingredients, :clinical_use_definitions
163
163
 
164
164
  def initialize(json_line)
165
165
  data = JSON.parse(json_line)
@@ -174,6 +174,7 @@ module Oddb2xml
174
174
  @packages = []
175
175
  @authorizations = []
176
176
  @ingredients = []
177
+ @clinical_use_definitions = []
177
178
 
178
179
  @entries.each do |entry|
179
180
  resource = entry["resource"]
@@ -186,11 +187,32 @@ module Oddb2xml
186
187
  @authorizations << Authorization.new(resource)
187
188
  when "Ingredient"
188
189
  @ingredients << Ingredient.new(resource)
190
+ when "ClinicalUseDefinition"
191
+ @clinical_use_definitions << ClinicalUseDefinition.new(resource)
189
192
  end
190
193
  end
191
194
  end
192
195
  end
193
196
 
197
+ # ClinicalUseDefinition carries one indication. Its `id` ends in ".NN",
198
+ # the per-indication suffix that combines with the FOPHDossierNumber
199
+ # (XXXXX) on the reimbursement RegulatedAuthorization to form the
200
+ # Indikationscode XXXXX.NN required by BAG from 2026-07-01.
201
+ class ClinicalUseDefinition
202
+ attr_reader :id, :nn_suffix, :type, :text
203
+
204
+ def initialize(resource)
205
+ @id = resource["id"]
206
+ @type = resource["type"]
207
+ @nn_suffix = @id&.[](/\.(\d{2})\z/, 1)
208
+ @text = resource.dig("indication", "diseaseSymptomProcedure", "concept", "text")
209
+ end
210
+
211
+ def indication?
212
+ @type == "indication"
213
+ end
214
+ end
215
+
194
216
  class MedicinalProduct
195
217
  attr_reader :names, :atc_code, :classification, :it_codes
196
218
 
@@ -427,6 +449,11 @@ module Oddb2xml
427
449
  prep.OrgGenCode = map_org_gen_code(mp.classification)
428
450
  prep.ItCode = mp.it_code # Add IT code
429
451
 
452
+ # Indikationscodes (BAG: XXXXX.NN, mandatory on prescriptions/invoices
453
+ # from 2026-07-01). Build from FOPHDossierNumber (reimbursement auth)
454
+ # plus each ClinicalUseDefinition's .NN suffix. See issue #113.
455
+ prep.IndicationCodes = build_indication_codes(bundle)
456
+
430
457
  # Map packages
431
458
  prep.Packs = OpenStruct.new
432
459
  prep.Packs.Pack = bundle.packages.map do |pkg|
@@ -535,6 +562,21 @@ module Oddb2xml
535
562
  reimbursement&.cost_share
536
563
  end
537
564
 
565
+ def build_indication_codes(bundle)
566
+ reimbursement = bundle.authorizations.find(&:reimbursement_sl?)
567
+ dossier = reimbursement&.foph_dossier_no
568
+ return [] unless dossier && !bundle.clinical_use_definitions.empty?
569
+
570
+ bundle.clinical_use_definitions.each_with_object([]) do |cud, acc|
571
+ next unless cud.indication? && cud.nn_suffix
572
+ acc << OpenStruct.new(
573
+ code: "#{dossier}.#{cud.nn_suffix}",
574
+ cud_id: cud.id,
575
+ text: cud.text
576
+ )
577
+ end
578
+ end
579
+
538
580
  def map_org_gen_code(classification)
539
581
  return nil unless classification
540
582
 
@@ -616,6 +658,13 @@ module Oddb2xml
616
658
  item[:comment_it] = ""
617
659
  item[:it_code] = (itc = seq.ItCode) ? itc : "" # NOW available in FHIR!
618
660
 
661
+ # Indikationscodes (BAG XXXXX.NN, see issue #113). Each entry is a
662
+ # Hash with :code, :cud_id, :text — mandatory on rx/invoices from
663
+ # 2026-07-01.
664
+ item[:indication_codes] = Array(seq.IndicationCodes).map do |ic|
665
+ {code: ic.code, cud_id: ic.cud_id, text: ic.text}
666
+ end
667
+
619
668
  # Build substances array
620
669
  item[:substances] = []
621
670
  if seq.Substances && seq.Substances.Substance
@@ -673,7 +722,8 @@ module Oddb2xml
673
722
  sl_entry: true,
674
723
  swissmedic_category: (cat = pac.SwissmedicCategory) ? cat : "",
675
724
  swissmedic_number8: (num = pac.SwissmedicNo8) ? num : "",
676
- prices: {exf_price: exf, pub_price: pub}
725
+ prices: {exf_price: exf, pub_price: pub},
726
+ indication_codes: item[:indication_codes]
677
727
  }
678
728
 
679
729
  # Map limitations from FHIR
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "3.0.5"
2
+ VERSION = "3.0.6"
3
3
  end
data/oddb2xml.gemspec CHANGED
@@ -38,6 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.add_dependency "htmlentities"
39
39
  spec.add_dependency "webrick", ">= 1.8.2"
40
40
  spec.add_dependency "rexml", ">= 3.3.9"
41
+ spec.add_dependency "csv" # bundled with Ruby <= 3.3, gem from 3.4 onwards
41
42
  spec.add_dependency "standardrb"
42
43
  spec.add_dependency "rack", ">= 3.1.20"
43
44
 
@@ -0,0 +1 @@
1
+ {"resourceType":"Bundle","id":"9a91dc6e-3410-4020-9375-b2cae207e1bf","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-bundle"]},"type":"collection","entry":[{"fullUrl":"http://fhir.epl.bag.admin.ch/MedicinalProductDefinition/de872be1-02ff-4b8e-8691-658099182eb7","resource":{"resourceType":"MedicinalProductDefinition","id":"de872be1-02ff-4b8e-8691-658099182eb7","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-medicinalproductdefinition"]},"text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">Cyramza Inf Konz 100 mg/10 ml</div>"},"classification":[{"coding":[{"system":"http://www.whocc.no/atc","code":"L01FG02","display":"Ramucirumab"}]},{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-index-therapeuticus","code":"070000","display":"07. STOFFWECHSEL"}]},{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-index-therapeuticus","code":"071600","display":"07.16. Oncologica"}]},{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-index-therapeuticus","code":"071610","display":"07.16.10. Cytostatica"}]}],"name":[{"productName":"Cyramza Inf Konz 100 mg/10 ml","usage":[{"country":{"coding":[{"system":"urn:iso:std:iso:3166","code":"CH","display":"Switzerland"}]},"language":{"coding":[{"system":"urn:ietf:bcp:47","code":"de-CH","display":"German (Switzerland)"}]}}]},{"productName":"Cyramza conc perf 100 mg/10 ml","usage":[{"country":{"coding":[{"system":"urn:iso:std:iso:3166","code":"CH","display":"Switzerland"}]},"language":{"coding":[{"system":"urn:ietf:bcp:47","code":"fr-CH","display":"French (Switzerland)"}]}}]},{"productName":"Cyramza Inf Konz 100 mg/10 ml","usage":[{"country":{"coding":[{"system":"urn:iso:std:iso:3166","code":"CH","display":"Switzerland"}]},"language":{"coding":[{"system":"urn:ietf:bcp:47","code":"it-CH","display":"Italian (Switzerland)"}]}}]}]}},{"fullUrl":"http://fhir.epl.bag.admin.ch/RegulatedAuthorization/65206","resource":{"resourceType":"RegulatedAuthorization","id":"65206","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-regulatedauthorization"]},"text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">Marketing Authorisation 65206 for MedicinalProductDefinition de872be1-02ff-4b8e-8691-658099182eb7</div>"},"contained":[{"resourceType":"Organization","id":"7601001261853","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-organization"]},"identifier":[{"system":"urn:oid:2.51.1.3","value":"7601001261853"}],"name":"Eli Lilly (Suisse) SA"}],"identifier":[{"system":"http://fhir.ch/ig/ch-epl/sid/authno","value":"65206"}],"subject":[{"reference":"CHIDMPMedicinalProductDefinition/de872be1-02ff-4b8e-8691-658099182eb7"}],"type":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-authorisation-type","code":"756000002001","display":"Marketing Authorisation"}]},"region":[{"coding":[{"system":"urn:iso:std:iso:3166","code":"CH","display":"Switzerland"}]}],"holder":{"reference":"#7601001261853"}}},{"fullUrl":"http://fhir.epl.bag.admin.ch/PackagedProductDefinition/c3a247c9-d686-49ab-9344-892d8b93f148","resource":{"resourceType":"PackagedProductDefinition","id":"c3a247c9-d686-49ab-9344-892d8b93f148","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-packagedproductdefinition"]},"text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">Cyramza Inf Konz 100 mg/10 ml Durchstf 1 Stk</div>"},"packageFor":[{"reference":"CHIDMPMedicinalProductDefinition/de872be1-02ff-4b8e-8691-658099182eb7"}],"containedItemQuantity":[{"unit":"Durchstf 1 Stk"}],"description":"Cyramza Inf Konz 100 mg/10 ml Durchstf 1 Stk","legalStatusOfSupply":[{"code":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-SMC-legal-status-of-supply","code":"756005022001","display":"Medicinal product subject to medical or veterinary prescription single dispensation (A)"}]}}],"packaging":{"identifier":[{"system":"urn:oid:2.51.1.1","value":"7680652060015"}]}}},{"fullUrl":"http://fhir.epl.bag.admin.ch/RegulatedAuthorization/65206001-c3a247c9-d686-49ab-9344-892d8b93f148","resource":{"resourceType":"RegulatedAuthorization","id":"65206001-c3a247c9-d686-49ab-9344-892d8b93f148","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-regulatedauthorization"]},"text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">Marketing Authorisation 65206001-c3a247c9-d686-49ab-9344-892d8b93f148 for PackagedProductDefinition c3a247c9-d686-49ab-9344-892d8b93f148</div>"},"contained":[{"resourceType":"Organization","id":"7601001261853","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-organization"]},"identifier":[{"system":"urn:oid:2.51.1.3","value":"7601001261853"}],"name":"Eli Lilly (Suisse) SA"}],"identifier":[{"system":"http://fhir.ch/ig/ch-epl/sid/authno","value":"65206001"}],"subject":[{"reference":"CHIDMPPackagedProductDefinition/c3a247c9-d686-49ab-9344-892d8b93f148"}],"type":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-authorisation-type","code":"756000002001","display":"Marketing Authorisation"}]},"region":[{"coding":[{"system":"urn:iso:std:iso:3166","code":"CH","display":"Switzerland"}]}],"holder":{"reference":"#7601001261853"}}},{"fullUrl":"http://fhir.epl.bag.admin.ch/RegulatedAuthorization/9c50920a-2d9d-476f-89d8-9477c8840de9","resource":{"resourceType":"RegulatedAuthorization","id":"9c50920a-2d9d-476f-89d8-9477c8840de9","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-regulatedauthorization"]},"text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">Reimbursement SL 9c50920a-2d9d-476f-89d8-9477c8840de9 for PackagedProductDefinition c3a247c9-d686-49ab-9344-892d8b93f148</div>"},"contained":[{"resourceType":"Organization","id":"7601001261853","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-organization"]},"identifier":[{"system":"urn:oid:2.51.1.3","value":"7601001261853"}],"name":"Eli Lilly (Suisse) SA"}],"extension":[{"url":"http://fhir.ch/ig/ch-epl/StructureDefinition/reimbursementSL","extension":[{"url":"FOPHDossierNumber","valueIdentifier":{"system":"urn:oid:2.16.756.1","value":"20403"}},{"url":"status","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-reimbursement-status","code":"756001021001","display":"Reimbursed"}]}},{"url":"statusDate","valueDate":"2019-06-01"},{"url":"listingStatus","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-listing-status","code":"756001002001","display":"Listed"}]}},{"url":"listingPeriod","valuePeriod":{"start":"2019-06-01"}},{"url":"firstListingDate","valueDate":"2016-03-01"},{"url":"costShare","valueInteger":10},{"url":"priceModel","valueBoolean":true},{"url":"http://fhir.ch/ig/ch-epl/StructureDefinition/productPrice","extension":[{"url":"type","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-price-type","code":"756002005001","display":"Retail price"}]}},{"url":"changeType","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-type-of-price-change","code":"756002006009","display":"Normal price mutation"}]}},{"url":"value","valueMoney":{"value":421.65,"currency":"CHF"}},{"url":"changeDate","valueDate":"2024-10-01"}]},{"url":"http://fhir.ch/ig/ch-epl/StructureDefinition/productPrice","extension":[{"url":"type","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-price-type","code":"756002005002","display":"Ex-factory price"}]}},{"url":"changeType","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-type-of-price-change","code":"756002006009","display":"Normal price mutation"}]}},{"url":"value","valueMoney":{"value":372.61,"currency":"CHF"}},{"url":"changeDate","valueDate":"2024-10-01"}]}]}],"subject":[{"reference":"CHIDMPPackagedProductDefinition/c3a247c9-d686-49ab-9344-892d8b93f148"}],"type":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-authorisation-type","code":"756000002003","display":"Reimbursement SL"}]},"indication":[{"extension":[{"url":"http://fhir.ch/ig/ch-epl/StructureDefinition/regulatedAuthorization-limitation","extension":[{"url":"status","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-limitationstatus","code":"756002071001","display":"Limitation Reimbursed"}]}},{"url":"statusDate","valueDate":"2024-10-01"},{"url":"period","valuePeriod":{"start":"2024-10-01"}},{"url":"firstLimitationDate","valueDate":"2016-03-01"},{"url":"indicationCode","valueString":"20403.01"},{"url":"limitationIndication","valueReference":{"reference":"ClinicalUseDefinition/CYRAMZA.01"}}]}]},{"extension":[{"url":"http://fhir.ch/ig/ch-epl/StructureDefinition/regulatedAuthorization-limitation","extension":[{"url":"status","valueCodeableConcept":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-epl-foph-limitationstatus","code":"756002071001","display":"Limitation Reimbursed"}]}},{"url":"statusDate","valueDate":"2024-10-01"},{"url":"period","valuePeriod":{"start":"2024-10-01","end":"2027-09-30"}},{"url":"reimbursementEndDate","valueDate":"2027-12-31"},{"url":"firstLimitationDate","valueDate":"2016-03-01"},{"url":"indicationCode","valueString":"20403.02"},{"url":"limitationIndication","valueReference":{"reference":"ClinicalUseDefinition/CYRAMZA.02"}}]}]}],"holder":{"reference":"#7601001261853"}}},{"fullUrl":"http://fhir.epl.bag.admin.ch/Ingredient/a5edbabc-f9d6-4019-ac6f-2a80fe033339","resource":{"resourceType":"Ingredient","id":"a5edbabc-f9d6-4019-ac6f-2a80fe033339","meta":{"profile":["http://fhir.ch/ig/ch-epl/StructureDefinition/ch-idmp-ingredient"]},"text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">Ramucirumabum 100 mg</div>"},"status":"draft","for":[{"reference":"CHIDMPMedicinalProductDefinition/de872be1-02ff-4b8e-8691-658099182eb7"}],"role":{"coding":[{"system":"http://fhir.ch/ig/ch-epl/CodeSystem/ch-SMC-ingredient-role","code":"756005051001","display":"Active"}]},"substance":{"code":{"concept":{"text":"Ramucirumabum"}},"strength":[{"presentationQuantity":{"value":100,"unit":"mg"}}]}}},{"fullUrl":"http://fhir.epl.bag.admin.ch/ClinicalUseDefinition/CYRAMZA.01","resource":{"resourceType":"ClinicalUseDefinition","id":"CYRAMZA.01","text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">In Kombination mit Paclitaxel für die Behandlung von erwachsenen Patienten mit ECOG-Status 0 oder 1 mit fortgeschrittenem Adenokarzinom des Magens oder gastroösophagealen Übergangs mit einem Progress nach vorausgegangener Platin- und Fluoropyrimidin-haltiger Chemotherapie.\nAls Monotherapie für die Behandlung von erwachsenen Patienten mit ECOG-Status 0 oder 1 mit fortgeschrittenem Adenokarzinom des Magens oder des gastroösophagealen Übergangs mit einem Progress nach vorausgegangener Platin- oder Fluoropyrimidin-haltiger Chemotherapie, wenn diese Patienten für eine Kombinationstherapie mit Paclitaxel nicht geeignet sind.\nDie Behandlung bedarf der Kostengutsprache durch den Krankenversicherer nach vorgängiger Konsultation des Vertrauensarztes.\nFolgender Indikationscode ist an den Krankenversicherer zu übermitteln: 20403.01</div>"},"type":"indication","indication":{"diseaseSymptomProcedure":{"concept":{"text":"In Kombination mit Paclitaxel für die Behandlung von erwachsenen Patienten mit ECOG-Status 0 oder 1 mit fortgeschrittenem Adenokarzinom des Magens oder gastroösophagealen Übergangs mit einem Progress nach vorausgegangener Platin- und Fluoropyrimidin-haltiger Chemotherapie.\nAls Monotherapie für die Behandlung von erwachsenen Patienten mit ECOG-Status 0 oder 1 mit fortgeschrittenem Adenokarzinom des Magens oder des gastroösophagealen Übergangs mit einem Progress nach vorausgegangener Platin- oder Fluoropyrimidin-haltiger Chemotherapie, wenn diese Patienten für eine Kombinationstherapie mit Paclitaxel nicht geeignet sind.\nDie Behandlung bedarf der Kostengutsprache durch den Krankenversicherer nach vorgängiger Konsultation des Vertrauensarztes.\nFolgender Indikationscode ist an den Krankenversicherer zu übermitteln: 20403.01"}}}}},{"fullUrl":"http://fhir.epl.bag.admin.ch/ClinicalUseDefinition/CYRAMZA.02","resource":{"resourceType":"ClinicalUseDefinition","id":"CYRAMZA.02","text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">In Kombination mit FOLFIRI (Irinotecan, Folsäure und 5-Fluorouracil) zur Behandlung von erwachsenen Patienten mit metastasiertem kolorektalem Karzinom (mKRK) mit Progress während oder nach vorausgegangener Therapie mit Bevacizumab, Oxaliplatin und einem Fluoropyrimidin. Die Behandlung bedarf der Kostengutsprache durch den Krankenversicherer nach vorgängiger Konsultation des Vertrauensarztes.\nDie Eli Lilly (Suisse) SA vergütet dem Krankenversicherer, bei dem die versicherte Person zum Zeitpunkt des Bezugs versichert war, auf dessen erste Aufforderung hin für auf jede bezogene Packung CYRAMZA einen festgelegten Anteil des Fabrikabgabepreises zurück. Sie gibt dem Krankenversicherer die Höhe der Rückvergütung bekannt. Die Mehrwertsteuer kann nicht zusätzlich zu diesem Anteil des Fabrikabgabepreises zurückgefordert werden. Die Aufforderung zur Rückvergütung soll ab dem Zeitpunkt der Verabreichung erfolgen.\nFolgender Indikationscode ist an den Krankenversicherer zu übermitteln: 20403.02</div>"},"type":"indication","indication":{"diseaseSymptomProcedure":{"concept":{"text":"In Kombination mit FOLFIRI (Irinotecan, Folsäure und 5-Fluorouracil) zur Behandlung von erwachsenen Patienten mit metastasiertem kolorektalem Karzinom (mKRK) mit Progress während oder nach vorausgegangener Therapie mit Bevacizumab, Oxaliplatin und einem Fluoropyrimidin. Die Behandlung bedarf der Kostengutsprache durch den Krankenversicherer nach vorgängiger Konsultation des Vertrauensarztes.\nDie Eli Lilly (Suisse) SA vergütet dem Krankenversicherer, bei dem die versicherte Person zum Zeitpunkt des Bezugs versichert war, auf dessen erste Aufforderung hin für auf jede bezogene Packung CYRAMZA einen festgelegten Anteil des Fabrikabgabepreises zurück. Sie gibt dem Krankenversicherer die Höhe der Rückvergütung bekannt. Die Mehrwertsteuer kann nicht zusätzlich zu diesem Anteil des Fabrikabgabepreises zurückgefordert werden. Die Aufforderung zur Rückvergütung soll ab dem Zeitpunkt der Verabreichung erfolgen.\nFolgender Indikationscode ist an den Krankenversicherer zu übermitteln: 20403.02"}}}}}]}
data/spec/fhir_spec.rb ADDED
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+ require "oddb2xml/downloader"
3
+ require "oddb2xml/extractor"
4
+ require "oddb2xml/fhir_support"
5
+
6
+ describe "FHIR Indikationscode support" do
7
+ let(:cyramza_fixture) { File.join(Oddb2xml::SpecData, "fhir", "cyramza.ndjson") }
8
+
9
+ describe Oddb2xml::FHIR::ClinicalUseDefinition do
10
+ it "extracts the .NN suffix from id" do
11
+ cud = described_class.new("id" => "CYRAMZA.02", "type" => "indication")
12
+ expect(cud.nn_suffix).to eq("02")
13
+ expect(cud.indication?).to be true
14
+ end
15
+
16
+ it "returns nil suffix for non-conforming ids" do
17
+ cud = described_class.new("id" => "CYRAMZA")
18
+ expect(cud.nn_suffix).to be_nil
19
+ end
20
+ end
21
+
22
+ describe Oddb2xml::FHIR::Bundle do
23
+ it "collects ClinicalUseDefinition entries" do
24
+ line = File.read(cyramza_fixture).lines.first
25
+ bundle = described_class.new(line)
26
+ expect(bundle.clinical_use_definitions).not_to be_empty
27
+ expect(bundle.clinical_use_definitions.map(&:id)).to include("CYRAMZA.01", "CYRAMZA.02")
28
+ end
29
+ end
30
+
31
+ describe Oddb2xml::FHIR::PreparationsParser do
32
+ it "constructs XXXXX.NN indication codes from FOPHDossierNumber + CUD suffix" do
33
+ parser = described_class.new(cyramza_fixture)
34
+ prep = parser.preparations.first
35
+ codes = prep.IndicationCodes.map(&:code)
36
+ expect(codes).to include("20403.01", "20403.02")
37
+ end
38
+ end
39
+
40
+ describe Oddb2xml::FhirExtractor do
41
+ it "exposes indication_codes on each item and package" do
42
+ data = described_class.new(cyramza_fixture).to_hash
43
+ expect(data).not_to be_empty
44
+
45
+ item = data.values.first
46
+ codes = item[:indication_codes].map { |ic| ic[:code] }
47
+ expect(codes).to include("20403.01", "20403.02")
48
+
49
+ pkg = item[:packages].values.first
50
+ expect(pkg[:indication_codes]).to eq(item[:indication_codes])
51
+ end
52
+ end
53
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oddb2xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.5
4
+ version: 3.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yasuhiro Asaka, Zeno R.R. Davatz, Niklaus Giger
@@ -261,6 +261,20 @@ dependencies:
261
261
  - - ">="
262
262
  - !ruby/object:Gem::Version
263
263
  version: 3.3.9
264
+ - !ruby/object:Gem::Dependency
265
+ name: csv
266
+ requirement: !ruby/object:Gem::Requirement
267
+ requirements:
268
+ - - ">="
269
+ - !ruby/object:Gem::Version
270
+ version: '0'
271
+ type: :runtime
272
+ prerelease: false
273
+ version_requirements: !ruby/object:Gem::Requirement
274
+ requirements:
275
+ - - ">="
276
+ - !ruby/object:Gem::Version
277
+ version: '0'
264
278
  - !ruby/object:Gem::Dependency
265
279
  name: standardrb
266
280
  requirement: !ruby/object:Gem::Requirement
@@ -512,6 +526,7 @@ files:
512
526
  - spec/data/compressor/oddb2xml_files_lppv.txt
513
527
  - spec/data/compressor/oddb2xml_files_nonpharma.xls
514
528
  - spec/data/epha_interactions.csv
529
+ - spec/data/fhir/cyramza.ndjson
515
530
  - spec/data/listen_neu.html
516
531
  - spec/data/medregbm_betrieb.txt
517
532
  - spec/data/medregbm_person.txt
@@ -539,6 +554,7 @@ files:
539
554
  - spec/data_helper.rb
540
555
  - spec/downloader_spec.rb
541
556
  - spec/extractor_spec.rb
557
+ - spec/fhir_spec.rb
542
558
  - spec/fixtures/vcr_cassettes/artikelstamm.json
543
559
  - spec/fixtures/vcr_cassettes/oddb2xml.json
544
560
  - spec/galenic_spec.rb
@@ -607,6 +623,7 @@ test_files:
607
623
  - spec/data/compressor/oddb2xml_files_lppv.txt
608
624
  - spec/data/compressor/oddb2xml_files_nonpharma.xls
609
625
  - spec/data/epha_interactions.csv
626
+ - spec/data/fhir/cyramza.ndjson
610
627
  - spec/data/listen_neu.html
611
628
  - spec/data/medregbm_betrieb.txt
612
629
  - spec/data/medregbm_person.txt
@@ -634,6 +651,7 @@ test_files:
634
651
  - spec/data_helper.rb
635
652
  - spec/downloader_spec.rb
636
653
  - spec/extractor_spec.rb
654
+ - spec/fhir_spec.rb
637
655
  - spec/fixtures/vcr_cassettes/artikelstamm.json
638
656
  - spec/fixtures/vcr_cassettes/oddb2xml.json
639
657
  - spec/galenic_spec.rb