oddb2xml 2.7.1 → 2.7.2

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.standard.yml +2 -0
  4. data/Gemfile +3 -3
  5. data/History.txt +8 -0
  6. data/README.md +1 -1
  7. data/Rakefile +24 -23
  8. data/bin/check_artikelstamm +11 -11
  9. data/bin/compare_v5 +23 -23
  10. data/bin/oddb2xml +14 -13
  11. data/lib/oddb2xml.rb +1 -1
  12. data/lib/oddb2xml/builder.rb +1070 -1038
  13. data/lib/oddb2xml/calc.rb +232 -233
  14. data/lib/oddb2xml/chapter_70_hack.rb +38 -32
  15. data/lib/oddb2xml/cli.rb +252 -236
  16. data/lib/oddb2xml/compare.rb +70 -59
  17. data/lib/oddb2xml/compositions_syntax.rb +448 -430
  18. data/lib/oddb2xml/compressor.rb +20 -20
  19. data/lib/oddb2xml/downloader.rb +153 -127
  20. data/lib/oddb2xml/extractor.rb +302 -289
  21. data/lib/oddb2xml/options.rb +34 -35
  22. data/lib/oddb2xml/parslet_compositions.rb +263 -269
  23. data/lib/oddb2xml/semantic_check.rb +39 -33
  24. data/lib/oddb2xml/util.rb +163 -163
  25. data/lib/oddb2xml/version.rb +1 -1
  26. data/lib/oddb2xml/xml_definitions.rb +32 -33
  27. data/oddb2xml.gemspec +31 -32
  28. data/spec/artikelstamm_spec.rb +111 -110
  29. data/spec/builder_spec.rb +489 -505
  30. data/spec/calc_spec.rb +552 -593
  31. data/spec/check_artikelstamm_spec.rb +26 -26
  32. data/spec/cli_spec.rb +173 -174
  33. data/spec/compare_spec.rb +9 -11
  34. data/spec/composition_syntax_spec.rb +390 -409
  35. data/spec/compressor_spec.rb +48 -48
  36. data/spec/data/transfer.dat +1 -0
  37. data/spec/data_helper.rb +47 -49
  38. data/spec/downloader_spec.rb +247 -260
  39. data/spec/extractor_spec.rb +171 -159
  40. data/spec/galenic_spec.rb +233 -256
  41. data/spec/options_spec.rb +116 -119
  42. data/spec/parslet_spec.rb +833 -861
  43. data/spec/spec_helper.rb +154 -153
  44. data/test_options.rb +39 -42
  45. data/tools/win_fetch_cacerts.rb +2 -3
  46. metadata +19 -3
@@ -1,41 +1,45 @@
1
- # encoding: utf-8
2
- require 'ox'
1
+ require "ox"
3
2
 
4
3
  module Oddb2xml
5
4
  def self.log_timestamp(msg)
6
5
  full_msg = "#{Time.now.strftime("%H:%M:%S")}: #{msg}"
7
6
  puts full_msg
8
- STDOUT.flush
7
+ $stdout.flush
9
8
  full_msg
10
9
  end
10
+
11
11
  class SemanticCheckXML
12
12
  attr_accessor :components
13
13
  attr_reader :keys, :sub_key_names, :filename, :basename, :version, :hash
14
- def initialize(filename, components = ["PRODUCTS", "LIMITATIONS", "ITEMS",])
14
+ def initialize(filename, components = ["PRODUCTS", "LIMITATIONS", "ITEMS"])
15
15
  raise "File #{filename} must exist" unless File.exist?(filename)
16
16
  @filename = filename
17
17
  @basename = File.basename(filename)
18
18
  @components = components
19
19
  @hash = load_file(@filename)
20
20
  end
21
+
21
22
  def self.get_component_key_name(component_name)
22
- return 'LIMNAMEBAG' if /LIMITATION/i.match(component_name)
23
- return 'PRODNO' if /PRODUCT/i.match(component_name)
24
- return 'GTIN' if /ITEM/i.match(component_name)
25
- raise "Cannot determine keyname for component #{component_name}"
23
+ return "LIMNAMEBAG" if /LIMITATION/i.match?(component_name)
24
+ return "PRODNO" if /PRODUCT/i.match?(component_name)
25
+ return "GTIN" if /ITEM/i.match?(component_name)
26
+ raise "Cannot determine keyname for component #{component_name}"
26
27
  end
28
+
27
29
  def get_items(component_name)
28
30
  # hack to make it spec/check_artikelstamm.rb work if called alone or as part
29
31
  # of the whole spec suite
30
- xx= @hash[:ARTIKELSTAMM] ||@hash['ARTIKELSTAMM']
32
+ xx = @hash[:ARTIKELSTAMM] || @hash["ARTIKELSTAMM"]
31
33
  comps = xx[component_name.to_sym] || xx[component_name]
32
34
  comps.values.first
33
35
  end
36
+
34
37
  def load_file(name)
35
- Oddb2xml.log_timestamp "Reading #{name} #{(File.size(name)/1024/1024).to_i} MB. This may take some time"
38
+ Oddb2xml.log_timestamp "Reading #{name} #{(File.size(name) / 1024 / 1024).to_i} MB. This may take some time"
36
39
  Ox.load(IO.read(name), mode: :hash_no_attrs)
37
40
  end
38
41
  end
42
+
39
43
  class SemanticCheck
40
44
  attr_accessor :items, :products, :limitations
41
45
  def initialize(filename)
@@ -45,20 +49,20 @@ module Oddb2xml
45
49
 
46
50
  def everyProductNumberIsUnique
47
51
  puts "#{Time.now.strftime("%H:%M:%S")}: everyProductNumberIsUnique"
48
- return false unless products.size > 0
49
- return products.collect{ |x| x[:PRODNO]}.uniq.size == products.size
52
+ return false unless products.size > 0
53
+ products.collect { |x| x[:PRODNO] }.uniq.size == products.size
50
54
  end
51
55
 
52
56
  def everyGTINIsUnique
53
57
  puts "#{Time.now.strftime("%H:%M:%S")}: everyGTINIsUnique"
54
- return false unless items.size > 0
55
- return items.collect{ |x| x[:GTIN]}.uniq.size == items.size
58
+ return false unless items.size > 0
59
+ items.collect { |x| x[:GTIN] }.uniq.size == items.size
56
60
  end
57
61
 
58
62
  def everyGTINIsNumericOnly
59
63
  puts "#{Time.now.strftime("%H:%M:%S")}: everyGTINIsNumericOnly"
60
64
  items.each do |item|
61
- unless /^[0-9]+$/i.match(item[:GTIN])
65
+ unless /^[0-9]+$/i.match?(item[:GTIN])
62
66
  puts "GTIN is not Numeric Only"
63
67
  return false
64
68
  end
@@ -68,13 +72,15 @@ module Oddb2xml
68
72
  def everyPharmaArticleHasAProductItem
69
73
  result = true
70
74
  puts "#{Time.now.strftime("%H:%M:%S")}: everyPharmaArticleHasAProductItem"
71
- allProductNumbers = products.collect{ |product| product[:PRODNO] }
75
+ all_product_numbers = products.collect { |product| product[:PRODNO] }
72
76
  items.each do |item|
73
77
  next unless item[:PRODNO]
74
- unless allProductNumbers.index(item[:PRODNO])
75
- puts "Item #{item[:GTIN]} has no Product #{item[:PRODNO]} #{item[:DSCR]}"
76
- result = false
77
- end unless item[:Chapter70_HACK]
78
+ unless item[:Chapter70_HACK]
79
+ unless all_product_numbers.index(item[:PRODNO])
80
+ puts "Item #{item[:GTIN]} has no Product #{item[:PRODNO]} #{item[:DSCR]}"
81
+ result = false
82
+ end
83
+ end
78
84
  end
79
85
  result
80
86
  end
@@ -82,9 +88,9 @@ module Oddb2xml
82
88
  def everyProductHasAtLeastOneArticle
83
89
  result = true
84
90
  puts "#{Time.now.strftime("%H:%M:%S")}: veryProductHasAtLeastOneArticle"
85
- allProductNumbers = items.collect{ |item| item[:PRODNO] }
91
+ all_product_numbers = items.collect { |item| item[:PRODNO] }
86
92
  products.each do |product|
87
- unless allProductNumbers.index(product[:PRODNO])
93
+ unless all_product_numbers.index(product[:PRODNO])
88
94
  puts "product #{product[:PRODNO]}: has no Item #{product[:DSCR]}"
89
95
  result = false
90
96
  end
@@ -95,10 +101,10 @@ module Oddb2xml
95
101
  def everyReferencedLimitationIsIncluded
96
102
  result = true
97
103
  puts "#{Time.now.strftime("%H:%M:%S")}: everyReferencedLimitationIsIncluded"
98
- allLimitations = limitations.collect{ |lim| lim[:LIMNAMEBAG] }
104
+ all_limitations = limitations.collect { |lim| lim[:LIMNAMEBAG] }
99
105
  products.each do |product|
100
106
  next unless product[:LIMNAMEBAG]
101
- unless allLimitations.index(product[:LIMNAMEBAG])
107
+ unless all_limitations.index(product[:LIMNAMEBAG])
102
108
  puts "product #{product[:PRODNO]} has no limitation #{product[:LIMNAMEBAG]} #{product[:DSCR]}"
103
109
  result = false
104
110
  end
@@ -109,30 +115,30 @@ module Oddb2xml
109
115
  def checkPackageSize
110
116
  puts "#{Time.now.strftime("%H:%M:%S")}: checkPackageSize"
111
117
  items.each do |item|
112
- if item['PKG_SIZE'] && item['PKG_SIZE'].length >= 6
113
- puts "WARNING possibly invalid package size #{item['PKG_SIZE']}"
118
+ if item["PKG_SIZE"] && item["PKG_SIZE"].length >= 6
119
+ puts "WARNING possibly invalid package size #{item["PKG_SIZE"]}"
114
120
  pp item
115
121
  end
116
122
  end
117
123
  end
118
124
 
119
125
  def allSemanticChecks
120
- @limitations = @stammdaten.get_items('LIMITATIONS')
121
- @items = @stammdaten.get_items('ITEMS')
122
- @products = @stammdaten.get_items('PRODUCTS')
126
+ @limitations = @stammdaten.get_items("LIMITATIONS")
127
+ @items = @stammdaten.get_items("ITEMS")
128
+ @products = @stammdaten.get_items("PRODUCTS")
123
129
  puts "#{Time.now.strftime("%H:%M:%S")}: Running all semantic checks for #{@stammdaten.filename} for #{products.size} products and #{items.size} items"
124
- unless everyProductNumberIsUnique &&
130
+ if everyProductNumberIsUnique &&
125
131
  everyGTINIsUnique &&
126
132
  everyGTINIsNumericOnly &&
127
133
  everyPharmaArticleHasAProductItem &&
128
134
  everyProductHasAtLeastOneArticle &&
129
135
  everyReferencedLimitationIsIncluded &&
130
136
  checkPackageSize
131
- puts "#{Time.now.strftime("%H:%M:%S")}: Checking #{@stammdaten.filename} failed"
132
- false
133
- else
134
137
  puts "#{Time.now.strftime("%H:%M:%S")}: Everything is okay"
135
138
  true
139
+ else
140
+ puts "#{Time.now.strftime("%H:%M:%S")}: Checking #{@stammdaten.filename} failed"
141
+ false
136
142
  end
137
143
  rescue => error
138
144
  puts "Execution failed with #{error}"
data/lib/oddb2xml/util.rb CHANGED
@@ -1,237 +1,233 @@
1
- # encoding: utf-8
2
- require 'open-uri'
3
- require 'htmlentities'
1
+ require "open-uri"
2
+ require "htmlentities"
4
3
 
5
4
  module Oddb2xml
6
- FAKE_GTIN_START = '999999'
7
- def Oddb2xml.gen_prodno(iksnr, seqnr)
8
- sprintf('%05d',iksnr) + sprintf('%02d', seqnr)
5
+ FAKE_GTIN_START = "999999"
6
+ def self.gen_prodno(iksnr, seqnr)
7
+ sprintf("%05d", iksnr) + sprintf("%02d", seqnr)
9
8
  end
10
- def Oddb2xml.uri_open(url)
11
- version = RUBY_VERSION.split('.').map { |x| x.to_i }
12
- if (version <=> [2,5,0]) >= 0
13
- URI.open(url)
9
+
10
+ def self.uri_open(url)
11
+ version = RUBY_VERSION.split(".").map { |x| x.to_i }
12
+ if (version <=> [2, 5, 0]) >= 0
13
+ URI.parse(url).open
14
14
  else
15
- open(url)
15
+ IO.popen(url)
16
16
  end
17
17
  end
18
- def Oddb2xml.calc_checksum(str)
18
+
19
+ def self.calc_checksum(str)
19
20
  str = str.strip
20
21
  sum = 0
21
- val = str.split(//u)
22
+ val = str.split(//u)
22
23
  12.times do |idx|
23
- fct = ((idx%2)*2)+1
24
- sum += fct*val[idx].to_i
24
+ fct = ((idx % 2) * 2) + 1
25
+ sum += fct * val[idx].to_i
25
26
  end
26
- ((10-(sum%10))%10).to_s
27
+ ((10 - (sum % 10)) % 10).to_s
27
28
  end
28
29
 
29
30
  unless defined?(RSpec)
30
- WorkDir = Dir.pwd
31
- Downloads = "#{Dir.pwd}/downloads"
31
+ WORK_DIR = Dir.pwd
32
+ DOWNLOADS = "#{Dir.pwd}/downloads"
32
33
  end
33
34
  @options = {}
34
- @atc_csv_origin = 'https://github.com/zdavatz/cpp2sqlite/blob/master/input/atc_codes_multi_lingual.txt'
35
+ @atc_csv_origin = "https://github.com/zdavatz/cpp2sqlite/blob/master/input/atc_codes_multi_lingual.txt"
35
36
  @atc_csv_content = {}
36
37
 
37
- def Oddb2xml.html_decode(string)
38
+ def self.html_decode(string)
38
39
  german = string
39
- german = string.force_encoding('ISO-8859-1').encode('UTF-8') if string.encoding.to_s.eql?('ASCII')
40
- while !german.eql?(HTMLEntities.new.decode(german))
40
+ german = string.force_encoding("ISO-8859-1").encode("UTF-8") if string.encoding.to_s.eql?("ASCII")
41
+ until german.eql?(HTMLEntities.new.decode(german))
41
42
  german = HTMLEntities.new.decode(german)
42
43
  end
43
- Oddb2xml.patch_some_utf8(german).gsub('<br>',"\n")
44
+ Oddb2xml.patch_some_utf8(german).gsub("<br>", "\n")
44
45
  end
45
46
 
46
- def Oddb2xml.patch_some_utf8(line)
47
+ def self.patch_some_utf8(line)
47
48
  begin
48
- line = line.encode('utf-8')
49
- rescue => error
49
+ line = line.encode("utf-8")
50
+ rescue
50
51
  end
51
52
  begin
52
- line.gsub("\u0089", "‰").gsub("\u0092", '').gsub("\u0096", '-').gsub("\u2013",'-').gsub("\u201D", '"').chomp
53
+ line.tr("\u0089", "‰").tr("\u0092", "").tr("\u0096", "-").tr("\u2013", "-").tr("\u201D", '"').chomp
53
54
  rescue => error
54
55
  puts "#{error}: in #{line}"
55
56
  line
56
57
  end
57
58
  end
58
59
 
59
- def Oddb2xml.convert_to_8859_1(line)
60
- begin
61
- # We want to ignore lines which are not really UTF-8 encoded
62
- ausgabe = Oddb2xml.patch_some_utf8(line).encode('ISO-8859-1')
63
- ausgabe.encode('ISO-8859-1')
64
- rescue => error
65
- puts "#{error}: in #{line}"
66
- end
60
+ def self.convert_to_8859_1(line)
61
+ # We want to ignore lines which are not really UTF-8 encoded
62
+ ausgabe = Oddb2xml.patch_some_utf8(line).encode("ISO-8859-1")
63
+ ausgabe.encode("ISO-8859-1")
64
+ rescue => error
65
+ puts "#{error}: in #{line}"
67
66
  end
68
67
 
69
- def Oddb2xml.add_epha_changes_for_ATC(iksnr, atc_code, force_run: false)
70
- @atc_csv_content = {} if force_run
68
+ def self.add_epha_changes_for_ATC(iksnr, atc_code, force_run: false)
69
+ @atc_csv_content = {} if force_run
71
70
  if @atc_csv_content.size == 0
72
- Oddb2xml.uri_open(@atc_csv_origin).readlines.each{
73
- |line|
74
- items = line.split(',')
75
- @atc_csv_content[[items[0], items[1]]] = items[2]
71
+ Oddb2xml.uri_open(@atc_csv_origin).readlines.each { |line|
72
+ items = line.split(",")
73
+ @atc_csv_content[[items[0], items[1]]] = items[2]
76
74
  }
77
75
 
78
76
  end
79
77
  new_value = @atc_csv_content[[iksnr.to_s, atc_code]]
80
- new_value ? new_value : atc_code
78
+ new_value || atc_code
81
79
  end
82
80
 
83
- def Oddb2xml.log(msg)
81
+ def self.log(msg)
84
82
  return unless @options[:log]
85
83
  # TODO:: require 'pry'; binding.pry if msg.size > 1000
86
84
  $stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}: #{msg[0..250]}"
87
85
  $stdout.flush
88
86
  end
89
87
 
90
- def Oddb2xml.save_options(options)
88
+ def self.save_options(options)
91
89
  @options = options
92
90
  end
93
91
 
94
- def Oddb2xml.skip_download?
92
+ def self.skip_download?
95
93
  @options[:skip_download]
96
94
  end
97
95
 
98
- def Oddb2xml.skip_download(file)
96
+ def self.skip_download(file)
99
97
  return false if defined?(VCR)
100
- dest = "#{Downloads}/#{File.basename(file)}"
101
- if File.exists?(dest)
102
- FileUtils.cp(dest, file, :verbose => false, :preserve => true) unless File.expand_path(file).eql?(dest)
98
+ dest = "#{DOWNLOADS}/#{File.basename(file)}"
99
+ if File.exist?(dest)
100
+ FileUtils.cp(dest, file, verbose: false, preserve: true) unless File.expand_path(file).eql?(dest)
103
101
  return true
104
102
  end
105
103
  false
106
104
  end
107
105
 
108
- def Oddb2xml.download_finished(file, remove_file = true)
109
- src = "#{WorkDir}/#{File.basename(file)}"
110
- dest = "#{Downloads}/#{File.basename(file)}"
111
- FileUtils.makedirs(Downloads)
112
- #return unless File.exists?(file)
113
- return unless file and File.exists?(file)
106
+ def self.download_finished(file, remove_file = true)
107
+ src = "#{WORK_DIR}/#{File.basename(file)}"
108
+ dest = "#{DOWNLOADS}/#{File.basename(file)}"
109
+ FileUtils.makedirs(DOWNLOADS)
110
+ # return unless File.exists?(file)
111
+ return unless file && File.exist?(file)
114
112
  return if File.expand_path(file).eql?(dest)
115
- FileUtils.cp(src, dest, :verbose => false)
113
+ FileUtils.cp(src, dest, verbose: false)
116
114
  Oddb2xml.log("download_finished saved as #{dest} #{File.size(dest)} bytes.")
117
115
  end
118
116
 
119
117
  # please keep this constant in sync between (GEM) swissmedic-diff/lib/swissmedic-diff.rb and (GEM) oddb2xml/lib/oddb2xml/extractor.rb
120
- def Oddb2xml.check_column_indices(sheet)
118
+ def self.check_column_indices(sheet)
121
119
  row = sheet[5] # Headers are found at row 5 since February 5
122
120
 
123
121
  error_2019 = nil
124
- 0.upto((COLUMNS_FEBRUARY_2019.size) -1).each{ |idx| puts "#{idx}: #{row[idx].value}" } if $VERBOSE
125
- COLUMNS_FEBRUARY_2019.each{
126
- |key, value|
122
+ 0.upto(COLUMNS_FEBRUARY_2019.size - 1).each { |idx| puts "#{idx}: #{row[idx].value}" } if $VERBOSE
123
+ COLUMNS_FEBRUARY_2019.each { |key, value|
127
124
  header_name = row[COLUMNS_FEBRUARY_2019.keys.index(key)].value.to_s
128
125
  unless value.match(header_name)
129
126
  puts "#{__LINE__}: #{key} -> #{COLUMNS_FEBRUARY_2019.keys.index(key)} #{value}\nbut was #{header_name}" if $VERBOSE
130
- error_2019 = "Packungen.xlslx_has_unexpected_column_#{COLUMNS_FEBRUARY_2019.keys.index(key)}_#{key}_#{value.to_s}_but_was_#{header_name}"
127
+ error_2019 = "Packungen.xlslx_has_unexpected_column_#{COLUMNS_FEBRUARY_2019.keys.index(key)}_#{key}_#{value}_but_was_#{header_name}"
131
128
  # require 'pry'; binding.pry
132
- break
129
+ break
133
130
  end
134
131
  }
135
- raise "#{error_2019}" if error_2019
132
+ raise error_2019.to_s if error_2019
136
133
  end
137
134
 
138
135
  # please keep this constant in sync between (GEM) swissmedic-diff/lib/swissmedic-diff.rb and (GEM) oddb2xml/lib/oddb2xml/extractor.rb
139
- COLUMNS_FEBRUARY_2019= {
140
- :iksnr => /Zulassungs-Nummer/i, # column-nr: 0
141
- :seqnr => /Dosisstärke-nummer/i,
142
- :name_base => /Bezeichnung des Arzneimittels/i,
143
- :company => /Zulassungsinhaberin/i,
144
- :production_science => /Heilmittelcode/i,
145
- :index_therapeuticus => /IT-Nummer/i, # column-nr: 5
146
- :atc_class => /ATC-Code/i,
147
- :registration_date => /Erstzul.datum Arzneimittel/i,
148
- :sequence_date => /Zul.datum Dosisstärke/i,
149
- :expiry_date => /Gültigkeitsdauer der Zulassung/i,
150
- :ikscd => /Packungscode/i, # column-nr: 10
151
- :size => /Packungsgrösse/i,
152
- :unit => /Einheit/i,
153
- :ikscat => /Abgabekategorie Packung/i,
154
- :ikscat_seq => /Abgabekategorie Dosisstärke/i,
155
- :ikscat_preparation => /Abgabekategorie Arzneimittel/i, # column-nr: 15
156
- :substances => /Wirkstoff/i,
157
- :composition => /Zusammensetzung/i,
158
- :composition_AMZV => /Volldeklaration rev. AMZV umgesetzt/i,
159
- :indication_registration => /Anwendungsgebiet Arzneimittel/i,
160
- :indication_sequence => /Anwendungsgebiet Dosisstärke/i, # column-nr 20
161
- :gen_production => /Gentechnisch hergestellte Wirkstoffe/i,
162
- :insulin_category => /Kategorie bei Insulinen/i,
163
- # swissmedi corrected in february 2018 the typo betäubunsmittel to betäubungsmittel-
164
- :drug_index => /Verz. bei betäubungsmittel-haltigen Arzneimittel/i,
165
- }
136
+ COLUMNS_FEBRUARY_2019 = {
137
+ iksnr: /Zulassungs-Nummer/i, # column-nr: 0
138
+ seqnr: /Dosisstärke-nummer/i,
139
+ name_base: /Bezeichnung des Arzneimittels/i,
140
+ company: /Zulassungsinhaberin/i,
141
+ production_science: /Heilmittelcode/i,
142
+ index_therapeuticus: /IT-Nummer/i, # column-nr: 5
143
+ atc_class: /ATC-Code/i,
144
+ registration_date: /Erstzul.datum Arzneimittel/i,
145
+ sequence_date: /Zul.datum Dosisstärke/i,
146
+ expiry_date: /Gültigkeitsdauer der Zulassung/i,
147
+ ikscd: /Packungscode/i, # column-nr: 10
148
+ size: /Packungsgrösse/i,
149
+ unit: /Einheit/i,
150
+ ikscat: /Abgabekategorie Packung/i,
151
+ ikscat_seq: /Abgabekategorie Dosisstärke/i,
152
+ ikscat_preparation: /Abgabekategorie Arzneimittel/i, # column-nr: 15
153
+ substances: /Wirkstoff/i,
154
+ composition: /Zusammensetzung/i,
155
+ composition_AMZV: /Volldeklaration rev. AMZV umgesetzt/i,
156
+ indication_registration: /Anwendungsgebiet Arzneimittel/i,
157
+ indication_sequence: /Anwendungsgebiet Dosisstärke/i, # column-nr 20
158
+ gen_production: /Gentechnisch hergestellte Wirkstoffe/i,
159
+ insulin_category: /Kategorie bei Insulinen/i,
160
+ # swissmedi corrected in february 2018 the typo betäubunsmittel to betäubungsmittel-
161
+ drug_index: /Verz. bei betäubungsmittel-haltigen Arzneimittel/i
162
+ }
166
163
 
167
164
  COLUMNS_JULY_2015 = {
168
- :iksnr => /Zulassungs-Nummer/i, # column-nr: 0
169
- :seqnr => /Dosisstärke-nummer/i,
170
- :name_base => /Präparatebezeichnung/i,
171
- :company => /Zulassungsinhaberin/i,
172
- :production_science => /Heilmittelcode/i,
173
- :index_therapeuticus => /IT-Nummer/i, # column-nr: 5
174
- :atc_class => /ATC-Code/i,
175
- :registration_date => /Erstzulassungs-datum./i,
176
- :sequence_date => /Zul.datum Dosisstärke/i,
177
- :expiry_date => /Gültigkeitsdauer der Zulassung/i,
178
- :ikscd => /Packungscode/i, # column-nr: 10
179
- :size => /Packungsgrösse/i,
180
- :unit => /Einheit/i,
181
- :ikscat => /Abgabekategorie Arzneimittel/i,
182
- :ikscat_seq => /Abgabekategorie Dosisstärke/i,
183
- :ikscat_preparation => /Abgabekategorie Präparat/i, # column-nr: 15
184
- :substances => /Wirkstoff/i,
185
- :composition => /Zusammensetzung/i,
186
- :indication_registration => /Anwendungsgebiet Präparat/i,
187
- :indication_sequence => /Anwendungsgebiet Dosisstärke/i,
188
- :gen_production => /Gentechnisch hergestellte Wirkstoffe/i, # column-nr 20
189
- :insulin_category => /Kategorie bei Insulinen/i,
190
- # swissmedi corrected in february 2018 the typo betäubunsmittel to betäubungsmittel-
191
- :drug_index => /Verz. bei betäubun.*smittel-haltigen Präparaten/i,
192
- }
193
- def Oddb2xml.add_hash(string)
165
+ iksnr: /Zulassungs-Nummer/i, # column-nr: 0
166
+ seqnr: /Dosisstärke-nummer/i,
167
+ name_base: /Präparatebezeichnung/i,
168
+ company: /Zulassungsinhaberin/i,
169
+ production_science: /Heilmittelcode/i,
170
+ index_therapeuticus: /IT-Nummer/i, # column-nr: 5
171
+ atc_class: /ATC-Code/i,
172
+ registration_date: /Erstzulassungs-datum./i,
173
+ sequence_date: /Zul.datum Dosisstärke/i,
174
+ expiry_date: /Gültigkeitsdauer der Zulassung/i,
175
+ ikscd: /Packungscode/i, # column-nr: 10
176
+ size: /Packungsgrösse/i,
177
+ unit: /Einheit/i,
178
+ ikscat: /Abgabekategorie Arzneimittel/i,
179
+ ikscat_seq: /Abgabekategorie Dosisstärke/i,
180
+ ikscat_preparation: /Abgabekategorie Präparat/i, # column-nr: 15
181
+ substances: /Wirkstoff/i,
182
+ composition: /Zusammensetzung/i,
183
+ indication_registration: /Anwendungsgebiet Präparat/i,
184
+ indication_sequence: /Anwendungsgebiet Dosisstärke/i,
185
+ gen_production: /Gentechnisch hergestellte Wirkstoffe/i, # column-nr 20
186
+ insulin_category: /Kategorie bei Insulinen/i,
187
+ # swissmedi corrected in february 2018 the typo betäubunsmittel to betäubungsmittel-
188
+ drug_index: /Verz. bei betäubun.*smittel-haltigen Präparaten/i
189
+ }
190
+ def self.add_hash(string)
194
191
  doc = Nokogiri::XML.parse(string) do |config|
195
192
  config.huge
196
193
  end
197
194
  nr = 0
198
195
  doc.root.elements.each do |node|
199
196
  nr += 1
200
- next if node.name.eql?('RESULT')
201
- node['SHA256'] = Digest::SHA256.hexdigest node.text
197
+ next if node.name.eql?("RESULT")
198
+ node["SHA256"] = Digest::SHA256.hexdigest node.text
202
199
  end
203
200
  doc.to_xml
204
201
  end
205
202
 
206
- def Oddb2xml.verify_sha256(file)
203
+ def self.verify_sha256(file)
207
204
  f = File.open(file)
208
205
  doc = Nokogiri::XML(f)
209
206
  nr = 0
210
207
  doc.root.elements.each do |node|
211
208
  nr += 1
212
- next if node.name.eql?('RESULT')
209
+ next if node.name.eql?("RESULT")
213
210
  sha256 = Digest::SHA256.hexdigest node.text
214
- unless node['SHA256'].eql?(sha256)
215
- puts "Verifiying #{node['SHA256']} != expectd #{sha256} against node #{node.text} failed"
216
- exit (3)
211
+ unless node["SHA256"].eql?(sha256)
212
+ puts "Verifiying #{node["SHA256"]} != expectd #{sha256} against node #{node.text} failed"
213
+ exit(3)
217
214
  end
218
215
  end
219
- return true
216
+ true
220
217
  end
221
218
 
222
- def Oddb2xml.validate_via_xsd(xsd_file, xml_file)
223
- xsd =open(xsd_file).read
219
+ def self.validate_via_xsd(xsd_file, xml_file)
220
+ xsd = IO.open(xsd_file).read
224
221
  xsd_rtikelstamm_xml = Nokogiri::XML::Schema(xsd)
225
222
  doc = Nokogiri::XML(File.read(xml_file))
226
- xsd_rtikelstamm_xml.validate(doc).each do
227
- |error|
228
- if error.message
229
- puts "Failed validating #{xml_file} with #{File.size(xml_file)} bytes using XSD from #{xsd_file}"
230
- puts "CMD: xmllint --noout --schema #{xsd_file} #{xml_file}"
231
- end
232
- msg = "expected #{error.message} to be nil\nfor #{xml_file}"
233
- puts msg
234
- expect(error.message).to be_nil, msg
223
+ xsd_rtikelstamm_xml.validate(doc).each do |error|
224
+ if error.message
225
+ puts "Failed validating #{xml_file} with #{File.size(xml_file)} bytes using XSD from #{xsd_file}"
226
+ puts "CMD: xmllint --noout --schema #{xsd_file} #{xml_file}"
227
+ end
228
+ msg = "expected #{error.message} to be nil\nfor #{xml_file}"
229
+ puts msg
230
+ expect(error.message).to be_nil, msg
235
231
  end
236
232
  end
237
233
 
@@ -240,36 +236,40 @@ COLUMNS_FEBRUARY_2019= {
240
236
  @@no8_to_ean13 = {}
241
237
  @@ean13_to_prodno = {}
242
238
  @@ean13_to_no8 = {}
243
- def Oddb2xml.setEan13forProdno(prodno, ean13)
244
- if ean13.to_i == 7680006660045 || ean13.to_i == 7680006660014
245
- Oddb2xml.log "setEan13forProdno #{prodno} ean13 #{ean13}"
246
- end
247
- @@prodno_to_ean13[prodno] ||= []
248
- @@prodno_to_ean13[prodno] << ean13
249
- @@ean13_to_prodno[ean13] = prodno
250
- end
251
- def Oddb2xml.setEan13forNo8(no8, ean13)
252
- if ean13.to_i == 7680006660045 || ean13.to_i == 7680006660014
253
- Oddb2xml.log "setEan13forNo8 #{no8} ean13 #{ean13}"
254
- end
255
- if @@no8_to_ean13[no8].nil?
256
- @@no8_to_ean13[no8] = ean13
257
- @@ean13_to_no8[ean13] = no8
258
- elsif !@@no8_to_ean13[no8].eql?(ean13)
259
- Oddb2xml.log "@@no8_to_ean13[no8] #{@@no8_to_ean13[no8]} not overridden by #{ean13}"
260
- end
261
- end
262
- def Oddb2xml.getEan13forProdno(prodno)
263
- @@prodno_to_ean13[prodno] || []
239
+ def self.setEan13forProdno(prodno, ean13)
240
+ if ean13.to_i == 7680006660045 || ean13.to_i == 7680006660014
241
+ Oddb2xml.log "setEan13forProdno #{prodno} ean13 #{ean13}"
264
242
  end
265
- def Oddb2xml.getEan13forNo8(no8)
266
- @@no8_to_ean13[no8] || []
267
- end
268
- def Oddb2xml.getProdnoForEan13(ean13)
269
- @@ean13_to_prodno[ean13]
243
+ @@prodno_to_ean13[prodno] ||= []
244
+ @@prodno_to_ean13[prodno] << ean13
245
+ @@ean13_to_prodno[ean13] = prodno
246
+ end
247
+
248
+ def self.setEan13forNo8(no8, ean13)
249
+ if ean13.to_i == 7680006660045 || ean13.to_i == 7680006660014
250
+ Oddb2xml.log "setEan13forNo8 #{no8} ean13 #{ean13}"
270
251
  end
271
- def Oddb2xml.getNo8ForEan13(ean13)
272
- @@ean13_to_no8[ean13]
252
+ if @@no8_to_ean13[no8].nil?
253
+ @@no8_to_ean13[no8] = ean13
254
+ @@ean13_to_no8[ean13] = no8
255
+ elsif !@@no8_to_ean13[no8].eql?(ean13)
256
+ Oddb2xml.log "@@no8_to_ean13[no8] #{@@no8_to_ean13[no8]} not overridden by #{ean13}"
273
257
  end
258
+ end
274
259
 
260
+ def self.getEan13forProdno(prodno)
261
+ @@prodno_to_ean13[prodno] || []
262
+ end
263
+
264
+ def self.getEan13forNo8(no8)
265
+ @@no8_to_ean13[no8] || []
266
+ end
267
+
268
+ def self.getProdnoForEan13(ean13)
269
+ @@ean13_to_prodno[ean13]
270
+ end
271
+
272
+ def self.getNo8ForEan13(ean13)
273
+ @@ean13_to_no8[ean13]
274
+ end
275
275
  end