oddb2xml 1.9.4 → 1.9.5

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