oddb2xml 2.7.1 → 2.7.2

Sign up to get free protection for your applications and to get access to all the features.
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