oddb2xml 1.9.4 → 1.9.5

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.
@@ -8,6 +8,7 @@ require 'oddb2xml/compressor'
8
8
  require 'oddb2xml/options'
9
9
  require 'oddb2xml/util'
10
10
  require 'rubyXL'
11
+ require 'date' # for today
11
12
 
12
13
  module Oddb2xml
13
14
 
@@ -42,7 +43,9 @@ module Oddb2xml
42
43
  end
43
44
  def run
44
45
  threads = []
45
- if @options[:address]
46
+ if @options[:calc]
47
+ threads << download(:package) # swissmedic
48
+ elsif @options[:address]
46
49
  [:company, :person].each do |type|
47
50
  threads << download(type) # medregbm.admin
48
51
  end
@@ -91,9 +94,13 @@ module Oddb2xml
91
94
  def build
92
95
  Oddb2xml.log("Start build")
93
96
  begin
97
+ @_files = {"calc"=>"oddb_calc.xml"} if @options[:calc]
94
98
  files.each_pair do |sbj, file|
95
99
  builder = Builder.new(@options) do |builder|
96
- if @options[:address]
100
+ if @options[:calc]
101
+ builder.packs = @packs
102
+ builder.subject = sbj
103
+ elsif @options[:address]
97
104
  builder.subject = sbj
98
105
  builder.companies = @companies
99
106
  builder.people = @people
@@ -143,6 +150,9 @@ module Oddb2xml
143
150
  output = builder.to_xml
144
151
  end
145
152
  File.open(File.join(WorkDir, file), 'w:utf-8'){ |fh| fh << output }
153
+ if @options[:calc]
154
+ FileUtils.cp(File.join(WorkDir, file), File.join(WorkDir, file.sub('.xml', '_'+Time.now.strftime("%d.%m.%Y_%H.%M")+'.xml')), :verbose => true)
155
+ end
146
156
  end
147
157
  rescue Interrupt
148
158
  files.values.each do |file|
@@ -206,12 +216,13 @@ module Oddb2xml
206
216
  end
207
217
  when :package
208
218
  Thread.new do
209
- downloader = SwissmedicDownloader.new(:package)
219
+ downloader = SwissmedicDownloader.new(:package, @options)
210
220
  bin = downloader.download
211
221
  @mutex.synchronize do
212
222
  @packs = SwissmedicExtractor.new(bin, :package).to_hash
213
- # Oddb2xml.log("SwissmedicExtractor added #{@packs.size} packs. File #{bin} was #{File.size(bin)} bytes")
214
- end
223
+ Oddb2xml.log("SwissmedicExtractor added #{@packs.size} packs from #{bin}")
224
+ @packs
225
+ end unless @options[:calc]
215
226
  end
216
227
  when :bm_update
217
228
  Thread.new do
@@ -296,9 +307,9 @@ module Oddb2xml
296
307
  else # xml
297
308
  ##
298
309
  # building order
299
- # 1. addtions
310
+ # 1. additions
300
311
  # 2. subjects
301
- # 3. optionals
312
+ # 3. optional SUBJECTS
302
313
  _files = (ADDITIONS + SUBJECTS)
303
314
  _files += OPTIONALS if @options[:fi]
304
315
  _files.each do|sbj|
@@ -313,6 +324,11 @@ module Oddb2xml
313
324
  end
314
325
  def report
315
326
  lines = []
327
+ if @options[:calc]
328
+ lines << Calc.dump_new_galenic_forms
329
+ lines << Calc.dump_names_without_galenic_forms
330
+ lines << Calc.report_conversion
331
+ end
316
332
  unless @options[:address]
317
333
  LANGUAGES.each do |lang|
318
334
  lines << lang
@@ -256,8 +256,9 @@ XML
256
256
  end
257
257
  end
258
258
  class SwissmedicDownloader < Downloader
259
- def initialize(type=:orphan)
259
+ def initialize(type=:orphan, options = {})
260
260
  @type = type
261
+ @options = options
261
262
  case @type
262
263
  when :orphan
263
264
  action = "arzneimittel/00156/00221/00222/00223/00224/00227/00228/index.html?lang=de"
@@ -269,12 +270,17 @@ XML
269
270
  action = "arzneimittel/00156/00221/00222/00230/index.html?lang=de"
270
271
  @xpath = "//div[@id='sprungmarke10_7']//a[@title='Excel-Version Zugelassene Verpackungen*']"
271
272
  end
272
- url = "http://www.swissmedic.ch/#{action}"
273
- super({}, url)
273
+ url = "https://www.swissmedic.ch/#{action}"
274
+ super(@options, url)
274
275
  end
275
276
  def download
276
- @type == file = "swissmedic_#{@type}.xlsx"
277
+ @type == file = File.join(Oddb2xml::WorkDir, "swissmedic_#{@type}.xlsx")
278
+ if @options[:calc] and @options[:skip_download] and File.exists?(file) and (Time.now-File.ctime(file)).to_i < 24*60*60
279
+ Oddb2xml.log "SwissmedicDownloader #{__LINE__}: Skip downloading #{file} #{File.size(file)} bytes"
280
+ return File.expand_path(file)
281
+ end
277
282
  begin
283
+ FileUtils.rm(File.expand_path(file), :verbose => true) if File.exists?(File.expand_path(file))
278
284
  page = @agent.get(@url)
279
285
  if link_node = page.search(@xpath).first
280
286
  link = Mechanize::Page::Link.new(link_node, @agent, page)
@@ -254,6 +254,7 @@ module Oddb2xml
254
254
  i_5,i_3 = 0,10 # :swissmedic_numbers
255
255
  p_5,p_1_2 = 0,1 # :prodno
256
256
  cat = 13 # :swissmedic_category
257
+ seq_name = 2
257
258
  ith = 4 # :ith_swissmedic IT-Code (swissmedic-diff)
258
259
  atc = 5 # :atc_code
259
260
  list_code = 6 # Heilmittelcode, possible values are
@@ -276,6 +277,7 @@ module Oddb2xml
276
277
  siz = 11 # :package_size
277
278
  eht = 12 # :einheit_swissmedic
278
279
  sub = 14 # :substance_swissmedic
280
+ comp = 15 # :composition_swissmedic
279
281
  @sheet.each_with_index do |row, i|
280
282
 
281
283
  next if (i <= 1)
@@ -286,7 +288,7 @@ module Oddb2xml
286
288
  next if no8.to_i == 0
287
289
  ean_base12 = "7680#{no8}"
288
290
  data[no8.intern] = {
289
- :ean => (ean_base12.ljust(12, '0') + calc_checksum(ean_base12)),
291
+ :ean => (ean_base12.ljust(12, '0') + Oddb2xml.calc_checksum(ean_base12)),
290
292
  :prodno => prodno ? prodno : '',
291
293
  :ith_swissmedic => row[ith] ? row[ith].value.to_s : '',
292
294
  :swissmedic_category => row[cat].value.to_s,
@@ -295,6 +297,8 @@ module Oddb2xml
295
297
  :package_size => row[siz] ? row[siz].value.to_s : '',
296
298
  :einheit_swissmedic => row[eht] ? row[eht].value.to_s : '',
297
299
  :substance_swissmedic => row[sub] ? row[sub].value.to_s : '',
300
+ :composition_swissmedic => row[comp] ? row[comp].value.to_s : '',
301
+ :sequence_name => row[seq_name] ? row[seq_name].value.to_s : '',
298
302
  :is_tier => (row[typ] == 'Tierarzneimittel' ? true : false),
299
303
  }
300
304
  end
@@ -311,16 +315,6 @@ module Oddb2xml
311
315
  end unless defined?(RSpec)
312
316
  end
313
317
 
314
- def calc_checksum(str)
315
- str = str.strip
316
- sum = 0
317
- val = str.split(//u)
318
- 12.times do |idx|
319
- fct = ((idx%2)*2)+1
320
- sum += fct*val[idx].to_i
321
- end
322
- ((10-(sum%10))%10).to_s
323
- end
324
318
  end
325
319
  class MigelExtractor < Extractor
326
320
  def initialize(bin)
@@ -14,6 +14,7 @@ module Oddb2xml
14
14
  :extended => false,
15
15
  :compress_ext => nil,
16
16
  :format => :xml,
17
+ :calc => false,
17
18
  :tag_suffix => nil,
18
19
  :debug => false,
19
20
  :ean14 => false,
@@ -45,6 +46,7 @@ Usage:
45
46
  -t S, --tag-suffix=S XML tag suffix S. Default is none. [A-z0-9]
46
47
  If S is given, it is also used as prefix of filename.
47
48
  -x N, --context=N context N {product|address}. product is default.
49
+ --calc create only oddb_calc.xml with GTIN, name and galenic information
48
50
 
49
51
  For debugging purposes
50
52
  --skip-download skips downloading files it the file is already under downloads.
@@ -63,6 +65,7 @@ EOS
63
65
  @opts[:price] = :zurrose
64
66
  }
65
67
  @parser.on('-f v', '--format v', /^xml|dat$/) {|v| @opts[:format] = v.intern }
68
+ @parser.on('--calc') {|v| @opts[:calc] = true }
66
69
  @parser.on('-o', '--option') {|v| @opts[:fi] = true }
67
70
  @parser.on('-I v', '--increment v', /^[0-9]+$/) {|v| @opts[:percent] = v ? v.to_i : 0
68
71
  @opts[:price] = :zurrose
@@ -1,4 +1,15 @@
1
1
  module Oddb2xml
2
+ def Oddb2xml.calc_checksum(str)
3
+ str = str.strip
4
+ sum = 0
5
+ val = str.split(//u)
6
+ 12.times do |idx|
7
+ fct = ((idx%2)*2)+1
8
+ sum += fct*val[idx].to_i
9
+ end
10
+ ((10-(sum%10))%10).to_s
11
+ end
12
+
2
13
  unless defined?(RSpec)
3
14
  WorkDir = Dir.pwd
4
15
  Downloads = "#{Dir.pwd}/downloads"
@@ -8,7 +19,7 @@ module Oddb2xml
8
19
  def Oddb2xml.log(msg)
9
20
  return unless @options[:log]
10
21
  $stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}: #{msg}"
11
- $stdout.flush
22
+ # $stdout.flush
12
23
  end
13
24
 
14
25
  def Oddb2xml.save_options(options)
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "1.9.4"
2
+ VERSION = "1.9.5"
3
3
  end
@@ -25,7 +25,7 @@
25
25
  # https://www.medregbm.admin.ch/Publikation/CreateExcelListMedizinalPersons
26
26
  # (epha-)interactions https://download.epha.ch/cleaned/matrix.csv
27
27
 
28
- For historical reasons the generated *.XML have not a common layout and some fields have different meanings in differen files.
28
+ For historical reasons the generated *.XML have not a common layout and some fields have different meanings in different files.
29
29
 
30
30
  The two files oddb_article and oddb_product are not normalized. There if for one swissmedic IKSNR several
31
31
  packages are available you will find an entry inside oddb_article and oddb_product for each of them.
@@ -45,6 +45,8 @@
45
45
  REF_DATA 1 in oddb_article if coming from a refdata source (migel, bag, swissmedic), else 0
46
46
 
47
47
  FIRST import all data from swissINDEX
48
+ * DSCRD German name
49
+ * DSCRF French name (Products/article only from ZurRose do not have a french name)
48
50
  * GTIN
49
51
  * PHAR
50
52
  * Status
@@ -73,8 +75,10 @@
73
75
  C Abgabe nach Fachberatung durch Medizinalpersonen
74
76
  D Abgabe nach Fachberatung
75
77
  E Abgabe ohne Fachberatung
78
+ * IT IT-Number aka Index Therapeuticus: column 'E' from packages.xlsx
76
79
  * ATC (if missing from swissINDEX) -> Field SubstanceSwissmedic in oddb_article.xml
77
80
  * Wirkstoff (column 'O') -> Field SubstanceSwissmedic in oddb_article.xml
81
+ * Composition (column 'P') -> Field CompositionSwissmedic in oddb_product.xml
78
82
  * Packungsgrösse (column 'L') -> Field PackGrSwissmedic in oddb_article.xml
79
83
  * Packungseinheit(column 'L') -> Field EinheitSwissmedic in oddb_article.xml
80
84
 
@@ -802,6 +806,7 @@
802
806
  <xs:element minOccurs="0" ref="ns1:PackGrSwissmedic"/>
803
807
  <xs:element minOccurs="0" ref="ns1:EinheitSwissmedic"/>
804
808
  <xs:element minOccurs="0" ref="ns1:SubstanceSwissmedic"/>
809
+ <xs:element minOccurs="0" ref="ns1:CompositionSwissmedic"/>
805
810
  </xs:sequence>
806
811
  <xs:attribute name="DT" use="required"/>
807
812
  </xs:complexType>
@@ -842,6 +847,7 @@
842
847
  <xs:element name="PackGrSwissmedic" type="xs:string"/>
843
848
  <xs:element name="EinheitSwissmedic" type="xs:string"/>
844
849
  <xs:element name="SubstanceSwissmedic" type="xs:string"/>
850
+ <xs:element name="CompositionSwissmedic" type="xs:string"/>
845
851
  <xs:element name="PRODUCTMD">
846
852
  <xs:complexType>
847
853
  <xs:sequence>
@@ -118,6 +118,8 @@ describe Oddb2xml::Builder do
118
118
  product_xml.match(/<GTIN>7680620690084/).should_not == nil
119
119
  product_xml.match(/<DSCRD>Levetiracetam DESITIN Filmtabl 250 mg/).should_not == nil
120
120
  product_xml.match(/<DSCRF>Levetiracetam DESITIN cpr pell 250 mg/).should_not == nil
121
+ product_xml.match(/<SubstanceSwissmedic>levetiracetamum</)
122
+ product_xml.match(/<CompositionSwissmedic>levetiracetamum 250 mg, excipiens pro compressi obducti pro charta.</).should_not == nil
121
123
 
122
124
  article_xml.scan(/<ART DT=/).size.should eq(NrPharmaArticles)
123
125
  article_xml.should match(/<PHAR>5819012</)
@@ -0,0 +1,324 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pp'
4
+ require 'spec_helper'
5
+ require "rexml/document"
6
+ include REXML
7
+ require "#{Dir.pwd}/lib/oddb2xml/calc"
8
+ include Oddb2xml
9
+
10
+ describe Oddb2xml::Calc do
11
+
12
+ after(:each) do
13
+ FileUtils.rm(Dir.glob(File.join(Oddb2xml::WorkDir, '*.*')))
14
+ FileUtils.rm(Dir.glob(File.join(Oddb2xml::WorkDir, 'downloads', '*')))
15
+ end
16
+ before(:each) do
17
+ FileUtils.rm(Dir.glob(File.join(Oddb2xml::WorkDir, '*.xml')))
18
+ FileUtils.rm(Dir.glob(File.join(Oddb2xml::WorkDir, '*.csv')))
19
+ end
20
+
21
+ # after each name you find the column of swissmedic_package.xlsx file
22
+ TestExample = Struct.new("TestExample", :test_description, :iksnr_A, :seqnr_B, :pack_K, :name_C, :package_size_L, :einheit_M, :composition_P ,
23
+ :values_to_compare)
24
+
25
+ tst_fluorglukose = TestExample.new('Fluorglukose',
26
+ 51908, 2, 16, "2-Fluorglukose (18-F), Injektionslösung",
27
+ '0,1 - 80', 'GBq',
28
+ 'fludeoxyglucosum(18-F) zum Kalibrierungszeitpunkt 0.1-8 GBq, dinatrii phosphas dihydricus, natrii dihydrogenophosphas dihydricus, natrii chloridum, antiox.: natrii thiosulfas 1.3-1.9 mg, aqua ad iniectabilia q.s. ad solutionem pro 1 ml.',
29
+ { :selling_units => 1,
30
+ :measure => 'GBq',
31
+ # :count => 10, :multi => 1, :dose => ''
32
+ }
33
+ )
34
+ tst_bicaNova = TestExample.new('bicaNova',
35
+ 58277, 1, 1, "bicaNova 1,5 % Glucose, Peritonealdialyselösung",
36
+ '1500 ml', '',
37
+ 'I) et II) corresp.: natrii chloridum 5.5 g, natrii hydrogenocarbonas 3.36 g, calcii chloridum dihydricum 184 mg, magnesii chloridum hexahydricum 102 mg, glucosum anhydricum 15 g ut glucosum monohydricum, aqua ad iniectabilia q.s. ad solutionem pro 1000 ml.',
38
+ { :selling_units => 1500,
39
+ :measure => 'ml',
40
+ # :count => 10, :multi => 1, :dose => ''
41
+ }
42
+ )
43
+ tst_kamillin = TestExample.new('Kamillin Medipharm, Bad',
44
+ 43454, 1, 101, "Kamillin Medipharm, Bad",
45
+ '25 x 40', 'ml',
46
+ 'haemagglutininum influenzae A (H1N1) (Virus-Stamm A/California/7/2009 (H1N1)-like: reassortant virus NYMC X-179A) 15 µg, haemagglutininum influenzae A (H3N2) (Virus-Stamm A/Texas/50/2012 (H3N2)-like: reassortant virus NYMC X-223A) 15 µg, haemagglutininum influenzae B (Virus-Stamm B/Massachusetts/2/2012-like: B/Massachusetts/2/2012) 15 µg, natrii chloridum, kalii chloridum, dinatrii phosphas dihydricus, kalii dihydrogenophosphas, residui: formaldehydum max. 100 µg, octoxinolum-9 max. 500 µg, ovalbuminum max. 0.05 µg, saccharum nihil, neomycinum nihil, aqua ad iniectabilia q.s. ad suspensionem pro 0.5 ml.',
47
+ { :selling_units => 25,
48
+ :measure => 'ml',
49
+ # :count => 10, :multi => 1, :dose => ''
50
+ }
51
+ )
52
+ tst_infloran = TestExample.new('Test Infloran, capsule',
53
+ 679, 2, 12, "Infloran, capsule",
54
+ '2x10', 'Kapsel(n)',
55
+ 'lactobacillus acidophilus cryodesiccatus min. 10^9 CFU, bifidobacterium infantis min. 10^9 CFU, color.: E 127, E 132, E 104, excipiens pro capsula.',
56
+ { :selling_units => 20,
57
+ :measure => 'Kapsel(n)',
58
+ # :count => 10, :multi => 1, :dose => ''
59
+ }
60
+ )
61
+ tst_mutagrip = TestExample.new('Test Mutagrip (Fertigspritzen)',
62
+ 373, 23, 10, "Mutagrip, Suspension zur Injektion",
63
+ '10 x 0.5 ml', 'Fertigspritze(n)',
64
+ 'ropivacaini hydrochloridum 2 mg, natrii chloridum, aqua ad iniectabilia q.s. ad solutionem pro 1 ml.',
65
+ { :selling_units => 10,
66
+ :measure => 'Fertigspritze(n)',
67
+ # :count => 10, :multi => 1, :dose => ''
68
+ }
69
+ )
70
+
71
+ tst_diamox = TestExample.new('Diamox. Tabletten',
72
+ 21191, 1, 19, 'Diamox, comprimés',
73
+ '1 x 25', 'Tablette(n)',
74
+ 'haemagglutininum influenzae A (H1N1) (Virus-Stamm A/California/7/2009 (H1N1)-like: reassortant virus NYMC X-179A) 15 µg, haemagglutininum influenzae A (H3N2) (Virus-Stamm A/Texas/50/2012 (H3N2)-like: reassortant virus NYMC X-223A) 15 µg, haemagglutininum influenzae B (Virus-Stamm B/Massachusetts/2/2012-like: B/Massachusetts/2/2012) 15 µg, natrii chloridum, kalii chloridum, dinatrii phosphas dihydricus, kalii dihydrogenophosphas, residui: formaldehydum max. 100 µg, octoxinolum-9 max. 500 µg, ovalbuminum max. 0.05 µg, saccharum nihil, neomycinum nihil, aqua ad iniectabilia q.s. ad suspensionem pro 0.5 ml.',
75
+ { :selling_units => 25,
76
+ :measure => 'Tablette(n)',
77
+ #:count => 25, :multi => 1
78
+ }
79
+ )
80
+
81
+ tst_naropin = TestExample.new('Das ist eine Injektionslösung von einer Packung mit 5 x 100 ml',
82
+ 54015, 01, 100, "Naropin 0,2 %, Infusionslösung / Injektionslösung",
83
+ '1 x 5 x 100', 'ml',
84
+ 'ropivacaini hydrochloridum 2 mg, natrii chloridum, aqua ad iniectabilia q.s. ad solutionem pro 1 ml.',
85
+ { :selling_units => 5,
86
+ :measure => 'ml',
87
+ #:count => 5, :multi => 1
88
+ }
89
+ )
90
+
91
+ context 'should return correct value for liquid' do
92
+ pkg_size_L = '1 x 5 x 200'
93
+ einheit_M = 'ml'
94
+ name_C = 'Naropin 0,2 %, Infusionslösung / Injektionslösung'
95
+ result = Calc.new(name_C, pkg_size_L, einheit_M, nil)
96
+ specify { expect(result.selling_units).to eq 5 }
97
+ specify { expect(result.measure).to eq 'ml' }
98
+ end
99
+
100
+ context 'should return correct value for W-Tropfen' do
101
+ pkg_size_L = '10'
102
+ einheit_M = 'ml'
103
+ name_C = 'W-Tropfen'
104
+ result = Calc.new(name_C, pkg_size_L, einheit_M, nil)
105
+ specify { expect(result.selling_units).to eq 10 }
106
+ specify { expect(result.measure).to eq 'ml' }
107
+ end
108
+
109
+
110
+ context 'should return correct value for Diamox, comprimés' do
111
+ pkg_size_L = '1 x 25'
112
+ einheit_M = 'Tablette(n)'
113
+ name_C = 'Diamox, comprimés'
114
+
115
+ result = Calc.new(name_C, pkg_size_L, einheit_M, nil)
116
+ specify { expect(result.selling_units).to eq 25 }
117
+ specify { expect(result.measure).to eq 'Tablette(n)' }
118
+
119
+ res = Calc.report_conversion
120
+ specify { expect(res.class).to eq Array }
121
+ specify { expect(res.first.class).to eq String }
122
+ end
123
+
124
+ context 'should return correct value for Perindopril' do
125
+ pkg_size_L = '90'
126
+ einheit_M = 'Tablette(n)'
127
+ name_C = 'comprimés pelliculés'
128
+
129
+ result = Calc.new(name_C, pkg_size_L, einheit_M, nil)
130
+ specify { expect(result.selling_units).to eq 90 }
131
+ specify { expect(result.measure).to eq einheit_M }
132
+
133
+ res = Calc.report_conversion
134
+ specify { expect(res.class).to eq Array }
135
+ specify { expect(res.first.class).to eq String }
136
+ end
137
+
138
+
139
+ context 'should find galenic_group for Kaugummi' do
140
+ result = Calc.get_galenic_group('Kaugummi')
141
+ specify { expect(result.class).to eq GalenicGroup }
142
+ specify { expect(result.description).to eq 'Kaugummi' }
143
+ end
144
+
145
+ context 'should find galenic_form for Infusionslösung / Injektionslösung' do
146
+ value = 'Infusionslösung / Injektionslösung'
147
+ result = Calc.get_galenic_form(value)
148
+ specify { expect(result.class).to eq GalenicForm }
149
+ specify { expect(result.description).to eq 'Infusionslösung/Injektionslösung' }
150
+ end
151
+
152
+ context 'should return galenic_group unknown for galenic_group Dummy' do
153
+ result = Calc.get_galenic_group('Dummy')
154
+ specify { expect(result.class).to eq GalenicGroup }
155
+ specify { expect(result.oid).to eq 1 }
156
+ specify { expect(result.descriptions['de']).to eq 'unbekannt' }
157
+ specify { expect(result.description).to eq 'unbekannt' }
158
+ end
159
+
160
+ class TestExample
161
+ def url
162
+ "http://ch.oddb.org/de/gcc/drug/reg/#{sprintf('%05d' % iksnr_A)}/seq/#{sprintf('%02d' % seqnr_B)}/pack/#{sprintf('%03d' % pack_K)}"
163
+ end
164
+ end
165
+ [tst_fluorglukose,
166
+ tst_kamillin,
167
+ tst_naropin,
168
+ tst_diamox,
169
+ tst_mutagrip,
170
+ ].each {
171
+ |tst|
172
+ context "verify #{tst.iksnr_A} #{tst.name_C}: #{tst.url}" do
173
+ info = Calc.new(tst.name_C, tst.package_size_L, tst.einheit_M, tst.composition_P)
174
+ tst.values_to_compare.each do
175
+ |key, value|
176
+ context key do
177
+ cmd = "expect(info.#{key}.to_s).to eq '#{value.to_s}'"
178
+ specify { eval(cmd) }
179
+ end
180
+ end
181
+ end
182
+ }
183
+
184
+ context 'find correct result for Injektionslösung' do
185
+ info = Calc.new(tst_naropin.name_C, tst_naropin.package_size_L, tst_naropin.einheit_M, tst_naropin.composition_P)
186
+ specify { expect(tst_naropin.url).to eq 'http://ch.oddb.org/de/gcc/drug/reg/54015/seq/01/pack/100' }
187
+ specify { expect(info.galenic_form.description).to eq 'Infusionslösung/Injektionslösung' }
188
+ specify { expect(info.galenic_group.description).to eq 'Injektion/Infusion' }
189
+ specify { expect(info.pkg_size).to eq '1 x 5 x 100' }
190
+ skip { expect(info.measure).to eq '100 ml' }
191
+ # specify { expect(info.count).to eq 5 }
192
+ # specify { expect(info.multi).to eq 1 }
193
+ # specify { expect(info.addition).to eq 0 }
194
+ # specify { expect(info.scale).to eq 1 }
195
+ end
196
+
197
+ context 'find correct result for Inflora, capsule' do
198
+ info = Calc.new(tst_infloran.name_C, tst_infloran.package_size_L, tst_infloran.einheit_M, tst_infloran.composition_P)
199
+ specify { expect(tst_infloran.url).to eq 'http://ch.oddb.org/de/gcc/drug/reg/00679/seq/02/pack/012' }
200
+ specify { expect(info.galenic_form.description).to eq 'capsule' }
201
+ skip { expect(info.galenic_group.description).to eq 'Injektion/Infusion' }
202
+ specify { expect(info.pkg_size).to eq '2x10' }
203
+ specify { expect(info.selling_units).to eq 20 }
204
+ skip { expect(info.measure).to eq '0' }
205
+ # specify { expect(info.count).to eq 5 }
206
+ # specify { expect(info.multi).to eq 1 }
207
+ # specify { expect(info.addition).to eq 0 }
208
+ # specify { expect(info.scale).to eq 1 }
209
+ end
210
+
211
+ context 'convert mg/l into ml/mg for solutions' do
212
+ result = Calc.new('50', 'g/l')
213
+ skip { expect(result.measure).to eq 50 }
214
+ end
215
+
216
+ run_time_options = '--calc --skip-download'
217
+ context "when passing #{run_time_options}" do
218
+ let(:cli) do
219
+ options = Oddb2xml::Options.new
220
+ options.parser.parse!(run_time_options.split(' '))
221
+ Oddb2xml::Cli.new(options.opts)
222
+ end
223
+ it 'should create a correct xml and a csv file' do
224
+ src = File.expand_path(File.join(File.dirname(__FILE__), 'data', 'swissmedic_package-galenic.xlsx'))
225
+ dest = File.join(Oddb2xml::WorkDir, 'swissmedic_package.xlsx')
226
+ FileUtils.makedirs(Oddb2xml::WorkDir)
227
+ FileUtils.cp(src, dest, { :verbose => true, :preserve => true})
228
+ FileUtils.cp(File.expand_path(File.join(File.dirname(__FILE__), 'data', 'XMLPublications.zip')),
229
+ File.join(Oddb2xml::WorkDir, 'downloads'),
230
+ { :verbose => true, :preserve => true})
231
+ cli.run
232
+ expected = [
233
+ 'oddb_calc.xml',
234
+ 'oddb_calc.csv',
235
+ ].each { |file|
236
+ full = File.join(Oddb2xml::WorkDir, file)
237
+ expect(File.exists?(full)).to eq true
238
+ }
239
+ xml = File.read(File.join(Oddb2xml::WorkDir, 'oddb_calc.xml'))
240
+ doc = REXML::Document.new xml
241
+ gtin = '7680540151191'
242
+ tst_naropin.values_to_compare.each{
243
+ | key, value |
244
+ result = XPath.match( doc, "//ARTICLE[GTIN='#{gtin}']/#{key.to_s.upcase}").first.text
245
+ puts "Testing key #{key.inspect} #{value.inspect} against #{result} seems to fail" unless result == value.to_s
246
+ result.should eq value.to_s
247
+ }
248
+ end
249
+ end
250
+ context 'find correct result for Kamillin' do
251
+ info = Calc.new(tst_kamillin.name_C, tst_kamillin.package_size_L, tst_kamillin.einheit_M, tst_kamillin.composition_P)
252
+ specify { expect(info.selling_units).to eq 25 }
253
+ end
254
+
255
+ context 'find correct result for bicaNova' do
256
+ info = Calc.new(tst_bicaNova.name_C, tst_bicaNova.package_size_L, tst_bicaNova.einheit_M, tst_bicaNova.composition_P)
257
+ specify { expect(info.selling_units).to eq 1500 }
258
+ specify { expect(info.measure).to eq 'ml' }
259
+ end
260
+
261
+ context 'should return correct value for mutagrip' do
262
+ pkg_size_L = '10 x 0.5 ml'
263
+ einheit_M = 'Fertigspritze(n)'
264
+ name_C = 'Suspension zur Injektion'
265
+
266
+ result = Calc.new(name_C, pkg_size_L, einheit_M, nil)
267
+ specify { expect(result.selling_units).to eq 10 }
268
+ specify { expect(result.measure).to eq einheit_M }
269
+
270
+ res = Calc.report_conversion
271
+ specify { expect(res.class).to eq Array }
272
+ specify { expect(res.first.class).to eq String }
273
+ end
274
+
275
+ end
276
+
277
+ missing_tests = "
278
+ 1. Das ist eine Injektionslösung von einer Packung mit 5 x 100 ml
279
+ 1 x 5 x 100
280
+
281
+ 2. Hier muss man schauen ob es sich um ein Injektionspräparat handelt
282
+ oder um ein Tabletten, Kapseln, etc.
283
+ 2 x 100
284
+
285
+ a) Beim Injektionspräparat sind es wohl 2 Ampullen à 100 ml
286
+ b) Bei den Tabletten sind es wohl total 200 Stück.
287
+
288
+ 3. Das ist ein klarer Fall von einer Lösung, idR wohl Ampullen:
289
+ 10 x 2 mL
290
+
291
+ 4. Das sind 10 Teebeutel à 1.5g
292
+ 10 x 1.5g
293
+
294
+ 5. Das sind 20 mg Wirkstoff in einer 10 ml Lösung. 'ml' steht dann in
295
+ der Spalte M
296
+ 20 mg / 10. Könnte auch so geschrieben sein: 1000mg/50ml oder auch so:
297
+ 1 x 50mg/100ml
298
+
299
+ 6. 1x1 Urethrastab ist einmal ein Stab. ;)
300
+
301
+ 7. 30 (3x10) sind Total 30 Tabletten verteilt auf 3 Blister à 10
302
+ Tabletten. Könnte auch so geschrieben sein: 84 (4 x 21)
303
+
304
+ 8. 10 + 10 Das sind zehn Ampullen mit einer Trockensubstanz und
305
+ nochmals zehn Ampullen mit der Lösung. Das ist ein Kombipräparat.
306
+
307
+ 9. 20 x 0.5 g sind zwanzig Einzeldosen à 0.5g.
308
+
309
+ 10. Das ist eine Gaze: 1 x 7,5 x 10 cm
310
+
311
+ 11. 100 (2 x 50) das sind total 100 Beutel, d.h. zweimal fünfzig Stück.
312
+
313
+ 12. 0,1 - 80 GBq Das ist eine Injektionslösung.
314
+
315
+ 13. 10 cm x 10 cm imprägnierter Verband. Das ist eine Salbengaze.
316
+
317
+ 14. Das ist ein Sauerstofftank: 9000-10000 l
318
+
319
+ 15. 360x1 Das ist eine Packung mit 360 Durchstechflaschen.
320
+
321
+ 16. 5 + 5 Das sind 10 Durchstechflaschen à 1 Stück.
322
+ "
323
+
324
+