oddb2xml 2.6.7 → 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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +40 -0
  3. data/.standard.yml +2 -0
  4. data/Elexis_Artikelstamm_v5.xsd +0 -3
  5. data/Gemfile +3 -3
  6. data/History.txt +30 -0
  7. data/README.md +1 -1
  8. data/Rakefile +24 -23
  9. data/bin/check_artikelstamm +11 -11
  10. data/bin/compare_v5 +23 -23
  11. data/bin/oddb2xml +14 -13
  12. data/lib/oddb2xml.rb +1 -1
  13. data/lib/oddb2xml/builder.rb +1077 -1039
  14. data/lib/oddb2xml/calc.rb +232 -233
  15. data/lib/oddb2xml/chapter_70_hack.rb +38 -32
  16. data/lib/oddb2xml/cli.rb +252 -233
  17. data/lib/oddb2xml/compare.rb +70 -59
  18. data/lib/oddb2xml/compositions_syntax.rb +448 -430
  19. data/lib/oddb2xml/compressor.rb +20 -20
  20. data/lib/oddb2xml/downloader.rb +155 -129
  21. data/lib/oddb2xml/extractor.rb +302 -296
  22. data/lib/oddb2xml/options.rb +34 -35
  23. data/lib/oddb2xml/parslet_compositions.rb +263 -265
  24. data/lib/oddb2xml/semantic_check.rb +39 -33
  25. data/lib/oddb2xml/util.rb +169 -159
  26. data/lib/oddb2xml/version.rb +1 -1
  27. data/lib/oddb2xml/xml_definitions.rb +32 -33
  28. data/oddb2xml.gemspec +32 -30
  29. data/spec/artikelstamm_spec.rb +139 -132
  30. data/spec/builder_spec.rb +495 -524
  31. data/spec/calc_spec.rb +552 -593
  32. data/spec/check_artikelstamm_spec.rb +26 -26
  33. data/spec/cli_spec.rb +182 -157
  34. data/spec/compare_spec.rb +9 -11
  35. data/spec/composition_syntax_spec.rb +390 -409
  36. data/spec/compressor_spec.rb +48 -48
  37. data/spec/data/Preparations.xml +139 -3
  38. data/spec/data/refdata_NonPharma.xml +0 -3
  39. data/spec/data/refdata_Pharma.xml +10 -25
  40. data/spec/data/swissmedic_package.xlsx +0 -0
  41. data/spec/data/transfer.dat +3 -1
  42. data/spec/data/varia_De.htm +2 -2
  43. data/spec/data_helper.rb +47 -49
  44. data/spec/downloader_spec.rb +247 -260
  45. data/spec/extractor_spec.rb +173 -165
  46. data/spec/galenic_spec.rb +233 -256
  47. data/spec/options_spec.rb +116 -119
  48. data/spec/parslet_spec.rb +833 -861
  49. data/spec/spec_helper.rb +154 -153
  50. data/test_options.rb +39 -42
  51. data/tools/win_fetch_cacerts.rb +2 -3
  52. metadata +49 -5
  53. data/.travis.yml +0 -30
@@ -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,227 +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.calc_checksum(str)
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
+ else
15
+ IO.popen(url)
16
+ end
17
+ end
18
+
19
+ def self.calc_checksum(str)
11
20
  str = str.strip
12
21
  sum = 0
13
- val = str.split(//u)
22
+ val = str.split(//u)
14
23
  12.times do |idx|
15
- fct = ((idx%2)*2)+1
16
- sum += fct*val[idx].to_i
24
+ fct = ((idx % 2) * 2) + 1
25
+ sum += fct * val[idx].to_i
17
26
  end
18
- ((10-(sum%10))%10).to_s
27
+ ((10 - (sum % 10)) % 10).to_s
19
28
  end
20
29
 
21
30
  unless defined?(RSpec)
22
- WorkDir = Dir.pwd
23
- Downloads = "#{Dir.pwd}/downloads"
31
+ WORK_DIR = Dir.pwd
32
+ DOWNLOADS = "#{Dir.pwd}/downloads"
24
33
  end
25
34
  @options = {}
26
- @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"
27
36
  @atc_csv_content = {}
28
37
 
29
- def Oddb2xml.html_decode(string)
38
+ def self.html_decode(string)
30
39
  german = string
31
- german = string.force_encoding('ISO-8859-1').encode('UTF-8') if string.encoding.to_s.eql?('ASCII')
32
- 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))
33
42
  german = HTMLEntities.new.decode(german)
34
43
  end
35
- Oddb2xml.patch_some_utf8(german).gsub('<br>',"\n")
44
+ Oddb2xml.patch_some_utf8(german).gsub("<br>", "\n")
36
45
  end
37
46
 
38
- def Oddb2xml.patch_some_utf8(line)
47
+ def self.patch_some_utf8(line)
39
48
  begin
40
- line = line.encode('utf-8')
41
- rescue => error
49
+ line = line.encode("utf-8")
50
+ rescue
42
51
  end
43
52
  begin
44
- 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
45
54
  rescue => error
46
55
  puts "#{error}: in #{line}"
47
56
  line
48
57
  end
49
58
  end
50
59
 
51
- def Oddb2xml.convert_to_8859_1(line)
52
- begin
53
- # We want to ignore lines which are not really UTF-8 encoded
54
- ausgabe = Oddb2xml.patch_some_utf8(line).encode('ISO-8859-1')
55
- ausgabe.encode('ISO-8859-1')
56
- rescue => error
57
- puts "#{error}: in #{line}"
58
- 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}"
59
66
  end
60
67
 
61
- def Oddb2xml.add_epha_changes_for_ATC(iksnr, atc_code, force_run: false)
62
- @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
63
70
  if @atc_csv_content.size == 0
64
- open(@atc_csv_origin).readlines.each{
65
- |line|
66
- items = line.split(',')
67
- @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]
68
74
  }
69
75
 
70
76
  end
71
77
  new_value = @atc_csv_content[[iksnr.to_s, atc_code]]
72
- new_value ? new_value : atc_code
78
+ new_value || atc_code
73
79
  end
74
80
 
75
- def Oddb2xml.log(msg)
81
+ def self.log(msg)
76
82
  return unless @options[:log]
77
83
  # TODO:: require 'pry'; binding.pry if msg.size > 1000
78
84
  $stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}: #{msg[0..250]}"
79
85
  $stdout.flush
80
86
  end
81
87
 
82
- def Oddb2xml.save_options(options)
88
+ def self.save_options(options)
83
89
  @options = options
84
90
  end
85
91
 
86
- def Oddb2xml.skip_download?
92
+ def self.skip_download?
87
93
  @options[:skip_download]
88
94
  end
89
95
 
90
- def Oddb2xml.skip_download(file)
96
+ def self.skip_download(file)
91
97
  return false if defined?(VCR)
92
- dest = "#{Downloads}/#{File.basename(file)}"
93
- if File.exists?(dest)
94
- 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)
95
101
  return true
96
102
  end
97
103
  false
98
104
  end
99
105
 
100
- def Oddb2xml.download_finished(file, remove_file = true)
101
- src = "#{WorkDir}/#{File.basename(file)}"
102
- dest = "#{Downloads}/#{File.basename(file)}"
103
- FileUtils.makedirs(Downloads)
104
- #return unless File.exists?(file)
105
- 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)
106
112
  return if File.expand_path(file).eql?(dest)
107
- FileUtils.cp(src, dest, :verbose => false)
113
+ FileUtils.cp(src, dest, verbose: false)
108
114
  Oddb2xml.log("download_finished saved as #{dest} #{File.size(dest)} bytes.")
109
115
  end
110
116
 
111
117
  # please keep this constant in sync between (GEM) swissmedic-diff/lib/swissmedic-diff.rb and (GEM) oddb2xml/lib/oddb2xml/extractor.rb
112
- def Oddb2xml.check_column_indices(sheet)
118
+ def self.check_column_indices(sheet)
113
119
  row = sheet[5] # Headers are found at row 5 since February 5
114
120
 
115
121
  error_2019 = nil
116
- 0.upto((COLUMNS_FEBRUARY_2019.size) -1).each{ |idx| puts "#{idx}: #{row[idx].value}" } if $VERBOSE
117
- COLUMNS_FEBRUARY_2019.each{
118
- |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|
119
124
  header_name = row[COLUMNS_FEBRUARY_2019.keys.index(key)].value.to_s
120
125
  unless value.match(header_name)
121
126
  puts "#{__LINE__}: #{key} -> #{COLUMNS_FEBRUARY_2019.keys.index(key)} #{value}\nbut was #{header_name}" if $VERBOSE
122
- 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}"
123
128
  # require 'pry'; binding.pry
124
- break
129
+ break
125
130
  end
126
131
  }
127
- raise "#{error_2019}" if error_2019
132
+ raise error_2019.to_s if error_2019
128
133
  end
129
134
 
130
135
  # please keep this constant in sync between (GEM) swissmedic-diff/lib/swissmedic-diff.rb and (GEM) oddb2xml/lib/oddb2xml/extractor.rb
131
- COLUMNS_FEBRUARY_2019= {
132
- :iksnr => /Zulassungs-Nummer/i, # column-nr: 0
133
- :seqnr => /Dosisstärke-nummer/i,
134
- :name_base => /Bezeichnung des Arzneimittels/i,
135
- :company => /Zulassungsinhaberin/i,
136
- :production_science => /Heilmittelcode/i,
137
- :index_therapeuticus => /IT-Nummer/i, # column-nr: 5
138
- :atc_class => /ATC-Code/i,
139
- :registration_date => /Erstzul.datum Arzneimittel/i,
140
- :sequence_date => /Zul.datum Dosisstärke/i,
141
- :expiry_date => /Gültigkeitsdauer der Zulassung/i,
142
- :ikscd => /Packungscode/i, # column-nr: 10
143
- :size => /Packungsgrösse/i,
144
- :unit => /Einheit/i,
145
- :ikscat => /Abgabekategorie Packung/i,
146
- :ikscat_seq => /Abgabekategorie Dosisstärke/i,
147
- :ikscat_preparation => /Abgabekategorie Arzneimittel/i, # column-nr: 15
148
- :substances => /Wirkstoff/i,
149
- :composition => /Zusammensetzung/i,
150
- :composition_AMZV => /Volldeklaration rev. AMZV umgesetzt/i,
151
- :indication_registration => /Anwendungsgebiet Arzneimittel/i,
152
- :indication_sequence => /Anwendungsgebiet Dosisstärke/i, # column-nr 20
153
- :gen_production => /Gentechnisch hergestellte Wirkstoffe/i,
154
- :insulin_category => /Kategorie bei Insulinen/i,
155
- # swissmedi corrected in february 2018 the typo betäubunsmittel to betäubungsmittel-
156
- :drug_index => /Verz. bei betäubungsmittel-haltigen Arzneimittel/i,
157
- }
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
+ }
158
163
 
159
164
  COLUMNS_JULY_2015 = {
160
- :iksnr => /Zulassungs-Nummer/i, # column-nr: 0
161
- :seqnr => /Dosisstärke-nummer/i,
162
- :name_base => /Präparatebezeichnung/i,
163
- :company => /Zulassungsinhaberin/i,
164
- :production_science => /Heilmittelcode/i,
165
- :index_therapeuticus => /IT-Nummer/i, # column-nr: 5
166
- :atc_class => /ATC-Code/i,
167
- :registration_date => /Erstzulassungs-datum./i,
168
- :sequence_date => /Zul.datum Dosisstärke/i,
169
- :expiry_date => /Gültigkeitsdauer der Zulassung/i,
170
- :ikscd => /Packungscode/i, # column-nr: 10
171
- :size => /Packungsgrösse/i,
172
- :unit => /Einheit/i,
173
- :ikscat => /Abgabekategorie Arzneimittel/i,
174
- :ikscat_seq => /Abgabekategorie Dosisstärke/i,
175
- :ikscat_preparation => /Abgabekategorie Präparat/i, # column-nr: 15
176
- :substances => /Wirkstoff/i,
177
- :composition => /Zusammensetzung/i,
178
- :indication_registration => /Anwendungsgebiet Präparat/i,
179
- :indication_sequence => /Anwendungsgebiet Dosisstärke/i,
180
- :gen_production => /Gentechnisch hergestellte Wirkstoffe/i, # column-nr 20
181
- :insulin_category => /Kategorie bei Insulinen/i,
182
- # swissmedi corrected in february 2018 the typo betäubunsmittel to betäubungsmittel-
183
- :drug_index => /Verz. bei betäubun.*smittel-haltigen Präparaten/i,
184
- }
185
- def Oddb2xml.add_hash(string)
186
- doc = Nokogiri::XML.parse(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)
191
+ doc = Nokogiri::XML.parse(string) do |config|
192
+ config.huge
193
+ end
187
194
  nr = 0
188
195
  doc.root.elements.each do |node|
189
196
  nr += 1
190
- next if node.name.eql?('RESULT')
191
- node['SHA256'] = Digest::SHA256.hexdigest node.text
197
+ next if node.name.eql?("RESULT")
198
+ node["SHA256"] = Digest::SHA256.hexdigest node.text
192
199
  end
193
200
  doc.to_xml
194
201
  end
195
202
 
196
- def Oddb2xml.verify_sha256(file)
203
+ def self.verify_sha256(file)
197
204
  f = File.open(file)
198
205
  doc = Nokogiri::XML(f)
199
206
  nr = 0
200
207
  doc.root.elements.each do |node|
201
208
  nr += 1
202
- next if node.name.eql?('RESULT')
209
+ next if node.name.eql?("RESULT")
203
210
  sha256 = Digest::SHA256.hexdigest node.text
204
- unless node['SHA256'].eql?(sha256)
205
- puts "Verifiying #{node['SHA256']} != expectd #{sha256} against node #{node.text} failed"
206
- exit (3)
211
+ unless node["SHA256"].eql?(sha256)
212
+ puts "Verifiying #{node["SHA256"]} != expectd #{sha256} against node #{node.text} failed"
213
+ exit(3)
207
214
  end
208
215
  end
209
- return true
216
+ true
210
217
  end
211
218
 
212
- def Oddb2xml.validate_via_xsd(xsd_file, xml_file)
213
- xsd =open(xsd_file).read
219
+ def self.validate_via_xsd(xsd_file, xml_file)
220
+ xsd = IO.open(xsd_file).read
214
221
  xsd_rtikelstamm_xml = Nokogiri::XML::Schema(xsd)
215
222
  doc = Nokogiri::XML(File.read(xml_file))
216
- xsd_rtikelstamm_xml.validate(doc).each do
217
- |error|
218
- if error.message
219
- puts "Failed validating #{xml_file} with #{File.size(xml_file)} bytes using XSD from #{xsd_file}"
220
- puts "CMD: xmllint --noout --schema #{xsd_file} #{xml_file}"
221
- end
222
- msg = "expected #{error.message} to be nil\nfor #{xml_file}"
223
- puts msg
224
- 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
225
231
  end
226
232
  end
227
233
 
@@ -230,36 +236,40 @@ COLUMNS_FEBRUARY_2019= {
230
236
  @@no8_to_ean13 = {}
231
237
  @@ean13_to_prodno = {}
232
238
  @@ean13_to_no8 = {}
233
- def Oddb2xml.setEan13forProdno(prodno, ean13)
234
- if ean13.to_i == 7680006660045 || ean13.to_i == 7680006660014
235
- Oddb2xml.log "setEan13forProdno #{prodno} ean13 #{ean13}"
236
- end
237
- @@prodno_to_ean13[prodno] ||= []
238
- @@prodno_to_ean13[prodno] << ean13
239
- @@ean13_to_prodno[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}"
240
242
  end
241
- def Oddb2xml.setEan13forNo8(no8, ean13)
242
- if ean13.to_i == 7680006660045 || ean13.to_i == 7680006660014
243
- Oddb2xml.log "setEan13forNo8 #{no8} ean13 #{ean13}"
244
- end
245
- if @@no8_to_ean13[no8].nil?
246
- @@no8_to_ean13[no8] = ean13
247
- @@ean13_to_no8[ean13] = no8
248
- elsif !@@no8_to_ean13[no8].eql?(ean13)
249
- Oddb2xml.log "@@no8_to_ean13[no8] #{@@no8_to_ean13[no8]} not overridden by #{ean13}"
250
- end
251
- end
252
- def Oddb2xml.getEan13forProdno(prodno)
253
- @@prodno_to_ean13[prodno] || []
254
- end
255
- def Oddb2xml.getEan13forNo8(no8)
256
- @@no8_to_ean13[no8] || []
257
- end
258
- def Oddb2xml.getProdnoForEan13(ean13)
259
- @@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}"
260
251
  end
261
- def Oddb2xml.getNo8ForEan13(ean13)
262
- @@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}"
263
257
  end
258
+ end
264
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
265
275
  end