gtin2atc 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 88ed6172e67a5d527bfa4c4f55fe1d49d4af214f
4
- data.tar.gz: b7daf74015a79a3f797037eaa0cc8c45f84ec3b8
3
+ metadata.gz: b6d462072d516aec948e6cf2ec404d60d78634d0
4
+ data.tar.gz: 965cfb24672bc54f53ec3cd347104dda20d8d39b
5
5
  SHA512:
6
- metadata.gz: a98367cbe6b716cee86116d9e100b7ea0fd8c44a85e5b7bb633d292f0f04de78d907865c9eebddf9fb74609161dbe3e69464d8353287ffc2f19596e51318a3c7
7
- data.tar.gz: a7d711d4fa0305d21540c6445669e09082734a99d0b30b9cfa4f05494ff242cadb365d2d89bc9d46d504a52959c5938e4675e0e435d7f33a43a4c749b180ca0c
6
+ metadata.gz: 5a9490c9a9d5efa5498153c8020b9119cfba390d7d09fc59524decb26f497502402f01ab79f10fdb5ae1757fe65be9a4b839a430d0f21c4d4e53130d7ba2c6b1
7
+ data.tar.gz: d1acea60db039502005e629dbb48f611dd9f4c18c50ef58c3bbf7426cb843090cf227bb4d6e88ef3f51f1aef1529afc7428e7567491b02e25a0b95e66578fdee
data/History.txt CHANGED
@@ -1,5 +1,12 @@
1
+ === 0.1.5 04.03.2015
2
+
3
+ * Added optional second parameter to specify output file
4
+ * Added output for dosis (name, unit, qty) for mono-preparations
5
+
1
6
  === 0.1.4 03.03.2015
2
7
 
8
+ * Add selling units ot generated gtin2atc.csv file
9
+ * Use ';' as column separator for generated CSV files
3
10
  * Create file pharmacode_gtin_not_found.txt
4
11
 
5
12
  === 0.1.3 27.01.2015
data/bin/gtin2atc CHANGED
@@ -23,12 +23,12 @@ end
23
23
 
24
24
  opts = options.opts
25
25
  startTime = Time.now
26
- if ARGV.size == 1 and File.exists?(ARGV[0])
27
- args = []
28
- IO.readlines(ARGV[0]).each{ |x| args << x.chomp}
26
+ if File.exists?(ARGV[0])
27
+ gtins2parse = []
28
+ IO.readlines(ARGV[0]).each{ |x| gtins2parse << x.chomp}
29
29
  else
30
- args = ARGV.clone
30
+ gtins2parse = ARGV.clone
31
31
  end
32
- Gtin2atc::Builder.new(opts).run(args)
32
+ Gtin2atc::Builder.new(opts).run(gtins2parse, ARGV[1])
33
33
  diff = (Time.now-startTime).to_i
34
34
  Gtin2atc::Util.debug_msg "#{File.basename(__FILE__)} done. Took #{diff} seconds"
@@ -14,11 +14,13 @@ module Gtin2atc
14
14
  AtcNotInSwissmedic = 'atc not in swissmedic'
15
15
  AtcNotInBag = 'atc not in bag'
16
16
  AtcDifferent = 'atc differed'
17
+ CsvOutputOptions = { :col_sep => ';', :encoding => 'UTF-8'}
17
18
  def initialize(opts)
18
19
  Util.set_logging(opts[:log])
20
+ @output = opts[:output]
19
21
  @do_compare = opts[:compare]
20
22
  @gen_reports = opts[:compare] and opts[:full]
21
- Util.debug_msg "Builder: opts are #{opts} @do_compare is #{@do_compare}"
23
+ Util.debug_msg "Builder: opts are #{opts} @do_compare is #{@do_compare} output #{@output}"
22
24
  @data_swissmedic = {}
23
25
  @data_bag = {}
24
26
  @data_swissindex = {}
@@ -93,6 +95,31 @@ module Gtin2atc
93
95
  Util.debug_msg "swissindex_xml_extractor extracted #{data.size} items"
94
96
  data
95
97
  end
98
+ def oddb_calc_xml_extractor
99
+ filename = 'oddb_calc.xml'
100
+ data = {}
101
+ unless File.exists?('oddb_calc.xml')
102
+ puts "Unable to open #{filename}"
103
+ else
104
+ xml = IO.read(filename)
105
+ Util.debug_msg "oddb_calc_xml_extractor xml is #{xml.size} bytes long"
106
+ result = ARTICLESEntry.parse(xml.sub(Strip_For_Sax_Machine, ''), :lazy => true)
107
+ result.ARTICLES.ARTICLE.each do |article|
108
+ item = {}
109
+ gtin = article.GTIN.to_i
110
+ item[:gtin] = gtin
111
+ item[:PKG_SIZE] = article.PKG_SIZE
112
+ item[:SELLING_UNITS] = article.SELLING_UNITS
113
+ item[:MEASURE] = article.MEASURE
114
+ if article.COMPOSITIONS.COMPONENT and article.COMPOSITIONS.COMPONENT.size == 1
115
+ item[:COMPOSITIONS] = article.COMPOSITIONS
116
+ end
117
+ data[gtin] = item
118
+ end
119
+ Util.debug_msg "oddb_calc_xml_extractor extracted #{data.size} items"
120
+ end
121
+ data
122
+ end
96
123
  def bag_xml_extractor
97
124
  data = {}
98
125
  @bag = BagDownloader.new
@@ -121,24 +148,37 @@ module Gtin2atc
121
148
  Util.debug_msg "bag_xml_extractor extracted #{data.size} items. Skipped #{@bag_entries_without_gtin} entries without gtin"
122
149
  data
123
150
  end
124
- def run(gtins_to_parse=[])
151
+
152
+ def run(gtins_to_parse=[], output_name=nil)
125
153
  Util.debug_msg("run #{gtins_to_parse}")
126
154
  Util.debug_msg("@use_swissindex true")
155
+ @oddb_calc = oddb_calc_xml_extractor
127
156
  @data_epha_atc = epha_atc_extractor
128
157
  @data_swissindex = swissindex_xml_extractor
129
158
  emitted_ids = []
130
- output_name = File.join(Util.get_archive, @do_compare ? 'gtin2atc_swissindex.csv' : 'gtin2atc.csv')
131
- CSV.open(output_name,'w+') do |csvfile|
132
- csvfile << ["gtin", "ATC", 'pharmacode', 'description', 'daily drug dose']
159
+ if @do_compare
160
+ output_name = File.join(Util.get_archive, 'gtin2atc_swissindex.csv')
161
+ else
162
+ output_name ||= 'gtin2atc.csv'
163
+ output_name = File.join(Util.get_archive, output_name)
164
+ end
165
+ CSV.open(output_name,'w+', CsvOutputOptions) do |csvfile|
166
+ csvfile << ["gtin", "ATC", 'pharmacode', 'description', 'daily drug dose', 'selling units']
133
167
  @data_swissindex.sort.each do |gtin, item|
134
168
  if @do_compare or gtins_to_parse.size == 0 or
135
169
  gtins_to_parse.index(gtin.to_s) or
136
- gtins_to_parse.index(item[:pharmacode])
170
+ gtins_to_parse.index(item[:pharmacode].to_s)
137
171
  atc = item[:atc_code]
138
172
  ddd = @data_epha_atc[atc]
139
- emitted_ids << gtin if gtin
140
- emitted_ids << item[:pharmacode] if item[:pharmacode]
141
- csvfile << [gtin, atc, item[:pharmacode], item[:description], ddd]
173
+ selling_units = @oddb_calc[gtin] ? @oddb_calc[gtin][:SELLING_UNITS] : nil
174
+ emitted_ids << gtin.to_i if gtin
175
+ emitted_ids << item[:pharmacode].to_i if item[:pharmacode]
176
+ if @oddb_calc[gtin] and @oddb_calc[gtin][:COMPOSITIONS]
177
+ comp = @oddb_calc[gtin][:COMPOSITIONS].COMPONENT.first
178
+ csvfile << [gtin, atc, item[:pharmacode], item[:description], ddd, selling_units, comp.NAME, comp.QTY, comp.UNIT]
179
+ else
180
+ csvfile << [gtin, atc, item[:pharmacode], item[:description], ddd, selling_units]
181
+ end
142
182
  end
143
183
  end
144
184
  end
@@ -147,16 +187,16 @@ module Gtin2atc
147
187
  missing_ids = []
148
188
  gtins_to_parse.each{
149
189
  |id|
150
- next if emitted_ids.index(id)
190
+ next if emitted_ids.index(id.to_i)
151
191
  missing_ids << id
152
192
  }
153
- File.open('pharmacode_gtin_not_found.txt', 'w+') { |f| f.write missing_ids.join("\n") }
193
+ File.open('pharmacode_gtin_not_found.txt', 'w+', CsvOutputOptions) { |f| f.write missing_ids.join("\n") }
154
194
  msg = "swissindex: Could not find info for #{missing_ids.size} missing ids see file pharmacode_gtin_not_found.txt"
155
195
  Util.debug_msg(msg)
156
196
  return unless @do_compare
157
197
  @data_bag = bag_xml_extractor
158
198
  output_name = File.join(Util.get_archive, 'gtin2atc_bag.csv')
159
- CSV.open(output_name,'w+') do |csvfile|
199
+ CSV.open(output_name,'w+', CsvOutputOptions) do |csvfile|
160
200
  csvfile << ["gtin", "ATC", 'description']
161
201
  @data_bag.sort.each do |gtin, item|
162
202
  csvfile << [gtin, item[:atc_code], item[:description]]
@@ -165,7 +205,7 @@ module Gtin2atc
165
205
  Util.debug_msg "bag: Extracted #{gtins_to_parse.size} of #{@data_bag.size} items into #{output_name} for #{gtins_to_parse}"
166
206
  @data_swissmedic = swissmedic_xls_extractor
167
207
  output_name = File.join(Util.get_archive, 'gtin2atc_swissmedic.csv')
168
- CSV.open(output_name,'w+') do |csvfile|
208
+ CSV.open(output_name,'w+', CsvOutputOptions) do |csvfile|
169
209
  csvfile << ["gtin", "ATC", 'description']
170
210
  @data_swissmedic.sort.each do |gtin, item|
171
211
  csvfile << [gtin, item[:atc_code], item[:pharmacode], item[:description]]
@@ -129,7 +129,7 @@ module Gtin2atc
129
129
  if File.exists?(file) and diff_hours = ((Time.now-File.ctime(file)).to_i/3600) and diff_hours < 24
130
130
  Util.debug_msg "Skip download of #{file} as only #{diff_hours} hours old"
131
131
  else
132
- FileUtils.rm_f(file, :verbose => true)
132
+ FileUtils.rm_f(file, :verbose => false)
133
133
  begin
134
134
  response = @agent.get(@url)
135
135
  response.save_as(file)
@@ -16,9 +16,13 @@ module Gtin2atc
16
16
  <<EOS
17
17
  #$0 ver.#{Gtin2atc::VERSION}
18
18
  Usage:
19
- gtin2atc [--compare] [--log] [file_with_gtin or gtin or pharmacode] [gtin..]
19
+ gtin2atc [--compare] [--log] [file_with_gtin or gtin or pharmacode] [output_file]
20
20
  If file_with_gtin is given only the GTIN (or pharamacode) (one per line) is outputted.
21
+ If a second parameter output_file is given the name of the generated csv file.
21
22
  If no file or gtin is given, alle GTIN will be processed.
23
+ If a file oddb_calc.xml (produced via oddb2xml --calc) is found in the current directory,
24
+ its content is read to add the daily drug dose and dose information for each article.
25
+
22
26
  --log log important actions
23
27
 
24
28
  --compare download an compare GTIN/ATC_code from BAG, SwissIndex and RefData
@@ -1,3 +1,3 @@
1
1
  module Gtin2atc
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
@@ -248,3 +248,50 @@ class MedicalInformationsEntry
248
248
  element :medicalInformations, :class => MedicalInformationsContent
249
249
  end
250
250
 
251
+ class COMPONENTContent
252
+ include SAXMachine
253
+ element :NAME
254
+ element :QTY
255
+ element :UNIT
256
+ end
257
+
258
+ class COMPONENTEntry
259
+ include SAXMachine
260
+ element :COMPONENT, :class => COMPONENTContent
261
+ end
262
+
263
+ class COMPONENTSContent
264
+ include SAXMachine
265
+ element :components, :class => COMPONENTContent
266
+ end
267
+
268
+ class COMPOSITIONSContent
269
+ include SAXMachine
270
+ attribute :ReleaseDate
271
+ elements :COMPONENT, :class => COMPONENTContent
272
+ end
273
+
274
+
275
+ class ARTICLEContent
276
+ include SAXMachine
277
+ element :GTIN
278
+ element :NAME
279
+ element :PKG_SIZE
280
+ element :MEASURE
281
+ element :SELLING_UNITS
282
+ element :GALENIC_FORM
283
+ element :GALENIC_GROUP
284
+ element :COMPOSITIONS, :class => COMPOSITIONSContent
285
+ end
286
+
287
+ class ARTICLESContent
288
+ include SAXMachine
289
+ attribute :ReleaseDate
290
+ elements :ARTICLE, :class => ARTICLEContent
291
+ end
292
+
293
+ class ARTICLESEntry
294
+ include SAXMachine
295
+ element :ARTICLES, :class => ARTICLESContent
296
+ end
297
+
data/spec/builder_spec.rb CHANGED
@@ -48,11 +48,10 @@ describe Gtin2atc::Builder do
48
48
  def check_csv(filename)
49
49
  File.exists?(filename).should eq true
50
50
  inhalt = IO.readlines(filename)
51
- puts inhalt
52
- /^\d{13},\w{4}/.should match inhalt[1]
51
+ /^\d{13};\w{4}/.should match inhalt[1]
53
52
  # Packungsgrösse, Dosierung, DDD, Route of Administration
54
- /^gtin,ATC,pharmacode,description,daily drug dose/.should match inhalt.first
55
- /^7680316440115,B03AA07,20244,FERRO-GRADUMET Depottabl,"0,2 g O Fe2\+"/.should match inhalt.join("\n")
53
+ /^gtin;ATC;pharmacode;description;daily drug dose/.should match inhalt.first
54
+ /^7680316440115;B03AA07;20244;FERRO-GRADUMET Depottabl;0,2 g O Fe2\+;/.should match inhalt.join("\n")
56
55
  end
57
56
 
58
57
  context 'when 20273 41803 (Pharmacodes) is given' do
@@ -102,8 +101,8 @@ describe Gtin2atc::Builder do
102
101
  check_csv(CSV_NAME)
103
102
  inhalt = IO.readlines(CSV_NAME)
104
103
  inhalt.size.should eq 2+1 # one header lines + two items
105
- inhalt[1].chomp.should eq '7680147690482,N07BC02,41803,KETALGIN Inj Lös 10 mg/ml,"25 mg O,P"'
106
- inhalt[2].chomp.should eq '7680353660163,B03AE10,20273,KENDURAL Depottabl,'
104
+ inhalt[1].chomp.should eq '7680147690482;N07BC02;41803;KETALGIN Inj Lös 10 mg/ml;25 mg O,P;'
105
+ inhalt[2].chomp.should eq '7680353660163;B03AE10;20273;KENDURAL Depottabl;;'
107
106
  end
108
107
  end
109
108
 
@@ -123,15 +122,15 @@ describe Gtin2atc::Builder do
123
122
  /7680353660163/.match(inhalt[1]).should == nil
124
123
  /7680147690482/.match(inhalt[2]).should == nil
125
124
  /7680353660163/.match(inhalt[2]).should_not == nil
126
- /7680353660163,B03AE10,20273,KENDURAL Depottabl/.match(inhalt[2]).should_not == nil
125
+ /7680353660163;B03AE10;20273;KENDURAL Depottabl/.match(inhalt[2]).should_not == nil
127
126
  end
128
127
  end
129
128
 
130
129
  def check_csv(filename)
131
130
  File.exists?(filename).should eq true
132
131
  inhalt = IO.readlines(filename)
133
- /^gtin,ATC/.match(inhalt.first).should_not == nil
134
- /^\d{13},\w{4}/.match(inhalt[1]).should_not == nil
132
+ /^gtin;ATC/.match(inhalt.first).should_not == nil
133
+ /^\d{13};\w{4}/.match(inhalt[1]).should_not == nil
135
134
  end
136
135
 
137
136
  context 'when --compare is given' do
@@ -144,8 +143,8 @@ describe Gtin2atc::Builder do
144
143
  it 'should produce three correct csv' do
145
144
  @res = buildr_capture(:stdout){ cli.run }
146
145
  check_csv('gtin2atc_bag.csv')
147
- check_csv('gtin2atc_swissindex.csv')
148
146
  check_csv('gtin2atc_swissmedic.csv')
147
+ check_csv('gtin2atc_swissindex.csv')
149
148
  end
150
149
 
151
150
  it 'should produce a good logging output' do
@@ -186,4 +185,34 @@ describe Gtin2atc::Builder do
186
185
 
187
186
  end
188
187
 
188
+ context 'when outputfile is given' do
189
+ let(:cli) do
190
+ options = Gtin2atc::Options.new
191
+ options.parser.parse!('7680316440115 tst.csv'.split(' '))
192
+ Gtin2atc::Builder.new(options.opts)
193
+ end
194
+
195
+ it 'should produce a correct tst.csv' do
196
+ tst_name = 'tst.csv'
197
+ buildr_capture(:stdout){ cli.run(["7680316440115"], tst_name) }
198
+ check_csv(tst_name)
199
+ end
200
+ end
201
+
202
+ context 'when producing csv' do
203
+ let(:cli) do
204
+ options = Gtin2atc::Options.new
205
+ Gtin2atc::Builder.new(options.opts)
206
+ end
207
+
208
+ it 'should contain dose for FERRO-GRADUMET Depottab' do
209
+ oddb_calc_xml = File.expand_path(File.join( __FILE__, '../data/oddb_calc.xml'))
210
+ FileUtils.cp(oddb_calc_xml, Gtin2atc::WorkDir, :verbose => false)
211
+ @res = buildr_capture(:stdout){ cli.run() }
212
+ check_csv(CSV_NAME)
213
+ inhalt = IO.readlines(CSV_NAME)
214
+ inhalt.index("7680316440115;B03AA07;20244;FERRO-GRADUMET Depottabl;0,2 g O Fe2+;30;Ferrum(ii);105.0;mg\n").should_not == nil
215
+ end
216
+ end
217
+
189
218
  end