gtin2atc 0.1.4 → 0.1.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.
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