oddb2xml 3.0.2 → 3.0.4

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: 55725f8e11fa91216b5f7189f9339a6bacf6fd69af78c633421abc8c573a2326
4
- data.tar.gz: acd34c442ef756f43aeac9e2551df614fff4bad81894a87add521e4c7efab8cd
3
+ metadata.gz: 3a0a4cbd5ff288013064ffb6d756ed0961fd98e52b6960fbfd32b4328a039369
4
+ data.tar.gz: 60c9943c0a7f344ecf87e04f16314da1b8a29e0801a8d7e814d265932f89e443
5
5
  SHA512:
6
- metadata.gz: 273f80bb691ae1d0e86db41d9215456c48822f4a764163c3675d87ca6f975f11cd8d2dce89f4bf71abd9b8e320b61babd45c73d0683faafbeb25adf56f2d12b6
7
- data.tar.gz: c0014b66c15ebddcff17cf1435d24faab68ab856faa5d198208f94d9d6925540d4939ce4ff82f4f4d38c1fc319156dbaecf49415f56e8fce1d676d3e06b179fc
6
+ metadata.gz: 75abbcde0acf8e33b8489dd03fc06e6bd8796f571444b0a7f7eb3cded37a25f0938d8db07a7ef6ef0023412e3ab2336c046be3447fb5dc371dd02f06c5950e12
7
+ data.tar.gz: 9cf7e4c5eecd5d708dea61b4c6e17a206f6f4eaa65742ae2ee0c7ea3a49d0b4e4ae2dad7d9ffd3c2e61191e8703693ea29b3aa194d517226f828282ff5b3f891
data/CLAUDE.md CHANGED
@@ -37,9 +37,9 @@ The system follows a **download → extract → build → compress** pipeline:
37
37
 
38
38
  1. **CLI** (`lib/oddb2xml/cli.rb`) — Entry point. Parses options via Optimist (`options.rb`), orchestrates the pipeline, manages multi-threaded downloads.
39
39
 
40
- 2. **Downloaders** (`lib/oddb2xml/downloader.rb`) — 11 subclasses of `Downloader`, each fetching from a specific Swiss data source. Files cached in `./downloads/`.
40
+ 2. **Downloaders** — 11 subclasses of `Downloader`, each fetching from a specific Swiss data source. 10 live in `lib/oddb2xml/downloader.rb`; the FHIR downloader lives in `lib/oddb2xml/fhir_support.rb`. Files cached in `./downloads/`.
41
41
 
42
- 3. **Extractors** (`lib/oddb2xml/extractor.rb`) — Matching extractor classes that parse downloaded files into Ruby hashes. Formats include XML (nokogiri/sax-machine), XLSX (rubyXL), SOAP (savon), CSV, and fixed-width text.
42
+ 3. **Extractors** (`lib/oddb2xml/extractor.rb`) — Matching extractor classes that parse downloaded files into Ruby hashes. Formats include XML (nokogiri/sax-machine), XLSX (rubyXL), CSV, and fixed-width text. Refdata uses the new SwissReg XML format from a zip download (`files.refdata.ch`).
43
43
 
44
44
  4. **Builder** (`lib/oddb2xml/builder.rb`) — The largest file (~1900 lines). Merges extracted data and generates output XML/DAT files. Methods follow `prepare_*` (data assembly) and `build_*` (output generation) naming.
45
45
 
@@ -47,6 +47,8 @@ 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.
51
+
50
52
  ### Key data identifiers
51
53
  - **GTIN/EAN13**: Primary article identifier (13-digit barcode)
52
54
  - **Pharmacode**: Swiss pharmacy code
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oddb2xml (3.0.2)
4
+ oddb2xml (3.0.4)
5
5
  htmlentities
6
6
  httpi
7
7
  mechanize (>= 2.8.5)
data/History.txt CHANGED
@@ -1,7 +1,18 @@
1
+ === 3.0.4 / 24.04.2026
2
+ * 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
+
4
+ === 3.0.3 / 24.04.2026
5
+ * FHIR: download per-language NDJSON files (foph-sl-export-latest-{de,fr,it}.ndjson) so French and Italian product names/descriptions are populated
6
+ * FHIR: map legal status code 756005022008 to Swissmedic category D (in addition to 756005022007)
7
+
1
8
  === 3.0.2 / 09.03.2026
2
9
  * Use raw.githubusercontent.com URL for ATC CSV to avoid 429 Too Many Requests errors
3
10
  * Add retry logic with exponential backoff for HTTP 429 errors in uri_open
4
11
  * Remove obsolete Ruby version check in uri_open (Ruby >= 2.5 already required)
12
+ * Migrate Refdata from SOAP API to new SwissReg zip download (files.refdata.ch)
13
+ * Fix UTF-8 encoding for German umlauts in SORTD field (e.g. ö → Ö)
14
+ * Restore Italian description fallback to German when not available from Refdata
15
+ * Fix Optimist short option conflict for --fhir and --fhir_url options
5
16
 
6
17
  === 2.7.9 / 19.09.22
7
18
  * Remove newly generated DSCRI when not running --artikelstamm and
data/README.md CHANGED
@@ -25,7 +25,7 @@ creates .dat files according to ([IGM-11](http://dev.ywesee.com/uploads/att/IGM.
25
25
  * oddb.dat
26
26
  * oddb_with_migel.dat
27
27
 
28
- the files are using [swissINDEX](http://www.refdata.ch/downloads/company/download/swissindex_TechnischeBeschreibung.pdf), [BAG-XML](http://bag.e-mediat.net/SL2007.Web.External/Default.aspx?webgrab=ignore) and [Swissmedic](http://www.swissmedic.ch/daten/00080/00251/index.html?lang=de) as sources.
28
+ the files are using [Refdata](https://files.refdata.ch/simis-public-prod/Articles/1.0/Refdata.Articles.zip), [BAG-XML](http://bag.e-mediat.net/SL2007.Web.External/Default.aspx?webgrab=ignore) and [Swissmedic](http://www.swissmedic.ch/daten/00080/00251/index.html?lang=de) as sources.
29
29
 
30
30
  The following additional data is in the files:
31
31
 
@@ -51,7 +51,7 @@ HIN (http://hin.ch) creates daily the actual file. They can be downloaded from `
51
51
  see `--help`.
52
52
 
53
53
  ```
54
- /opt/src/oddb2xml_v5/bin/oddb2xml version 2.4.3
54
+ /opt/src/oddb2xml/bin/oddb2xml version 3.0.4
55
55
  Usage:
56
56
  oddb2xml [option]
57
57
  produced files are found under data
@@ -61,6 +61,10 @@ see `--help`.
61
61
  -e, --extended pharma, non-pharma plus prices and non-pharma from zurrose.
62
62
  Products without EAN-Code will also be listed.
63
63
  File oddb_calc.xml will also be generated
64
+ --fhir Use FHIR NDJSON format from FOPH/BAG instead of XML
65
+ from Spezialitätenliste. Downloads per-language
66
+ NDJSON files (de, fr, it) from epl.bag.admin.ch.
67
+ --fhir-url=<s> Specific FHIR NDJSON URL to download (implies --fhir)
64
68
  -f, --format=<s> File format F, default is xml. {xml|dat}
65
69
  If F is given, -o option is ignored. (Default: xml)
66
70
  -i, --include Include target option for ean14 for 'dat' format.
@@ -80,6 +84,8 @@ see `--help`.
80
84
  Downloaded files are saved under downloads
81
85
  --log log important actions
82
86
  -u, --use-ra11zip=<s> Use the ra11.zip (a zipped transfer.dat from Galexis)
87
+ -b, --firstbase Build all NONPHARMA articles on firstbase
88
+ (GS1 Switzerland CSV from id.gs1.ch)
83
89
  -v, --version Print version and exit
84
90
  -h, --help Show this message
85
91
  ```
@@ -106,8 +112,8 @@ FR
106
112
 
107
113
  ## Supported ruby version
108
114
 
109
- We run tests on travis-ci.org for the Ruby versions mentioned in the .travis.yml file. You will need ruby > 2.5 to work correctly.
110
- Look at the github actions to see the spec test results. We ignore errors against ruby head, as it is sometimes unstable.
115
+ You will need ruby >= 2.5 to work correctly. Current development happens on Ruby 3.2 (`.ruby-version`).
116
+ CI runs on Ruby 3.0, 3.1 and 3.2 via GitHub Actions see the badge above for the latest spec results.
111
117
 
112
118
 
113
119
  ## XSD files
@@ -274,17 +280,17 @@ We use the following files:
274
280
 
275
281
  * https://www.swissmedic.ch/arzneimittel/00156/00221/00222/00230/index.html?lang=de (Präparateliste und zugelassene Packungen)
276
282
  * https://raw.githubusercontent.com/zdavatz/oddb2xml_files/master/interactions_de_utf8.csv
277
- * http://refdatabase.refdata.ch/Service/Article.asmx
283
+ * https://files.refdata.ch/simis-public-prod/Articles/1.0/Refdata.Articles.zip
278
284
  * http://bag.e-mediat.net/SL2007.Web.External/File.axd?file=XMLPublications.zip
279
285
  * https://www.medregbm.admin.ch/Publikation/CreateExcelListBetriebs
280
286
  * https://www.medregbm.admin.ch/Publikation/CreateExcelListMedizinalPersons
281
287
  * http://zurrose.com/fileadmin/main/lib/download.php?file=/fileadmin/user_upload/downloads/ProduktUpdate/IGM11_mit_MwSt/Vollstamm/transfer.dat
282
- * https://index.ws.e-mediat.net/Swissindex/NonPharma/ws_NonPharma_V101.asmx
283
- * https://index.ws.e-mediat.net/Swissindex/NonPharma/ws_Pharma_V101.asmx
288
+ * https://raw.githubusercontent.com/zdavatz/oddb2xml_files/master/NON-Pharma.xls
284
289
  * http://download.swissmedicinfo.ch/ (AipsDownload)
285
290
  * https://raw.githubusercontent.com/zdavatz/oddb2xml_files/master/LPPV.txt
286
- * https://raw.githubusercontent.com/epha/robot/master/data/manual/swissmedic/atc.csv
287
291
  * https://raw.githubusercontent.com/zdavatz/cpp2sqlite/master/input/atc_codes_multi_lingual.txt
292
+ * https://epl.bag.admin.ch/static/fhir/foph-sl-export-latest-{de,fr,it}.ndjson (FHIR NDJSON, used with `--fhir`)
293
+ * https://id.gs1.ch/01/07612345000961 (GS1 Switzerland firstbase CSV — full barcode registry, used with `-b`/`--firstbase`)
288
294
 
289
295
  ## Rules for matching GTIN (aka EAN13), product number and IKSNR
290
296
 
data/lib/oddb2xml/cli.rb CHANGED
@@ -285,10 +285,15 @@ module Oddb2xml
285
285
  # instead of Thread.new do
286
286
 
287
287
  downloader = FhirDownloader.new(@options)
288
- fhir_file = downloader.download
289
- Oddb2xml.log("FhirDownloader downloaded #{File.size(fhir_file)} bytes")
288
+ fhir_files = downloader.download
289
+ total_bytes = if fhir_files.is_a?(Hash)
290
+ fhir_files.values.sum { |f| File.size(f) }
291
+ else
292
+ File.size(fhir_files)
293
+ end
294
+ Oddb2xml.log("FhirDownloader downloaded #{total_bytes} bytes")
290
295
  @mutex.synchronize do
291
- hsh = FhirExtractor.new(fhir_file).to_hash
296
+ hsh = FhirExtractor.new(fhir_files).to_hash
292
297
  @items = hsh
293
298
  Oddb2xml.log("FhirExtractor added #{@items.size} items from FHIR")
294
299
  @items
@@ -135,6 +135,7 @@ module Oddb2xml
135
135
  end
136
136
  end
137
137
  end
138
+ xml.force_encoding("UTF-8") if xml.encoding.name != "UTF-8"
138
139
  xml
139
140
  end
140
141
  end
@@ -248,13 +249,7 @@ module Oddb2xml
248
249
  end
249
250
 
250
251
  def init
251
- config = {
252
- log_level: :info,
253
- log: false, # $stdout
254
- raise_errors: true,
255
- wsdl: @url
256
- }
257
- @client = Savon::Client.new(config)
252
+ # No SOAP client needed - we download a zip file directly
258
253
  end
259
254
 
260
255
  def download
@@ -347,14 +342,14 @@ module Oddb2xml
347
342
  end
348
343
 
349
344
  class FirstbaseDownloader < Downloader
350
- BASE_URL = "http://pillbox.oddb.org"
345
+ BASE_URL = "https://id.gs1.ch/01/07612345000961"
351
346
  include DownloadMethod
352
347
  def initialize(type = :orphan, options = {})
353
- @url = BASE_URL + "/firstbase.xlsx"
348
+ @url = BASE_URL
354
349
  end
355
350
 
356
351
  def download
357
- @file2save = File.join(DOWNLOADS, "firstbase.xlsx")
352
+ @file2save = File.join(DOWNLOADS, "firstbase.csv")
358
353
  report_download(@url, @file2save)
359
354
  begin
360
355
  download_as(@file2save, "w+")
@@ -202,7 +202,8 @@ module Oddb2xml
202
202
 
203
203
  class RefdataExtractor < Extractor
204
204
  def initialize(xml, type)
205
- @type = (type == :pharma ? "PHARMA" : "NONPHARMA")
205
+ @type = (type.to_s.upcase == "PHARMA" ? "PHARMA" : "NONPHARMA")
206
+ xml = xml.dup.force_encoding("UTF-8") if xml.encoding.name != "UTF-8"
206
207
  super(xml)
207
208
  end
208
209
 
@@ -242,6 +243,7 @@ module Oddb2xml
242
243
  item[:desc_it] = name.FullName
243
244
  end
244
245
  end
246
+ item[:desc_it] = item[:desc_de] if item[:desc_it].empty? # refdata has no italian name
245
247
  item[:atc_code] = article.MedicinalProduct.ProductClassification.Atc || ""
246
248
  item[:company_name] = article.PackagedProduct.Holder.Name || ""
247
249
  item[:company_ean] = article.PackagedProduct.Holder.Identifier || ""
@@ -606,32 +608,28 @@ module Oddb2xml
606
608
 
607
609
  class FirstbaseExtractor < Extractor
608
610
  def initialize(file)
609
- @sheet = RubyXL::Parser.parse(file).worksheets[0]
611
+ @file = file
610
612
  end
611
613
 
612
614
  def to_hash
613
615
  data = {}
614
- return data unless @sheet
615
- @sheet.each_with_index do |row, i|
616
- next if i <= 1
617
- if row.nil?
618
- puts "Empty row (#{i}) in firstbase"
619
- next
620
- end
621
- gtin = row[0].value.to_s.gsub(/^0+/, '')
616
+ return data unless @file && File.exist?(@file)
617
+ CSV.foreach(@file, headers: true, encoding: "UTF-8") do |row|
618
+ gtin = row["Gtin"].to_s.gsub(/^0+/, "")
619
+ next if gtin.empty?
622
620
  data[gtin] = {
623
621
  gtin: gtin,
624
- gln: row[1].value.to_s,
625
- target_market: row[2] ? row[2].value.to_s: "",
626
- gpc: row[3] ? row[3].value.to_s: "",
627
- trade_item_description_de: row[4] ? row[4].value.to_s: "",
628
- trade_item_description_en: row[5] ? row[5].value.to_s: "",
629
- trade_item_description_fr: row[6] ? row[6].value.to_s: "",
630
- trade_item_description_it: row[7] ? row[7].value.to_s: "",
631
- manufacturer_name: row[8] ? row[8].value.to_s: "",
632
- start_availability_date: row[9] ? row[9].value.to_s: "",
633
- gross_weight: row[10] ? row[10].value.to_s: "",
634
- net_weight: row[11] ? row[11].value.to_s: "",
622
+ gln: row["InformationProviderGln"].to_s,
623
+ target_market: row["TargetMarketCountryCode"].to_s,
624
+ gpc: row["GpcCategoryCode"].to_s,
625
+ trade_item_description_de: row["TradeItemDescription_DE"].to_s,
626
+ trade_item_description_en: "",
627
+ trade_item_description_fr: row["TradeItemDescription_FR"].to_s,
628
+ trade_item_description_it: row["TradeItemDescription_IT"].to_s,
629
+ manufacturer_name: row["InformationProviderPartyName"].to_s,
630
+ start_availability_date: row["Date_Created_Batch"].to_s,
631
+ gross_weight: "",
632
+ net_weight: "",
635
633
  }
636
634
  end
637
635
  data
@@ -15,62 +15,69 @@ module Oddb2xml
15
15
 
16
16
  BASE_URL = "https://epl.bag.admin.ch"
17
17
  STATIC_FHIR_PATH = "/static/fhir"
18
+ LANGUAGES = %w[de fr it].freeze
18
19
 
19
20
  def initialize(options = {})
20
21
  @options = options
21
- @url = find_latest_fhir_url
22
- super(options, @url)
22
+ super(options, BASE_URL)
23
23
  end
24
24
 
25
+ # Returns either a single file path String (when --fhir_url is used) or a
26
+ # Hash of { "de" => path, "fr" => path, "it" => path } for per-language
27
+ # NDJSON files.
25
28
  def download
26
- filename = File.basename(@url)
29
+ if @options[:fhir_url]
30
+ @url = @options[:fhir_url]
31
+ download_one(@url)
32
+ else
33
+ files = {}
34
+ LANGUAGES.each do |lang|
35
+ url = "#{BASE_URL}#{STATIC_FHIR_PATH}/foph-sl-export-latest-#{lang}.ndjson"
36
+ path = download_one(url)
37
+ files[lang] = path if path
38
+ end
39
+ raise "FhirDownloader: no FHIR files downloaded successfully" if files.empty?
40
+ files
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def download_one(url)
47
+ @url = url
48
+ filename = File.basename(url)
27
49
  file = File.join(WORK_DIR, filename)
28
50
  @file2save = File.join(DOWNLOADS, filename)
29
51
 
30
- report_download(@url, @file2save)
52
+ report_download(url, @file2save)
31
53
 
32
- # Check if we should skip download (file exists and is recent)
33
54
  if skip_download?
34
55
  Oddb2xml.log "FhirDownloader: Skip downloading #{@file2save} (#{format_size(File.size(@file2save))}, less than 24h old)"
35
56
  return File.expand_path(@file2save)
36
57
  end
37
58
 
38
59
  begin
39
- # Download the file
40
60
  download_as(file, "w+")
41
61
 
42
- # Validate NDJSON format
43
62
  if validate_ndjson(@file2save)
44
63
  line_count = count_ndjson_lines(@file2save)
45
- Oddb2xml.log "FhirDownloader: NDJSON validation successful (#{line_count} bundles, #{format_size(File.size(@file2save))})"
64
+ Oddb2xml.log "FhirDownloader: NDJSON validation successful for #{filename} (#{line_count} bundles, #{format_size(File.size(@file2save))})"
46
65
  else
47
- Oddb2xml.log "FhirDownloader: WARNING - NDJSON validation failed!"
66
+ Oddb2xml.log "FhirDownloader: WARNING - NDJSON validation failed for #{filename}!"
48
67
  end
49
68
 
50
69
  File.expand_path(@file2save)
51
70
  rescue Timeout::Error, Errno::ETIMEDOUT
52
71
  retrievable? ? retry : raise
53
72
  rescue => error
54
- Oddb2xml.log "FhirDownloader: Error downloading FHIR file: #{error.message}"
55
- raise
73
+ Oddb2xml.log "FhirDownloader: Error downloading #{filename}: #{error.message}"
74
+ nil
56
75
  ensure
57
76
  Oddb2xml.download_finished(@file2save, false)
58
77
  FileUtils.rm_f(file, verbose: true) if File.exist?(file) && file != @file2save
59
78
  end
60
79
  end
61
80
 
62
- private
63
-
64
- def find_latest_fhir_url
65
- agent = Mechanize.new
66
- response = agent.get "https://epl.bag.admin.ch/api/sl/public/resources/current"
67
- resources = JSON.parse(response.body)
68
- "https://epl.bag.admin.ch/static/" + resources["fhir"]["fileUrl"]
69
- rescue => e
70
- Oddb2xml.log "FhirDownloader: Error finding latest URL: #{e.message}"
71
- nil
72
- end
73
-
74
81
  def skip_download?
75
82
  @options[:skip_download] || (File.exist?(@file2save) && file_age_hours(@file2save) < 24)
76
83
  end
@@ -552,7 +559,7 @@ module Oddb2xml
552
559
  "B"
553
560
  when "756005022005"
554
561
  "C"
555
- when "756005022007"
562
+ when "756005022007", "756005022008"
556
563
  "D"
557
564
  when "756005022009"
558
565
  "E"
@@ -565,8 +572,16 @@ module Oddb2xml
565
572
 
566
573
  # FHIR Extractor - Compatible with existing BagXmlExtractor
567
574
  class FhirExtractor < Extractor
568
- def initialize(fhir_file)
569
- @fhir_file = fhir_file
575
+ # Accepts either a single NDJSON file path (back-compat) or a Hash
576
+ # { "de" => path, "fr" => path, "it" => path } of per-language files.
577
+ def initialize(fhir_files)
578
+ if fhir_files.is_a?(Hash)
579
+ @fhir_files = fhir_files
580
+ @fhir_file = fhir_files["de"] || fhir_files.values.first
581
+ else
582
+ @fhir_files = {"de" => fhir_files}
583
+ @fhir_file = fhir_files
584
+ end
570
585
  end
571
586
 
572
587
  def to_hash
@@ -712,9 +727,54 @@ module Oddb2xml
712
727
  end
713
728
  end
714
729
 
730
+ # Merge names/descriptions from additional language files
731
+ @fhir_files.each do |lang, file|
732
+ next if file == @fhir_file
733
+ next unless file && File.exist?(file)
734
+ merge_language(data, file, lang)
735
+ end
736
+
715
737
  Oddb2xml.log "FhirExtractor: Extracted #{data.size} packages"
716
738
  data
717
739
  end
740
+
741
+ private
742
+
743
+ def merge_language(data, file, lang)
744
+ Oddb2xml.log "FhirExtractor: Merging #{lang} names/descriptions from #{file}"
745
+ result = FhirPreparationsEntry.parse(file)
746
+ name_accessor = "Name#{lang.capitalize}"
747
+ name_key = "name_#{lang}".to_sym
748
+ desc_key = "desc_#{lang}".to_sym
749
+
750
+ result.Preparations.Preparation.each do |seq|
751
+ next unless seq && seq.Packs && seq.Packs.Pack
752
+
753
+ translated_name = seq.respond_to?(name_accessor) ? seq.send(name_accessor) : nil
754
+
755
+ seq.Packs.Pack.each do |pac|
756
+ next unless pac.GTIN
757
+ ean13 = pac.GTIN.to_s
758
+ item = data[ean13]
759
+ next unless item
760
+
761
+ if translated_name && !translated_name.empty?
762
+ item[name_key] = translated_name
763
+ if item[:packages][ean13]
764
+ item[:packages][ean13][name_key] = translated_name
765
+ end
766
+ end
767
+
768
+ # The FHIR parser assigns pkg.description to all three
769
+ # Description* fields; in a language-specific file this is the
770
+ # description in that language.
771
+ desc = pac.DescriptionDe
772
+ if desc && !desc.empty? && item[:packages][ean13]
773
+ item[:packages][ean13][desc_key] = desc
774
+ end
775
+ end
776
+ end
777
+ end
718
778
  end
719
779
  end
720
780
 
@@ -22,8 +22,8 @@ module Oddb2xml
22
22
  opt :extended, "pharma, non-pharma plus prices and non-pharma from zurrose.
23
23
  Products without EAN-Code will also be listed.
24
24
  File oddb_calc.xml will also be generated"
25
- opt :fhir, "Use FHIR NDJSON format from FOPH/BAG instead of XML from Spezialitätenliste", default: false
26
- opt :fhir_url, "Specific FHIR NDJSON URL to download (implies --fhir)", type: :string, default: nil
25
+ opt :fhir, "Use FHIR NDJSON format from FOPH/BAG instead of XML from Spezialitätenliste", default: false, short: :none
26
+ opt :fhir_url, "Specific FHIR NDJSON URL to download (implies --fhir)", type: :string, default: nil, short: :none
27
27
  opt :format, "File format F, default is xml. {xml|dat}
28
28
  If F is given, -o option is ignored.", type: :string, default: "xml"
29
29
  opt :include, "Include target option for ean14 for 'dat' format.
@@ -45,7 +45,7 @@ module Oddb2xml
45
45
  opt :log, "log important actions", short: :none
46
46
  opt :use_ra11zip, "Use the ra11.zip (a zipped transfer.dat from Galexis)",
47
47
  default: File.exist?("ra11.zip") ? "ra11.zip" : nil, type: :string
48
- opt :firstbase, "Build all NONPHARMA articles on firstbase", short: "b", default: false
48
+ opt :firstbase, "Build all NONPHARMA articles on firstbase (GS1 Switzerland CSV from id.gs1.ch)", short: "b", default: false
49
49
  end
50
50
 
51
51
  @opts[:percent] = @opts[:increment]
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "3.0.2"
2
+ VERSION = "3.0.4"
3
3
  end
data/spec/builder_spec.rb CHANGED
@@ -10,7 +10,7 @@ ARTICLE_ATTRIBUTE_TESTS = [
10
10
  ["ARTICLE", "PROD_DATE", Oddb2xml::DATE_REGEXP],
11
11
  ["ARTICLE", "VALID_DATE", Oddb2xml::DATE_REGEXP],
12
12
  ["ARTICLE/ART", "SHA256", /[a-f0-9]{32}/],
13
- ["ARTICLE/ART", "DT", /\d{4}-\d{2}-\d{2}/]
13
+ ["ARTICLE/ART", "DT", //]
14
14
  ]
15
15
 
16
16
  ARTICLE_MISSING_ELEMENTS = [