swissmedic-diff 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,2 +1,9 @@
1
1
  tags
2
2
  *.swp
3
+ pkg
4
+ .*#
5
+ .bundle
6
+ .ruby-version
7
+ *.patch
8
+ InstalledFiles
9
+ SetupConfig
data/.travis.yml CHANGED
@@ -11,7 +11,6 @@ rvm:
11
11
  - 2.1.2
12
12
  - 2.0.0
13
13
  - 1.9.3
14
- - 1.8.7
15
14
  matrix:
16
15
  allow_failures:
17
16
  - rvm: ruby-head
data/Gemfile CHANGED
@@ -11,6 +11,6 @@ group :debugger do
11
11
  gem 'pry-debugger'
12
12
  else
13
13
  gem 'pry-byebug'
14
+ gem 'pry-doc'
14
15
  end
15
16
  end unless RUBY_VERSION =~ /^1\.8/
16
-
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- swissmedic-diff (0.1.9)
4
+ swissmedic-diff (0.2.0)
5
5
  nokogiri
6
- rubyXL
6
+ rubyXL (= 3.3.1)
7
7
  rubyzip
8
8
  spreadsheet
9
9
 
@@ -25,7 +25,7 @@ GEM
25
25
  method_source (0.8.2)
26
26
  mini_portile (0.6.2)
27
27
  minitest (5.7.0)
28
- minitest-reporters (1.0.16)
28
+ minitest-reporters (1.0.17)
29
29
  ansi
30
30
  builder
31
31
  minitest (>= 5.0)
@@ -42,7 +42,7 @@ GEM
42
42
  rake (10.4.2)
43
43
  ruby-ole (1.2.11.8)
44
44
  ruby-progressbar (1.7.5)
45
- rubyXL (3.3.8)
45
+ rubyXL (3.3.1)
46
46
  nokogiri (>= 1.4.4)
47
47
  rubyzip (>= 1.1.6)
48
48
  rubyzip (1.1.7)
@@ -60,3 +60,6 @@ DEPENDENCIES
60
60
  pry-debugger
61
61
  rake
62
62
  swissmedic-diff!
63
+
64
+ BUNDLED WITH
65
+ 1.10.5
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ === 0.2.0 / 03.07.2015
2
+
3
+ * Abort if Swissmedic introduces incompatible header lines
4
+ * Support new format of SwissMedic July 2015
5
+ * Reworked compating xlsx-files
6
+ * Remove support for old .xls-format (used before 2013)
7
+
1
8
  === 0.1.9 / 08.06.2015
2
9
 
3
10
  * Swissmedic has different header lines
data/Manifest.txt CHANGED
@@ -13,12 +13,8 @@ lib/swissmedic-diff.rb
13
13
  lib/version.rb
14
14
  setup.rb
15
15
  swissmedic-diff.gemspec
16
- test/data/Packungen-2013.10.14.xls
17
- test/data/Packungen.older.xls
18
- test/data/Packungen.xls
19
- test/data/Packungen_2013_small.xls
20
- test/data/Packungen_2014_small.xlsx
21
- test/data/Packungen_error_column.xls
22
- test/data/Packungen_error_missing1.xls
23
- test/data/Packungen_error_missing2.xls
16
+ test/data/Packungen-2014.01.01.xlsx
17
+ test/data/Packungen-2014.02.01.xlsx
18
+ test/data/Packungen-2015.06.04.xlsx
19
+ test/data/Packungen-2015.07.02.xlsx
24
20
  test/test_swissmedic-diff.rb
data/README.txt CHANGED
@@ -29,7 +29,7 @@ Then you can get the version 0.1.2.
29
29
 
30
30
  == REQUIREMENTS:
31
31
 
32
- * ruby 1.8 (with oniguruma patch) or ruby 1.9
32
+ * ruby 1.9, ruby 2.x
33
33
  * spreadsheet
34
34
 
35
35
  == INSTALL:
@@ -62,6 +62,7 @@ Usage: /usr/bin/swissmedic-diff [-gnr] <file1> <file2> [<output>]
62
62
  * Hannes Wyss <hwyss@ywesee.com>
63
63
  * Masaomi Hatakeyama <mhatakeyama@ywesee.com>
64
64
  * Zeno R.R. Davatz <zdavatz@ywesee.com>
65
+ * Niklaus Giger <ngiger@ywesee.com>
65
66
 
66
67
  == LICENSE:
67
68
 
@@ -23,11 +23,59 @@ require File.join(File.dirname(__FILE__), 'compatibility.rb')
23
23
  #Source:: http://scm.ywesee.com/?p=swissmedic-diff/.git;a=summary
24
24
  class SwissmedicDiff
25
25
  module Diff
26
- COLUMNS = [ :iksnr, :seqnr, :name_base, :company,
26
+ COLUMNS_2014 = {
27
+ :iksnr => /Zulassungs-Nummer/i, # column-nr: 0
28
+ :seqnr => /Dosistärke-nummer|^Sequenz$/i,
29
+ :name_base => /Präparatebezeichnung|^Sequenzname$/i,
30
+ :company => /Zulassungsinhaberin/i,
31
+ :index_therapeuticus => /IT-Nummer/i,
32
+ :atc_class => /ATC-Code/i, # column-nr: 5
33
+ :production_science => /Heilmittelcode/i,
34
+ :registration_date => /Erstzul.datum Präp./i,
35
+ :sequence_date => /Zul.datum Dosisstärke *|Zul.datum Sequenz/i,
36
+ :expiry_date => /Gültigkeits-datum */i,
37
+ :ikscd => /Verpackungs ID/i, # column-nr: 10
38
+ :size => /Packungsgrösse/i,
39
+ :unit => /Einheit/i,
40
+ :ikscat => /Abgabekategorie/i,
41
+ :substances => /Wirkstoff/i,
42
+ :composition => /Zusammensetzung/i, # column-nr: 15
43
+ :indication_registration => /Anwendungsgebiet Präparate/i,
44
+ :indication_sequence => /Anwendungsgebiet Dosisstärke|Anwendungsgebiet Sequenz/i,
45
+ }
46
+
47
+ COLUMNS_OLD = [ :iksnr, :seqnr, :name_base, :company,
27
48
  :index_therapeuticus, :atc_class, :production_science,
28
49
  :registration_date, :sequence_date, :expiry_date, :ikscd,
29
50
  :size, :unit, :ikscat, :substances, :composition,
30
51
  :indication_registration, :indication_sequence ]
52
+
53
+ COLUMNS_JULY_2015 = {
54
+ :iksnr => /Zulassungs-Nummer/i, # column-nr: 0
55
+ :seqnr => /Dosisstärke-nummer/i,
56
+ :name_base => /Präparatebezeichnung/i,
57
+ :company => /Zulassungsinhaberin/i,
58
+ :production_science => /Heilmittelcode/i,
59
+ :index_therapeuticus => /IT-Nummer/i, # column-nr: 5
60
+ :atc_class => /ATC-Code/i,
61
+ :registration_date => /Erstzulassungs-datum./i,
62
+ :sequence_date => /Zul.datum Dosisstärke/i,
63
+ :expiry_date => /Gültigkeitsdauer der Zulassung/i,
64
+ :ikscd => /Packungscode/i, # column-nr: 10
65
+ :size => /Packungsgrösse/i,
66
+ :unit => /Einheit/i,
67
+ :ikscat => /Abgabekategorie Packung/i,
68
+ :ikscat_seq => /Abgabekategorie Dosisstärke/i,
69
+ :ikscat_preparation => /Abgabekategorie Präparat/i, # column-nr: 15
70
+ :substances => /Wirkstoff/i,
71
+ :composition => /Zusammensetzung/i,
72
+ :indication_registration => /Anwendungsgebiet Präparat/i,
73
+ :indication_sequence => /Anwendungsgebiet Dosisstärke/i,
74
+ :gen_production => /Gentechnisch hergestellte Wirkstoffe/i, # column-nr 20
75
+ :insulin_category => /Kategorie bei Insulinen/i,
76
+ :drug_index => /Verz. bei betäubunsmittel-haltigen Präparaten/i,
77
+ }
78
+
31
79
  FLAGS = {
32
80
  :new => 'Neues Produkt',
33
81
  :name_base => 'Namensänderung',
@@ -58,9 +106,6 @@ class SwissmedicDiff
58
106
  cell.to_s
59
107
  end
60
108
  end
61
- def column(key)
62
- COLUMNS.index(key)
63
- end
64
109
  def describe(diff, iksnr)
65
110
  sprintf("%s: %s", iksnr, name(diff, iksnr))
66
111
  end
@@ -77,10 +122,10 @@ class SwissmedicDiff
77
122
  sprintf "%s (%s)", txt, pairs.join(',')
78
123
  when :registration_date, :expiry_date
79
124
  row = diff.newest_rows[iksnr].sort.first.last
80
- sprintf "%s (%s)", txt, row[column(flag)].strftime('%d.%m.%Y')
125
+ sprintf "%s (%s)", txt, row[COLUMNS_2014.keys.index(flag)].value.strftime('%d.%m.%Y')
81
126
  else
82
127
  row = diff.newest_rows[iksnr].sort.first.last
83
- sprintf "%s (%s)", txt, cell(row, column(flag))
128
+ sprintf "%s (%s)", txt, cell(row, COLUMNS_2014.keys.index(flag))
84
129
  end
85
130
  end
86
131
 
@@ -101,26 +146,27 @@ class SwissmedicDiff
101
146
  @diff.newest_rows = newest_rows
102
147
  Spreadsheet.client_encoding = 'UTF-8'
103
148
  tbook = Spreadsheet.open(target)
104
- sheet = tbook.worksheet(0)
105
149
  idx, prr, prp = nil
106
150
  multiples = {}
151
+ latest_keys = get_column_indices(Spreadsheet.open(latest)).keys
152
+ target_keys = get_column_indices(tbook).keys
107
153
  each_valid_row(tbook) { |row|
108
- iksnr = cell(row, column(:iksnr))
109
- seqnr = cell(row, column(:seqnr))
110
- pacnr = cell(row, column(:ikscd))
154
+ iksnr = cell(row, target_keys.index(:iksnr))
155
+ seqnr = cell(row, target_keys.index(:seqnr))
156
+ pacnr = cell(row, target_keys.index(:ikscd))
111
157
  (multiples[iksnr] ||= {})
112
158
  if prr == iksnr && prp == pacnr
113
159
  idx += 1
114
160
  elsif previous = multiples[iksnr][pacnr]
115
161
  prr = iksnr
116
162
  prp = pacnr
117
- idx = previous[COLUMNS.size].to_i + 1
163
+ idx = previous[target_keys.size].to_i + 1
118
164
  else
119
165
  prr = iksnr
120
166
  prp = pacnr
121
167
  idx = 0
122
168
  end
123
- row[COLUMNS.size] = idx
169
+ row[target_keys.size] = idx
124
170
  (newest_rows[iksnr] ||= {})[pacnr] = row
125
171
  multiples[iksnr][pacnr] = row
126
172
  if(other = known_regs.delete([iksnr]))
@@ -130,12 +176,12 @@ class SwissmedicDiff
130
176
  end
131
177
  known_seqs.delete([iksnr, seqnr])
132
178
  if(other = known_pacs.delete([iksnr, pacnr, idx]))
133
- flags = rows_diff(row, other, ignore)
179
+ flags = rows_diff(row, target_keys, other, latest_keys, ignore)
134
180
  (changes[iksnr].concat flags).uniq!
135
181
  updates.push row unless flags.empty?
136
182
  else
137
- replacements.store [ iksnr, seqnr, cell(row, column(:size)),
138
- cell(row, column(:unit)) ], row
183
+ replacements.store [ iksnr, seqnr, cell(row, target_keys.index(:size)),
184
+ cell(row, target_keys.index(:unit)) ], row
139
185
  flags = changes[iksnr]
140
186
  flags.push(:sequence).uniq! unless(flags.include? :new)
141
187
  news.push row
@@ -143,8 +189,8 @@ class SwissmedicDiff
143
189
  }
144
190
  @diff.replacements = reps = {}
145
191
  known_pacs.each { |(iksnr, pacnr), row|
146
- key = [iksnr, '%02i' % cell(row, column(:seqnr)).to_i,
147
- cell(row, column(:size)), cell(row, column(:unit))]
192
+ key = [iksnr, '%02i' % cell(row, target_keys.index(:seqnr)).to_i,
193
+ cell(row, target_keys.index(:size)), cell(row, target_keys.index(:unit))]
148
194
  if(rep = replacements[key])
149
195
  changes[iksnr].push :replaced_package
150
196
  reps.store rep, pacnr
@@ -156,7 +202,7 @@ class SwissmedicDiff
156
202
  ## the keys in known_pacs don't include the sequence number (which
157
203
  # would prevent us from properly recognizing multi-sequence-Packages),
158
204
  # so we need complete the path to the package now
159
- key[1,0] = '%02i' % cell(row, column(:seqnr)).to_i
205
+ key[1,0] = '%02i' % cell(row, target_keys.index(:seqnr)).to_i
160
206
  key
161
207
  }
162
208
  @diff.sequence_deletions = known_seqs.keys
@@ -181,24 +227,25 @@ class SwissmedicDiff
181
227
  lbook = Spreadsheet.open(latest)
182
228
  idx, prr, prp = nil
183
229
  multiples = {}
230
+ latest_keys = get_column_indices(lbook).keys
184
231
  each_valid_row(lbook) { |row|
185
- iksnr = cell(row, column(:iksnr))
186
- seqnr = cell(row, column(:seqnr))
187
- pacnr = cell(row, column(:ikscd))
232
+ iksnr = cell(row, latest_keys.index(:iksnr))
233
+ seqnr = cell(row, latest_keys.index(:seqnr))
234
+ pacnr = cell(row, latest_keys.index(:ikscd))
188
235
  multiples[iksnr] ||= {}
189
236
  if prr == iksnr && prp == pacnr
190
237
  idx += 1
191
238
  elsif previous = multiples[iksnr][pacnr]
192
239
  prr = iksnr
193
240
  prp = pacnr
194
- idx = previous[COLUMNS.size].to_i + 1
241
+ idx = previous[latest_keys.size].to_i + 1
195
242
  else
196
243
  prr = iksnr
197
244
  prp = pacnr
198
245
  idx = 0
199
246
  end
200
247
  multiples[iksnr][pacnr] = row
201
- row[COLUMNS.size] = idx
248
+ row[latest_keys.size] = idx
202
249
  known_regs.store [iksnr], row
203
250
  known_seqs.store [iksnr, seqnr], row
204
251
  known_pacs.store [iksnr, pacnr, idx], row
@@ -208,16 +255,19 @@ class SwissmedicDiff
208
255
  def name(diff, iksnr)
209
256
  rows = diff.newest_rows[iksnr]
210
257
  row = rows.sort.first.last
211
- cell(row, column(:name_base))
258
+ cell(row, COLUMNS_2014.keys.index(:name_base))
212
259
  end
213
- def rows_diff(row, other, ignore = [])
260
+ def rows_diff(row, row_keys, other, other_keys, ignore = [])
214
261
  flags = []
215
- COLUMNS.each_with_index { |key, idx|
216
- if(!ignore.include?(key) \
217
- && _comparable(key, row, idx) != _comparable(key, other, idx))
218
- # binding.pry if key == :expiry_date
219
-
220
- flags.push key
262
+ COLUMNS_OLD.each_with_index {
263
+ |key, idx|
264
+ if !ignore.include?(key)
265
+ left = _comparable(key, row, row_keys.index(key))
266
+ right = _comparable(key, other, other_keys.index(key))
267
+ if left != right
268
+ puts "Pushing key #{key}: '#{left.inspect}' != '#{right.inspect}'" if $VERBOSE
269
+ flags.push key
270
+ end
221
271
  end
222
272
  }
223
273
  flags
@@ -277,6 +327,42 @@ class SwissmedicDiff
277
327
  end
278
328
  end
279
329
 
330
+ def get_column_indices(spreadsheet)
331
+ error_2014 = nil
332
+ filename = spreadsheet.root.filepath
333
+ headerRowId = rows_to_skip(spreadsheet)-1
334
+ row = spreadsheet.worksheet(0)[headerRowId]
335
+
336
+ COLUMNS_2014.each{
337
+ |key, value|
338
+ header_name = row[COLUMNS_2014.keys.index(key)].value
339
+ unless value.match(header_name)
340
+ puts "#{__LINE__}: #{key} -> #{COLUMNS_2014.keys.index(key)} #{value}\nbut was #{header_name}" if $VERBOSE
341
+ error_2014 = "#{filename}_has_unexpected_column_#{COLUMNS_2014.keys.index(key)}_#{key}_#{value.to_s}_but_was_#{header_name}"
342
+ break
343
+ end
344
+ }
345
+ return COLUMNS_2014 unless error_2014
346
+ error_2015 = nil
347
+ COLUMNS_JULY_2015.each{
348
+ |key, value|
349
+ header_name = row[COLUMNS_JULY_2015.keys.index(key)].value
350
+ unless value.match(header_name)
351
+ puts "#{__LINE__}: #{key} -> #{COLUMNS_JULY_2015.keys.index(key)} #{value}\nbut was #{header_name}" if $VERBOSE
352
+ error_2015 = "#{filename}_has_unexpected_column_#{COLUMNS_JULY_2015.keys.index(key)}_#{key}_#{value.to_s}_but_was_#{header_name}"
353
+ break
354
+ end
355
+ }
356
+ unless error_2015
357
+ idx14 = COLUMNS_2014.keys.index(:name_base)
358
+ idx15 = COLUMNS_2014.keys.index(:name_base)
359
+ if (idx14 != idx15)
360
+ raise ":name_base must be same index in COLUMNS_JULY_2015 and COLUMNS_2014. Is #{idx14} and #{idx15}"
361
+ end
362
+ return COLUMNS_JULY_2015
363
+ end
364
+ raise "#{error_2015}\n#{error_2014}"
365
+ end
280
366
  #=== iterate over all valid rows of a swissmedic Packungen.xls
281
367
  #
282
368
  # Iterates over all rows, ignoring Tierarzneimittel and
@@ -292,20 +378,22 @@ class SwissmedicDiff
292
378
  #return ::
293
379
  def each_valid_row(spreadsheet)
294
380
  skipRows = rows_to_skip(spreadsheet)
381
+ column_keys = get_column_indices(spreadsheet).keys
295
382
  worksheet = spreadsheet.worksheet(0)
296
383
  row_nr = 0
297
384
  worksheet.each() {
298
385
  |row|
299
386
  row_nr += 1
300
387
  next if row_nr <= skipRows
301
- if row.size < COLUMNS.size/2
388
+ break unless row
389
+ if row.size < column_keys.size/2
302
390
  $stdout.puts "Data missing in \n(line " + (row_nr).to_s + "): " + row.join(", ").to_s + "\n"
303
391
  next
304
392
  end
305
- next if (cell(row, column(:production_science)) == 'Tierarzneimittel')
306
- row[column(:iksnr)] = "%05i" % cell(row, column(:iksnr)).to_i
307
- row[column(:seqnr)] = "%02i" % cell(row, column(:seqnr)).to_i
308
- row[column(:ikscd)] = "%03i" % cell(row, column(:ikscd)).to_i
393
+ next if (cell(row, column_keys.index(:production_science)) == 'Tierarzneimittel')
394
+ row[column_keys.index(:iksnr)] = "%05i" % cell(row, column_keys.index(:iksnr)).to_i
395
+ row[column_keys.index(:seqnr)] = "%02i" % cell(row, column_keys.index(:seqnr)).to_i
396
+ row[column_keys.index(:ikscd)] = "%03i" % cell(row, column_keys.index(:ikscd)).to_i
309
397
  yield row
310
398
  }
311
399
  end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class SwissmedicDiff
2
- VERSION = '0.1.9'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -15,7 +15,7 @@ spec = Gem::Specification.new do |s|
15
15
  Dir.glob('test/data/*.xls')
16
16
  s.test_file = "test/test_swissmedic-diff.rb"
17
17
  s.executables << 'swissmedic-diff'
18
- s.add_dependency('rubyXL')
18
+ s.add_dependency('rubyXL', '3.3.1')
19
19
  s.add_dependency('nokogiri')
20
20
  s.add_dependency('rubyzip')
21
21
  s.add_dependency('spreadsheet')
Binary file
Binary file
Binary file
@@ -6,58 +6,40 @@ $: << File.expand_path("../lib", File.dirname(__FILE__))
6
6
 
7
7
  require 'minitest/autorun'
8
8
  require 'swissmedic-diff'
9
- require 'pp'
9
+ require 'pp'
10
10
 
11
11
  module ODDB
12
12
  class SwissmedicPluginTest < Minitest::Test
13
13
  def setup
14
14
  @diff = SwissmedicDiff.new
15
- @data = File.expand_path 'data/Packungen.xls',
16
- File.dirname(__FILE__)
17
- @older = File.expand_path 'data/Packungen.older.xls',
18
- File.dirname(__FILE__)
19
- @data_error_column = File.expand_path 'data/Packungen_error_column.xls',
20
- File.dirname(__FILE__)
21
- @data_error_missing_case1 = File.expand_path 'data/Packungen_error_missing1.xls',
22
- File.dirname(__FILE__)
23
- @data_error_missing_case2 = File.expand_path 'data/Packungen_error_missing2.xls',
24
- File.dirname(__FILE__)
25
- @data_2013 = File.expand_path 'data/Packungen-2013.10.14.xls',
26
- File.dirname(__FILE__)
27
- @workbook = Spreadsheet.open(@data)
15
+ @january_2014 = File.expand_path 'data/Packungen-2014.01.01.xlsx', File.dirname(__FILE__)
16
+ @february_2014 = File.expand_path 'data/Packungen-2014.02.01.xlsx', File.dirname(__FILE__)
28
17
  end
29
-
30
- def test_diff_xls_and_xlsx
18
+
19
+ def test_diff_new_format_july_2015
31
20
  @diff = SwissmedicDiff.new
32
- last_month = File.expand_path 'data/Packungen_2013_small.xls', File.dirname(__FILE__)
33
- this_month = File.expand_path 'data/Packungen_2014_small.xlsx', File.dirname(__FILE__)
34
- result = @diff.diff last_month, this_month, [:atc_class, :sequence_date]
21
+ last_month = File.expand_path 'data/Packungen-2015.06.04.xlsx', File.dirname(__FILE__)
22
+ this_month = File.expand_path 'data/Packungen-2015.07.02.xlsx', File.dirname(__FILE__)
23
+ result = @diff.diff this_month, last_month, [:atc_class, :sequence_date]
35
24
  assert(result.changes.flatten.index('Zulassungs-Nummer') == nil, "Should not find Zulassungs-Nummer in changes")
36
- # puts "Got #{result.news.size} news, #{result.changes.size} changes, #{result.updates.size} updates."
37
- assert_equal(8, result.news.size)
38
- assert_equal(4, result.changes.size)
39
- assert_equal(2, result.updates.size)
40
- assert(result.news.first.index('00280'), "Should find 00280 in news")
41
- assert(result.news.flatten.index('65034'), "Should find 65034 in news")
42
- assert(result.news.flatten.index('00277') == nil, "Should not find 00277 in news")
43
- assert(result.news.flatten.index('Zulassungs-Nummer') == nil, "Should not find Zulassungs-Nummer in changes")
25
+ assert_equal(1, result.news.size)
26
+ assert_equal(2, result.changes.size)
27
+ assert_equal(1, result.updates.size)
28
+ assert_equal(['65838'], result.news.collect{|x| x[0] if x[0] == '65838'})
29
+ assert_equal({"65837"=>[:indication_sequence], "65838"=>[:new]}, result.changes)
44
30
  end
45
31
 
46
- def test_date_xls
47
- tbook = Spreadsheet.open(File.expand_path('data/Packungen.xls', File.dirname(__FILE__)))
48
- sheet = tbook.worksheet(0)
49
- assert_equal(nil, sheet.row(0)[8]) # sequence_date
50
- assert_equal(2010, sheet.row(4).date(8).year)
51
- assert_equal(26, sheet.row(4).date(8).day)
52
- # assert_equal(26, Spreadsheet.date_cell(sheet.row(4), 8))
53
- assert_equal(26, Spreadsheet.date_cell(sheet.row(4), 8).day)
54
- assert_equal(2010, Spreadsheet.date_cell(sheet.row(4), 8).year)
32
+ def test_diff_wrong_header
33
+ @diff = SwissmedicDiff.new
34
+ last_month = File.expand_path 'data/Packungen-2015.06.04.xlsx', File.dirname(__FILE__)
35
+ this_month = File.expand_path 'data/Packungen-wrong-header.xlsx', File.dirname(__FILE__)
36
+ assert_raises(RuntimeError) { @diff.diff this_month, last_month, [:atc_class, :sequence_date]}
55
37
  end
56
-
38
+
39
+
57
40
  def test_date_xlsx
58
- tbook = Spreadsheet.open(File.expand_path('data/Packungen_2014_small.xlsx', File.dirname(__FILE__)))
41
+ tbook = Spreadsheet.open(@january_2014)
59
42
  sheet = tbook.worksheet(0)
60
- # sheet = RubyXL::Parser.parse(File.expand_path(File.expand_path 'data/Packungen_2014_small.xlsx', File.dirname(__FILE__)))[0]
61
43
  assert_equal(nil, sheet.row(0)[8]) # sequence_date
62
44
  assert_equal(2010, sheet.row(4).date(8).year)
63
45
  assert_equal(26, sheet.row(4).date(8).day)
@@ -65,188 +47,87 @@ module ODDB
65
47
  assert_equal(2010, Spreadsheet.date_cell(sheet.row(4), 8).year)
66
48
  end
67
49
 
68
- def test_diff_xlsx_and_xls
69
- @diff = SwissmedicDiff.new
70
- last_month = File.expand_path 'data/Packungen_2014_01.xlsx', File.dirname(__FILE__)
71
- this_month = File.expand_path 'data/Packungen.xls', File.dirname(__FILE__)
72
- result = @diff.diff last_month, this_month, [:atc_class, :sequence_date]
73
- assert_equal(7, result.news.size)
74
- assert_equal(2, result.updates.size)
75
- assert_equal(10, result.changes.size)
76
- assert(result.changes.flatten.index('00275'), "Should find 00275 in changes")
77
- assert(result.changes.flatten.index('00277'), "Should find 00277 in changes")
78
- assert(result.news.flatten.index('Zulassungs-Nummer') == nil, "Should not find Zulassungs-Nummer in changes")
79
- end
80
50
  def test_diff_xlsx_and_xlsx
81
- @diff = SwissmedicDiff.new
82
- last_month = File.expand_path 'data/Packungen_2014_01.xlsx', File.dirname(__FILE__)
83
- this_month = File.expand_path 'data/Packungen_2014_small.xlsx', File.dirname(__FILE__)
84
- result = @diff.diff last_month, this_month, [:atc_class, :sequence_date]
85
- assert_equal({"00277"=>[:expiry_date, :indication_sequence]}, result.changes)
86
- assert_equal(1, result.updates.size)
87
- assert_equal([], result.news)
88
- end
89
-
90
- def test_iterate
91
- diff = SwissmedicDiff.new
92
- strings = []
93
- diff.each_valid_row(Spreadsheet.open(@data_2013)) { |x| strings << "iksnr #{x[0]} packungs id #{x[diff.column(:ikscd)]}" }
94
- expected = [
95
- "iksnr 00277 packungs id 001",
96
- "iksnr 00277 packungs id 002",
97
- "iksnr 61338 packungs id 001",
98
- "iksnr 61338 packungs id 002",
99
- "iksnr 61367 packungs id 001",
100
- "iksnr 61367 packungs id 002",
101
- "iksnr 61367 packungs id 003",
102
- "iksnr 61367 packungs id 004",
103
- "iksnr 61367 packungs id 005",
104
- "iksnr 61416 packungs id 001",
105
- "iksnr 63164 packungs id 001",
106
- "iksnr 63164 packungs id 002",
107
- "iksnr 63164 packungs id 003",
108
- "iksnr 65040 packungs id 001"
109
- ]
110
- assert_equal(expected, strings)
111
- end
112
-
113
- def test_diff_pre_2013_to_2013
114
- result = @diff.diff(@data_2013, @data)
115
- assert(result.changes.flatten.index('Zulassungs-Nummer') == nil, "Should not find Zulassungs-Nummer in changes")
116
- assert(result.news.flatten.index('Zulassungs-Nummer') == nil, "Should not find Zulassungs-Nummer in changes")
117
- assert(result.news.flatten.index('00277') == nil, "Should not find 00277 in news")
118
- assert_equal 6, result.news.size
51
+ result = @diff.diff @february_2014, @january_2014, [:atc_class, :sequence_date]
52
+ assert_equal 4, result.news.size
119
53
  expected = {
120
- "00277"=>[:company, :sequence_date, :substances, :composition, :name_base],
121
- "61338"=>[:sequence_date, :company, :atc_class],
122
- "61367"=>
123
- [:sequence_date,
124
- :ikscat,
125
- :substances,
126
- :composition,
127
- :sequence,
128
- :replaced_package],
129
- "61416"=>[:sequence_date],
130
- "63164"=>[:new],
131
- "65040"=>[:new],
132
- "00275"=>[:delete],
133
- "61345"=>[:delete]
134
- }
135
- assert_equal(expected, result.changes)
136
- diff_string =%(+ 63164: Rivastigmin Patch Sandoz 5, Transdermales Pflaster
137
- + 65040: Panthoben, Salbe
138
- - 00275: Cardio-Pulmo-Rénal Sérocytol, suppositoire
139
- - 61345: Terbinafin-Teva 125 mg, Tabletten
140
- > 00277: Coeur-Vaisseaux Sérocytol, suppositoire; Zulassungsinhaber (Sérolab, société anonyme), Zulassungsdatum Sequenz (2010-04-26), Wirkstoffe (globulina equina (immunisé avec coeur, endothélium vasculaire porcins)), Zusammensetzung (globulina equina (immunisé avec coeur, endothélium vasculaire porcins) 8 mg, propylenglycolum, conserv.: E 216, E 218, excipiens pro suppositorio.), Namensänderung (Coeur-Vaisseaux Sérocytol, suppositoire)
141
- > 61338: Cefuroxim Fresenius i.v. 750 mg, Pulver zur Herstellung einer i.v. Lösung; Zulassungsdatum Sequenz (2010-03-16), Zulassungsinhaber (Fresenius Kabi (Schweiz) AG), ATC-Code (J01DC02)
142
- > 61367: Hypericum-Mepha 250, Lactab; Zulassungsdatum Sequenz (2010-04-23), Abgabekategorie (D), Wirkstoffe (hyperici herbae extractum ethanolicum siccum quantificatum), Zusammensetzung (hyperici herbae extractum ethanolicum siccum quantificatum 250 mg corresp. hypericinum 0.25-0.75 mg, DER: 4-7:1, excipiens pro compresso obducto.), Packungs-Nummer (006 -> 005)
143
- > 61416: Otriduo Schnupfen, Nasentropfen; Zulassungsdatum Sequenz (2010-05-12))
144
- assert_equal(diff_string, @diff.to_s)
145
- end
146
- def test_diff
147
- result = @diff.diff(@data, @older)
148
- assert_equal 3, result.news.size
149
- assert_equal 'Cardio-Pulmo-Rénal Sérocytol, suppositoire',
150
- result.news.first.at(2)
151
- assert_equal 2, result.updates.size
152
- assert_equal 'Coeur-Vaisseaux Sérocytol, suppositoire(update)',
153
- result.updates.first.at(2)
154
- assert_equal 6, result.changes.size
155
- expected = {
156
- "00275"=>[:new],
157
- "00277"=>[:name_base],
158
- "61338"=>[:company, :atc_class],
159
- "61367"=>[:sequence, :replaced_package],
160
- "61416"=>[:new],
161
- "00274"=>[:delete]
54
+ "00277"=>[:name_base, :expiry_date, :indication_sequence],
55
+ "65040"=>[:sequence, :replaced_package],
56
+ "60125"=>[:new],
57
+ "61367"=>[:new],
58
+ "00274"=>[:delete]
162
59
  }
163
60
  assert_equal(expected, result.changes)
61
+ assert_equal 1, result.updates.size
62
+ assert_equal 5, result.changes.size
164
63
  assert_equal 3, result.package_deletions.size
165
64
  assert_equal 4, result.package_deletions.first.size
166
65
  iksnrs = result.package_deletions.collect { |row| row.at(0) }.sort
167
66
  ikscds = result.package_deletions.collect { |row| row.at(2) }.sort
168
- assert_equal ["00274", "61367", "61367"], iksnrs
169
- assert_equal ["001", "002", "005"], ikscds
67
+ assert_equal ["00274", "00274", "65040"], iksnrs
68
+ assert_equal ["001", "001", "002"], ikscds
170
69
  assert_equal 1, result.sequence_deletions.size
171
70
  assert_equal ["00274", "01"], result.sequence_deletions.at(0)
172
71
  assert_equal 1, result.registration_deletions.size
173
72
  assert_equal ["00274"], result.registration_deletions.at(0)
174
73
  assert_equal 1, result.replacements.size
175
- assert_equal '005', result.replacements.values.first
74
+ assert_equal '001', result.replacements.values.first
75
+
76
+ assert_equal 'Panthoben, Salbe', result.news.first[2].value
77
+ assert_equal 'Coeur-Vaisseaux Sérocytol, Namensänderung', result.updates.first[2].value
176
78
  end
79
+
177
80
  def test_diff_error_column
178
- res = @diff.diff(@data_error_column, @older)
81
+ res = @diff.diff(@february_2014, @january_2014)
179
82
  assert_equal(OpenStruct, res.class)
180
83
  end
181
84
 
182
- # if row.size < COLUMNS.size/2
183
- # as per december 2013 does no longer raise an error, but outputs the problematic line
184
- def test_diff_error_missing_case1
185
- @diff.diff(@data_error_missing_case1, @older)
186
- end
187
-
188
- # if row.select{|val| val==nil}.size > COLUMNS.size/2
189
- # as per december 2013 does no longer raise an error, but outputs the problematic line
190
- def test_diff_error_missing_case2
191
- @diff.diff(@data_error_missing_case2, @older)
192
- end
193
85
  def test_diff__ignore
194
- ignore = [:company, :atc_class]
195
- result = @diff.diff(@data, @older, ignore)
196
- assert_equal 3, result.news.size
197
- assert_equal 'Cardio-Pulmo-Rénal Sérocytol, suppositoire',
198
- result.news.first.at(2)
199
- assert_equal 1, result.updates.size
200
- assert_equal 'Coeur-Vaisseaux Sérocytol, suppositoire(update)',
201
- result.updates.first.at(2)
202
- assert_equal 5, result.changes.size
86
+ ignore = [:company, :name_base, :expiry_date, :indication_sequence]
87
+ result = @diff.diff(@february_2014, @january_2014, ignore)
203
88
  expected = {
204
- "00275"=>[:new],
205
- "00277"=>[:name_base],
206
- "61367"=>[:sequence, :replaced_package],
207
- "61416"=>[:new],
89
+ "00278"=>[:atc_class],
90
+ "00279"=>[:atc_class],
91
+ "65040"=>[:sequence, :replaced_package],
92
+ "60125"=>[:new],
93
+ "61367"=>[:new],
208
94
  "00274"=>[:delete]
209
95
  }
210
96
  assert_equal(expected, result.changes)
97
+ assert_equal 4, result.news.size
98
+ assert_equal 3, result.updates.size
99
+ assert_equal 6, result.changes.size
211
100
  assert_equal 3, result.package_deletions.size
212
- assert_equal 4, result.package_deletions.first.size
213
- iksnrs = result.package_deletions.collect { |row| row.at(0) }.sort
214
- ikscds = result.package_deletions.collect { |row| row.at(2) }.sort
215
- assert_equal ["00274", "61367", "61367"], iksnrs
216
- assert_equal ["001", "002", "005"], ikscds
217
- assert_equal 1, result.sequence_deletions.size
218
- assert_equal ["00274", "01"], result.sequence_deletions.at(0)
219
- assert_equal 1, result.registration_deletions.size
220
- assert_equal ["00274"], result.registration_deletions.at(0)
221
- assert_equal 1, result.replacements.size
222
- assert_equal '005', result.replacements.values.first
223
101
  end
224
102
  def test_to_s
225
103
  @diff.to_s
226
- @diff.diff(@data, @older)
104
+ @diff.diff(@february_2014, @january_2014)
227
105
  assert_equal <<-EOS.strip, @diff.to_s
228
- + 00275: Cardio-Pulmo-Rénal Sérocytol, suppositoire
229
- + 61416: Otriduo Schnupfen, Nasentropfen
106
+ + 60125: Otriduo Schnupfen, Dosierspray
107
+ + 61367: Hypericum-Mepha 250, Lactab
230
108
  - 00274: Cardio-Pulmo-Rénal Sérocytol, suppositoire
231
- > 00277: Coeur-Vaisseaux Sérocytol, suppositoire; Namensänderung (Coeur-Vaisseaux Sérocytol, suppositoire)
232
- > 61338: Cefuroxim Fresenius i.v. 750 mg, Pulver zur Herstellung einer i.v. Lösung; Zulassungsinhaber (Fresenius Kabi (Schweiz) AG), ATC-Code (J01DC02)
233
- > 61367: Hypericum-Mepha 250, Lactab; Packungs-Nummer (005 -> 006)
109
+ > 00277: Coeur-Vaisseaux Sérocytol, Namensänderung; Namensänderung (Coeur-Vaisseaux Sérocytol, Namensänderung), Ablaufdatum der Zulassung (25.04.2020), Anwendungsgebiet Sequenz ()
110
+ > 00278: Colon Sérocytol, suppositoire; ATC-Code (J06AA)
111
+ > 00279: Conjonctif Sérocytol, suppositoire; ATC-Code (D03AX04)
112
+ > 65040: Panthoben, Salbe; Packungs-Nummer (001 -> 003)
234
113
  EOS
235
114
  assert_equal <<-EOS.strip, @diff.to_s(:name)
236
115
  - 00274: Cardio-Pulmo-Rénal Sérocytol, suppositoire
237
- + 00275: Cardio-Pulmo-Rénal Sérocytol, suppositoire
238
- > 61338: Cefuroxim Fresenius i.v. 750 mg, Pulver zur Herstellung einer i.v. Lösung; Zulassungsinhaber (Fresenius Kabi (Schweiz) AG), ATC-Code (J01DC02)
239
- > 00277: Coeur-Vaisseaux Sérocytol, suppositoire; Namensänderung (Coeur-Vaisseaux Sérocytol, suppositoire)
240
- > 61367: Hypericum-Mepha 250, Lactab; Packungs-Nummer (005 -> 006)
241
- + 61416: Otriduo Schnupfen, Nasentropfen
242
- EOS
116
+ > 00277: Coeur-Vaisseaux Sérocytol, Namensänderung; Namensänderung (Coeur-Vaisseaux Sérocytol, Namensänderung), Ablaufdatum der Zulassung (25.04.2020), Anwendungsgebiet Sequenz ()
117
+ > 00278: Colon Sérocytol, suppositoire; ATC-Code (J06AA)
118
+ > 00279: Conjonctif Sérocytol, suppositoire; ATC-Code (D03AX04)
119
+ + 61367: Hypericum-Mepha 250, Lactab
120
+ + 60125: Otriduo Schnupfen, Dosierspray
121
+ > 65040: Panthoben, Salbe; Packungs-Nummer (001 -> 003)
122
+ EOS
243
123
  assert_equal <<-EOS.strip, @diff.to_s(:registration)
244
124
  - 00274: Cardio-Pulmo-Rénal Sérocytol, suppositoire
245
- + 00275: Cardio-Pulmo-Rénal Sérocytol, suppositoire
246
- > 00277: Coeur-Vaisseaux Sérocytol, suppositoire; Namensänderung (Coeur-Vaisseaux Sérocytol, suppositoire)
247
- > 61338: Cefuroxim Fresenius i.v. 750 mg, Pulver zur Herstellung einer i.v. Lösung; Zulassungsinhaber (Fresenius Kabi (Schweiz) AG), ATC-Code (J01DC02)
248
- > 61367: Hypericum-Mepha 250, Lactab; Packungs-Nummer (005 -> 006)
249
- + 61416: Otriduo Schnupfen, Nasentropfen
125
+ > 00277: Coeur-Vaisseaux Sérocytol, Namensänderung; Namensänderung (Coeur-Vaisseaux Sérocytol, Namensänderung), Ablaufdatum der Zulassung (25.04.2020), Anwendungsgebiet Sequenz ()
126
+ > 00278: Colon Sérocytol, suppositoire; ATC-Code (J06AA)
127
+ > 00279: Conjonctif Sérocytol, suppositoire; ATC-Code (D03AX04)
128
+ + 60125: Otriduo Schnupfen, Dosierspray
129
+ + 61367: Hypericum-Mepha 250, Lactab
130
+ > 65040: Panthoben, Salbe; Packungs-Nummer (001 -> 003)
250
131
  EOS
251
132
  end
252
133
  end
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swissmedic-diff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Masaomi Hatakeyama, Zeno R.R. Davatz
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-06-08 00:00:00.000000000 Z
12
+ date: 2015-07-04 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rdoc
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ~>
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - ~>
25
28
  - !ruby/object:Gem::Version
@@ -27,17 +30,19 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: hoe
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - ~>
32
36
  - !ruby/object:Gem::Version
33
- version: '3.7'
37
+ version: '3.13'
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - ~>
39
44
  - !ruby/object:Gem::Version
40
- version: '3.7'
45
+ version: '3.13'
41
46
  description: ! '* Compares two Excel Documents provided by Swissmedic and displays
42
47
  the
43
48
 
@@ -60,7 +65,6 @@ extra_rdoc_files:
60
65
  - Manifest.txt
61
66
  - README.txt
62
67
  files:
63
- - .gemtest
64
68
  - .gitignore
65
69
  - .travis.yml
66
70
  - Gemfile
@@ -76,19 +80,15 @@ files:
76
80
  - lib/version.rb
77
81
  - setup.rb
78
82
  - swissmedic-diff.gemspec
79
- - test/data/Packungen-2013.10.14.xls
80
- - test/data/Packungen.older.xls
81
- - test/data/Packungen.xls
82
- - test/data/Packungen_2013_small.xls
83
- - test/data/Packungen_2014_small.xlsx
84
- - test/data/Packungen_error_column.xls
85
- - test/data/Packungen_error_missing1.xls
86
- - test/data/Packungen_error_missing2.xls
83
+ - test/data/Packungen-2014.01.01.xlsx
84
+ - test/data/Packungen-2014.02.01.xlsx
85
+ - test/data/Packungen-2015.06.04.xlsx
86
+ - test/data/Packungen-2015.07.02.xlsx
87
87
  - test/test_swissmedic-diff.rb
88
+ - .gemtest
88
89
  homepage: https://github.com/zdavatz/swissmedic-diff
89
90
  licenses:
90
91
  - MIT
91
- metadata: {}
92
92
  post_install_message:
93
93
  rdoc_options:
94
94
  - --main
@@ -96,21 +96,28 @@ rdoc_options:
96
96
  require_paths:
97
97
  - lib
98
98
  required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
99
100
  requirements:
100
101
  - - ! '>='
101
102
  - !ruby/object:Gem::Version
102
103
  version: '0'
104
+ segments:
105
+ - 0
106
+ hash: -1183980882964765712
103
107
  required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
104
109
  requirements:
105
110
  - - ! '>='
106
111
  - !ruby/object:Gem::Version
107
112
  version: '0'
113
+ segments:
114
+ - 0
115
+ hash: -1183980882964765712
108
116
  requirements: []
109
- rubyforge_project: swissmedic-diff
110
- rubygems_version: 2.3.0
117
+ rubyforge_project:
118
+ rubygems_version: 1.8.23.2
111
119
  signing_key:
112
- specification_version: 4
120
+ specification_version: 3
113
121
  summary: ! '* Compares two Excel Documents provided by Swissmedic and displays the
114
122
  salient differences'
115
- test_files:
116
- - test/test_swissmedic-diff.rb
123
+ test_files: []
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NGZmZDYzOTBkNGI4MWQ5OTdlMTU4YmYyNzExNzI0YmU1MmZjOWIyMg==
5
- data.tar.gz: !binary |-
6
- NTA2M2YwNTU3M2RjNTIxNzJmZTUxZjM5MTg2NWZhZjg1NGM3ZGZlNA==
7
- SHA512:
8
- metadata.gz: !binary |-
9
- YzU4YjQ4ODRkMzc4OTZmMWM3MWM2MjUxNTBlNDFmY2Q5ZmM0ZmVhMTJhZDZj
10
- MmQ2MTg2NWY2NzY1MzEzZTRkZTBlY2FkMTA3MGY0OGRkOWE4M2YxOTIxM2M2
11
- YTZkZWQyODMzZDRjMDE2OGVjNGVhNGM5NTFhNjc2ZjYyYTQ0ZmI=
12
- data.tar.gz: !binary |-
13
- MjUwYjRmZThhMGUxMTZkMDUxNzdjZTRkNWQyYWFlMzZmMzdmNjI2YmMwZjFk
14
- MWFjMmEwOWMwYTNjNTM3YTkyODNjOGE1MGMxNTFhMDIyZjRjOWQ0OWM4M2Qz
15
- YTM1ZTgyY2MwZTIwNTM0NzcyNjkwNDFhMjExM2MyZDMzNTgzZjI=
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file