oddb2xml 2.7.1 → 2.7.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -2
  3. data/.standard.yml +2 -0
  4. data/Gemfile +3 -3
  5. data/History.txt +24 -0
  6. data/README.md +3 -3
  7. data/Rakefile +24 -23
  8. data/bin/check_artikelstamm +11 -11
  9. data/bin/compare_v5 +23 -23
  10. data/bin/oddb2xml +14 -13
  11. data/lib/oddb2xml/builder.rb +1070 -1038
  12. data/lib/oddb2xml/calc.rb +232 -233
  13. data/lib/oddb2xml/chapter_70_hack.rb +38 -32
  14. data/lib/oddb2xml/cli.rb +252 -236
  15. data/lib/oddb2xml/compare.rb +70 -59
  16. data/lib/oddb2xml/compositions_syntax.rb +451 -430
  17. data/lib/oddb2xml/compressor.rb +20 -20
  18. data/lib/oddb2xml/downloader.rb +157 -129
  19. data/lib/oddb2xml/extractor.rb +295 -295
  20. data/lib/oddb2xml/options.rb +34 -35
  21. data/lib/oddb2xml/parslet_compositions.rb +265 -269
  22. data/lib/oddb2xml/semantic_check.rb +39 -33
  23. data/lib/oddb2xml/util.rb +163 -163
  24. data/lib/oddb2xml/version.rb +1 -1
  25. data/lib/oddb2xml/xml_definitions.rb +32 -33
  26. data/lib/oddb2xml.rb +1 -1
  27. data/oddb2xml.gemspec +34 -34
  28. data/shell.nix +17 -0
  29. data/spec/artikelstamm_spec.rb +111 -110
  30. data/spec/builder_spec.rb +490 -505
  31. data/spec/calc_spec.rb +552 -593
  32. data/spec/check_artikelstamm_spec.rb +26 -26
  33. data/spec/cli_spec.rb +173 -174
  34. data/spec/compare_spec.rb +9 -11
  35. data/spec/composition_syntax_spec.rb +390 -409
  36. data/spec/compressor_spec.rb +48 -48
  37. data/spec/data/transfer.dat +1 -0
  38. data/spec/data_helper.rb +47 -49
  39. data/spec/downloader_spec.rb +251 -260
  40. data/spec/extractor_spec.rb +171 -159
  41. data/spec/fixtures/vcr_cassettes/oddb2xml.json +1 -1
  42. data/spec/galenic_spec.rb +233 -256
  43. data/spec/options_spec.rb +116 -119
  44. data/spec/parslet_spec.rb +896 -863
  45. data/spec/spec_helper.rb +153 -153
  46. data/test_options.rb +39 -42
  47. data/tools/win_fetch_cacerts.rb +2 -3
  48. metadata +42 -12
@@ -1,21 +1,22 @@
1
- # encoding: utf-8
2
- require 'nokogiri'
3
- require 'oddb2xml/util'
4
- require 'oddb2xml/calc'
5
- require 'csv'
1
+ require "nokogiri"
2
+ require "oddb2xml/util"
3
+ require "oddb2xml/calc"
4
+ require "csv"
5
+
6
6
  class Numeric
7
7
  # round a given number to the nearest step
8
8
  def round_by(increment)
9
9
  (self / increment).round * increment
10
10
  end
11
11
  end
12
+
12
13
  module Nokogiri
13
14
  module XML
14
15
  class Document < Nokogiri::XML::Node
15
16
  attr_writer :tag_suffix
16
- alias :create_element_origin :create_element
17
+ alias_method :create_element_origin, :create_element
17
18
  def create_element name, *args, &block
18
- name += (@tag_suffix || '')
19
+ name += (@tag_suffix || "")
19
20
  create_element_origin(name, *args, &block)
20
21
  end
21
22
  end
@@ -24,108 +25,116 @@ end
24
25
 
25
26
  module Oddb2xml
26
27
  XML_OPTIONS = {
27
- 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
28
- 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
29
- 'xmlns' => 'http://wiki.oddb.org/wiki.php?pagename=Swissmedic.Datendeklaration',
30
- 'CREATION_DATETIME' => Time.new.strftime('%FT%T%z'),
31
- 'PROD_DATE' => Time.new.strftime('%FT%T%z'),
32
- 'VALID_DATE' => Time.new.strftime('%FT%T%z'),
33
- 'GENERATED_BY' => "oddb2xml #{VERSION}"
28
+ "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
29
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
30
+ "xmlns" => "http://wiki.oddb.org/wiki.php?pagename=Swissmedic.Datendeklaration",
31
+ "CREATION_DATETIME" => Time.new.strftime("%FT%T%z"),
32
+ "PROD_DATE" => Time.new.strftime("%FT%T%z"),
33
+ "VALID_DATE" => Time.new.strftime("%FT%T%z"),
34
+ "GENERATED_BY" => "oddb2xml #{VERSION}"
34
35
  }
35
36
  class Builder
36
- Data_dir = File.expand_path(File.join(File.dirname(__FILE__),'..','..', 'data'))
37
- @@article_overrides = YAML.load_file(File.join(Data_dir, 'article_overrides.yaml'))
38
- @@product_overrides = YAML.load_file(File.join(Data_dir, 'product_overrides.yaml'))
39
- @@ignore_file = File.join(Data_dir, 'gtin2ignore.yaml')
40
- @@gtin2ignore = YAML.load_file(@@ignore_file) if File.exist?(@@ignore_file)
37
+ Data_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data"))
38
+ @@article_overrides = YAML.load_file(File.join(Data_dir, "article_overrides.yaml"))
39
+ @@product_overrides = YAML.load_file(File.join(Data_dir, "product_overrides.yaml"))
40
+ @@ignore_file = File.join(Data_dir, "gtin2ignore.yaml")
41
+ @@gtin2ignore = YAML.load_file(@@ignore_file) if File.exist?(@@ignore_file)
41
42
  @@gtin2ignore ||= []
42
43
  attr_accessor :subject, :refdata, :items, :flags, :lppvs,
43
- :actions, :migel, :orphan,
44
- :infos, :packs, :infos_zur_rose,
45
- :ean14, :tag_suffix,
46
- :companies, :people,
47
- :xsd
44
+ :actions, :migel, :orphan,
45
+ :infos, :packs, :infos_zur_rose,
46
+ :ean14, :tag_suffix,
47
+ :companies, :people,
48
+ :xsd
48
49
  def initialize(args = {})
49
- @options = args
50
- @subject = nil
51
- @refdata = {}
52
- @items = {} # Spezailitäteniste: SL-Items from Preparations.xml in BAG, using GTINS as key
53
- @flags = {}
54
- @lppvs = {}
55
- @infos = {}
56
- @packs = {}
57
- @migel = {}
58
- @infos_zur_rose ||= {}
59
- @actions = []
60
- @orphan = []
61
- @ean14 = false
62
- @companies = []
63
- @people = []
50
+ @options = args
51
+ @subject = nil
52
+ @refdata = {}
53
+ @items = {} # Spezailitäteniste: SL-Items from Preparations.xml in BAG, using GTINS as key
54
+ @flags = {}
55
+ @lppvs = {}
56
+ @infos = {}
57
+ @packs = {}
58
+ @migel = {}
59
+ @infos_zur_rose ||= {}
60
+ @actions = []
61
+ @orphan = []
62
+ @ean14 = false
63
+ @companies = []
64
+ @people = []
64
65
  @tag_suffix = nil
65
66
  @pharmacode = {} # index pharmacode => item
66
67
  if block_given?
67
68
  yield self
68
69
  end
69
70
  end
70
- def to_xml(subject=nil)
71
+
72
+ def to_xml(subject = nil)
71
73
  Oddb2xml.log "to_xml subject #{subject || @subject}"
72
74
  if subject
73
- self.send('build_' + subject.to_s)
75
+ send("build_" + subject.to_s)
74
76
  elsif @subject
75
- self.send('build_' + @subject.to_s)
77
+ send("build_" + @subject.to_s)
76
78
  end
77
79
  end
78
- def to_dat(subject=nil)
79
- Oddb2xml.log "to_dat subject #{subject ? subject.to_s : @subject.to_s} for #{self.class}"
80
+
81
+ def to_dat(subject = nil)
82
+ Oddb2xml.log "to_dat subject #{subject ? subject.to_s : @subject.to_s} for #{self.class}"
80
83
  if subject
81
- self.send('build_' + subject.to_s)
84
+ send("build_" + subject.to_s)
82
85
  elsif @subject
83
- self.send('build_' + @subject.to_s)
86
+ send("build_" + @subject.to_s)
84
87
  end
85
88
  end
86
- private
87
- def prepare_articles(reset=false)
89
+
90
+ private_class_method
91
+
92
+ def prepare_articles(reset = false)
88
93
  @articles = nil if reset
89
94
  unless @articles
90
- Oddb2xml.log("prepare_articles starting with #{@articles ? @articles.size : 'no'} articles.")
95
+ Oddb2xml.log("prepare_articles starting with #{@articles ? @articles.size : "no"} articles.")
91
96
  @articles = []
92
97
  @refdata.each do |ean13, obj|
93
- if migel = @migel[ean13]
94
- # delete duplicates
95
- @migel[ean13] = nil
96
- end unless SkipMigelDownloader
97
- if seq = @items[obj[:ean13]]
98
+ unless SKIP_MIGEL_DOWNLOADER
99
+ if @migel[ean13]
100
+ # delete duplicates
101
+ @migel[ean13] = nil
102
+ end
103
+ end
104
+ if (seq = @items[obj[:ean13]])
98
105
  obj[:seq] = seq.clone
99
106
  end
100
107
  @articles << obj
101
108
  @pharmacode[obj[:pharmacode]] = obj
102
109
  end
103
110
  # add
104
- @migel.values.compact.each do |migel|
105
- next unless migel[:pharmacode]
106
- entry = {
107
- :ean13 => migel[:ean13],
108
- :pharmacode => migel[:pharmacode],
109
- :stat_date => '',
110
- :desc_de => migel[:desc_de],
111
- :desc_fr => migel[:desc_fr],
112
- :atc_code => '',
113
- :quantity => migel[:quantity],
114
- :company_ean => migel[:company_ean],
115
- :company_name => migel[:company_name],
116
- :migel => true,
111
+ unless SKIP_MIGEL_DOWNLOADER
112
+ @migel.values.compact.each do |migel|
113
+ next unless migel[:pharmacode]
114
+ entry = {
115
+ ean13: migel[:ean13],
116
+ pharmacode: migel[:pharmacode],
117
+ stat_date: "",
118
+ desc_de: migel[:desc_de],
119
+ desc_fr: migel[:desc_fr],
120
+ atc_code: "",
121
+ quantity: migel[:quantity],
122
+ company_ean: migel[:company_ean],
123
+ company_name: migel[:company_name],
124
+ migel: true
117
125
  }
118
- @articles << entry
119
- end unless SkipMigelDownloader
120
- nrAdded = 0
126
+ @articles << entry
127
+ end
128
+ end
129
+ nr_added = 0
121
130
  if @options[:extended] || @options[:artikelstamm]
122
131
  Oddb2xml.log("prepare_articles extended prepare_local_index having already #{@articles.size} articles")
123
- nrItems = 0
132
+ nr_items = 0
124
133
  @infos_zur_rose.each do |ean13, info|
125
- nrItems += 1
134
+ nr_items += 1
126
135
  pharmacode = info[:pharmacode]
127
136
  if @pharmacode[pharmacode]
128
- @pharmacode[pharmacode][:price] = info[:price]
137
+ @pharmacode[pharmacode][:price] = info[:price]
129
138
  @pharmacode[pharmacode][:pub_price] = info[:pub_price]
130
139
  next
131
140
  end
@@ -134,20 +143,20 @@ module Oddb2xml
134
143
  existing = @refdata[ean13]
135
144
  if existing
136
145
  found = true
137
- existing[:price] = info[:price]
146
+ existing[:price] = info[:price]
138
147
  existing[:pub_price] = info[:pub_price]
139
148
  else
140
149
  entry = {
141
- :desc => info[:description],
142
- :desc_de => info[:description],
143
- :status => info[:status] == '3' ? 'I' : 'A', # from ZurRose, we got 1,2 or 3 means aktive, aka available in trade
144
- :atc_code => '',
145
- :ean13 => ean13,
146
- :pharmacode => pharmacode,
147
- :price => info[:price],
148
- :pub_price => info[:pub_price],
149
- :type => info[:type],
150
- }
150
+ desc: info[:description],
151
+ desc_de: info[:description],
152
+ status: info[:status] == "3" ? "I" : "A", # from ZurRose, we got 1,2 or 3 means aktive, aka available in trade
153
+ atc_code: "",
154
+ ean13: ean13,
155
+ pharmacode: pharmacode,
156
+ price: info[:price],
157
+ pub_price: info[:pub_price],
158
+ type: info[:type]
159
+ }
151
160
  if pharmacode
152
161
  @refdata[pharmacode] = entry
153
162
  else
@@ -155,15 +164,16 @@ module Oddb2xml
155
164
  end
156
165
  obj = entry
157
166
  end
158
- if not found and obj.size > 0
167
+ if !found && (obj.size > 0)
159
168
  @articles << obj unless @options[:artikelstamm]
160
- nrAdded += 1
169
+ nr_added += 1
161
170
  end
162
171
  end
163
172
  end
164
173
  end
165
- Oddb2xml.log("prepare_articles done. Added #{nrAdded} prices. Total #{@articles.size}")
174
+ Oddb2xml.log("prepare_articles done. Added #{nr_added} prices. Total #{@articles.size}")
166
175
  end
176
+
167
177
  def prepare_substances
168
178
  unless @substances
169
179
  Oddb2xml.log("prepare_substances from #{@items.size} items")
@@ -177,9 +187,10 @@ module Oddb2xml
177
187
  @substances.uniq!
178
188
  @substances.sort!
179
189
  Oddb2xml.log("prepare_substances done. Total #{@substances.size} from #{@items.size} items")
180
- exit 2 if (@options[:extended] || @options[:artikelstamm]) and @substances.size == 0
190
+ exit 2 if (@options[:extended] || @options[:artikelstamm]) && (@substances.size == 0)
181
191
  end
182
192
  end
193
+
183
194
  def prepare_limitations
184
195
  unless @limitations
185
196
  Oddb2xml.log("prepare_limitations from #{@items.size} items")
@@ -193,10 +204,11 @@ module Oddb2xml
193
204
  # ID is no longer fixed TAG (swissmedicNo8, swissmedicNo5, pharmacode)
194
205
  # limitation.xml needs all duplicate entries by this keys.
195
206
  limitations.uniq! { |lim| lim[:id].to_s + lim[:code] + lim[:type] }
196
- @limitations = limitations.sort_by {|lim| lim[:code] }
207
+ @limitations = limitations.sort_by { |lim| lim[:code] }
197
208
  Oddb2xml.log("prepare_limitations done. Total #{@limitations.size} from #{@items.size} items")
198
209
  end
199
210
  end
211
+
200
212
  def prepare_interactions
201
213
  unless @interactions
202
214
  @interactions = []
@@ -205,60 +217,61 @@ module Oddb2xml
205
217
  end
206
218
  end
207
219
  end
220
+
208
221
  def prepare_codes
209
- unless @codes
210
- @codes = {
211
- 'X' => {:int => 11, :txt => 'Kontraindiziert'},
212
- 'D' => {:int => 13, :txt => 'Kombination meiden'},
213
- 'C' => {:int => 14, :txt => 'Monitorisieren'},
214
- 'B' => {:int => 15, :txt => 'Vorsichtsmassnahmen'},
215
- 'A' => {:int => 16, :txt => 'keine Massnahmen'}
216
- }
217
- end
222
+ @codes ||= {
223
+ "X" => {int: 11, txt: "Kontraindiziert"},
224
+ "D" => {int: 13, txt: "Kombination meiden"},
225
+ "C" => {int: 14, txt: "Monitorisieren"},
226
+ "B" => {int: 15, txt: "Vorsichtsmassnahmen"},
227
+ "A" => {int: 16, txt: "keine Massnahmen"}
228
+ }
218
229
  end
230
+
219
231
  def prepare_products
220
232
  unless @products
221
233
  @products = {}
222
234
  if @chapter70items
223
235
  Chapter70xtractor::LIMITATIONS.each do |key, desc_de|
224
236
  puts "Chapter70: Adding lim #{key} #{desc_de}" if $VERBOSE
225
- @limitations<< {:code => key,
226
- :id => ( key.eql?('L') ? '70.02' :'70.01'),
227
- :desc_de => desc_de,
228
- :desc_fr => '',
229
- :chap70 => true,
230
- }
237
+ @limitations << {code: key,
238
+ id: (key.eql?("L") ? "70.02" : "70.01"),
239
+ desc_de: desc_de,
240
+ desc_fr: "",
241
+ chap70: true}
231
242
  end
232
243
  @chapter70items.values.each do |item|
233
244
  next unless item[:limitation] && item[:limitation].length > 0
234
- rose = @infos_zur_rose.values.find {|x| x[:pharmacode] && x[:pharmacode].eql?(item[:pharmacode])}
235
- ean13 = rose[:ean13] if rose
236
- ean13 ||= '9999'+item[:pharmacode]
245
+ rose = @infos_zur_rose.values.find { |x| x[:pharmacode]&.eql?(item[:pharmacode]) }
246
+ ean13 = rose[:ean13] if rose
247
+ ean13 ||= "9999" + item[:pharmacode]
237
248
  prodno = item[:pharmacode]
238
249
  obj = {
239
- :chapter70 => true,
240
- :ean13 => ean13,
241
- :description => item[:description],
242
- :code => item[:limitation], # LIMNAMEBAG
250
+ chapter70: true,
251
+ ean13: ean13,
252
+ description: item[:description],
253
+ code: item[:limitation] # LIMNAMEBAG
243
254
  }
244
255
  @products[prodno] = obj
245
256
  puts "Chapter70: Adding product #{ean13} #{obj}" if $VERBOSE
246
257
  end
247
258
  end
248
259
  @refdata.each_pair do |ean13, item|
249
- next if item and item.is_a?(Hash) and item[:atc_code] and /^Q/i.match(item[:atc_code])
250
- next if item[:prodno] and @products[item[:prodno]]
260
+ next if item&.is_a?(Hash) && item[:atc_code] && /^Q/i.match(item[:atc_code])
261
+ next if item[:prodno] && @products[item[:prodno]]
262
+ refdata_atc = item[:atc_code]
251
263
  obj = {
252
- :seq => @items[ean13] ? @items[ean13] : @items[item[:ean13]],
253
- :pac => nil,
254
- :no8 => nil,
255
- :ean13 => item[:ean13],
256
- :atc => item[:atc_code],
257
- :ith => '',
258
- :siz => '',
259
- :eht => '',
260
- :sub => '',
261
- :comp => '',
264
+ seq: @items[ean13] || @items[item[:ean13]],
265
+ pac: nil,
266
+ no8: nil,
267
+ ean13: item[:ean13],
268
+ atc: refdata_atc,
269
+ ith: "",
270
+ siz: "",
271
+ eht: "",
272
+ sub: "",
273
+ comp: "",
274
+ data_origin: "refdata-product"
262
275
  }
263
276
  # obj[:pexf_refdata] = item[:price]
264
277
  # obj[:ppub_refdata] = item[:pub_price=]
@@ -266,6 +279,15 @@ module Oddb2xml
266
279
  if obj[:ean13] # via EAN-Code
267
280
  obj[:no8] = obj[:ean13].to_s[4..11]
268
281
  end
282
+ swissmedic_pack = @packs[item[:no8]]
283
+ if swissmedic_pack
284
+ swissmedic_atc = swissmedic_pack[:atc_code]
285
+ if swissmedic_atc && swissmedic_atc.length >= 3 && (refdata_atc.nil? || !refdata_atc.eql?(swissmedic_atc))
286
+ puts "WARNING: #{ean13} ATC-code #{swissmedic_atc} from swissmedic overrides #{refdata_atc} one from refdata #{item[:desc_de]}"
287
+ item[:data_origin] += "-swissmedic-ATC"
288
+ item[:atc] = swissmedic_atc
289
+ end
290
+ end
269
291
  if obj[:no8] && (ppac = @packs[obj[:no8]]) && # Packungen.xls
270
292
  !ppac[:is_tier]
271
293
  # If RefData does not have EAN
@@ -273,7 +295,7 @@ module Oddb2xml
273
295
  obj[:ean13] = ppac[:ean13]
274
296
  end
275
297
  # If RefData dose not have ATC-Code
276
- if obj[:atc].nil? or obj[:atc].empty?
298
+ if obj[:atc].nil? || obj[:atc].empty?
277
299
  obj[:atc] = ppac[:atc_code].to_s
278
300
  end
279
301
  obj[:ith] = ppac[:ith_swissmedic]
@@ -285,7 +307,7 @@ module Oddb2xml
285
307
  obj[:price] = item[:price]
286
308
  obj[:pub_price] = item[:pub_price]
287
309
 
288
- if obj[:ean13].to_s[0..3] == '7680'
310
+ if obj[:ean13].to_s[0..3] == "7680"
289
311
  if item[:prodno]
290
312
  @products[item[:prodno]] = obj
291
313
  else
@@ -296,118 +318,118 @@ module Oddb2xml
296
318
  end
297
319
  @products
298
320
  end
321
+
299
322
  def build_substance
300
323
  prepare_substances
301
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
324
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
302
325
  xml.doc.tag_suffix = @tag_suffix
303
- datetime = Time.new.strftime('%FT%T%z')
304
326
  xml.SUBSTANCE(
305
327
  XML_OPTIONS
306
328
  ) {
307
329
  Oddb2xml.log "build_substance #{@substances.size} substances"
308
- exit 2 if (@options[:extended] || @options[:artikelstamm]) and @substances.size == 0
309
- nbr_records = 0
310
- @substances.each_with_index do |sub_name, i|
311
- xml.SB('DT' => '') do
330
+ exit 2 if (@options[:extended] || @options[:artikelstamm]) && (@substances.size == 0)
331
+ nbr_records = 0
332
+ @substances.each_with_index do |sub_name, i|
333
+ xml.SB("DT" => "") do
312
334
  xml.SUBNO((i + 1).to_i)
313
- #xml.NAMD
314
- #xml.ANAMD
315
- #xml.NAMF
335
+ # xml.NAMD
336
+ # xml.ANAMD
337
+ # xml.NAMF
316
338
  xml.NAML sub_name
317
339
  nbr_records += 1
318
340
  end
319
341
  end
320
342
  xml.RESULT {
321
- xml.OK_ERROR 'OK'
343
+ xml.OK_ERROR "OK"
322
344
  xml.NBR_RECORD nbr_records
323
- xml.ERROR_CODE ''
324
- xml.MESSAGE ''
345
+ xml.ERROR_CODE ""
346
+ xml.MESSAGE ""
325
347
  }
326
348
  }
327
349
  end
328
- Oddb2xml.add_hash(_builder.to_xml)
350
+ Oddb2xml.add_hash(a_builder.to_xml)
329
351
  end
352
+
330
353
  def build_limitation
331
354
  prepare_limitations
332
355
  Oddb2xml.log "build_limitation #{@limitations.size} limitations"
333
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
356
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
334
357
  xml.doc.tag_suffix = @tag_suffix
335
- datetime = Time.new.strftime('%FT%T%z')
336
358
  xml.LIMITATION(XML_OPTIONS) do
337
- nbr_records = 0
338
- @limitations.each do |lim|
339
- if lim[:id].empty?
340
- puts "Skipping empty id of #{lim}"
341
- next
342
- end
343
- xml.LIM('DT' => '') do
359
+ nbr_records = 0
360
+ @limitations.each do |lim|
361
+ if lim[:id].empty?
362
+ puts "Skipping empty id of #{lim}"
363
+ next
364
+ end
365
+ xml.LIM("DT" => "") do
344
366
  case lim[:key]
345
367
  when :swissmedic_number8
346
368
  xml.SwissmedicNo8 lim[:id]
347
369
  when :swissmedic_number5
348
370
  xml.SwissmedicNo5 lim[:id]
349
371
  when :pharmacode
350
- xml.Pharmacode lim[:id]
372
+ xml.Pharmacode lim[:id]
351
373
  end
352
- xml.IT lim[:it]
353
- xml.LIMTYP lim[:type]
354
- xml.LIMVAL lim[:value]
374
+ xml.IT lim[:it]
375
+ xml.LIMTYP lim[:type]
376
+ xml.LIMVAL lim[:value]
355
377
  xml.LIMNAMEBAG lim[:code] # original LIMCD
356
- xml.LIMNIV lim[:niv]
357
- xml.DSCRD lim[:desc_de]
358
- xml.DSCRF lim[:desc_fr]
359
- xml.VDAT lim[:vdate]
378
+ xml.LIMNIV lim[:niv]
379
+ xml.DSCRD lim[:desc_de]
380
+ xml.DSCRF lim[:desc_fr]
381
+ xml.VDAT lim[:vdate]
360
382
  nbr_records += 1
361
383
  end
362
384
  end
363
385
  xml.RESULT do
364
- xml.OK_ERROR 'OK'
386
+ xml.OK_ERROR "OK"
365
387
  xml.NBR_RECORD nbr_records
366
- xml.ERROR_CODE ''
367
- xml.MESSAGE ''
388
+ xml.ERROR_CODE ""
389
+ xml.MESSAGE ""
368
390
  end
369
391
  end
370
392
  end
371
- Oddb2xml.add_hash(_builder.to_xml)
393
+ Oddb2xml.add_hash(a_builder.to_xml)
372
394
  end
395
+
373
396
  def build_interaction
374
397
  prepare_interactions
375
398
  prepare_codes
376
399
  nbr_records = 0
377
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
400
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
378
401
  xml.doc.tag_suffix = @tag_suffix
379
- datetime = Time.new.strftime('%FT%T%z')
380
402
  xml.INTERACTION(XML_OPTIONS) {
381
403
  Oddb2xml.log "build_interaction #{@interactions.size} interactions"
382
- @interactions.sort_by{|ix| ix[:ixno] }.each do |ix|
383
- xml.IX('DT' => '') {
384
- xml.IXNO ix[:ixno]
385
- xml.TITD ix[:title]
386
- #xml.TITF
404
+ @interactions.sort_by { |ix| ix[:ixno] }.each do |ix|
405
+ xml.IX("DT" => "") {
406
+ xml.IXNO ix[:ixno]
407
+ xml.TITD ix[:title]
408
+ # xml.TITF
387
409
  xml.GRP1D ix[:atc1]
388
- #xml.GRP1F
410
+ # xml.GRP1F
389
411
  xml.GRP2D ix[:atc2]
390
- #xml.GRP2F
391
- xml.EFFD ix[:effect]
392
- #xml.EFFF
393
- if @codes and ix[:grad]
394
- if dict = @codes[ix[:grad].upcase]
395
- xml.RLV dict[:int]
412
+ # xml.GRP2F
413
+ xml.EFFD ix[:effect]
414
+ # xml.EFFF
415
+ if @codes && ix[:grad]
416
+ if (dict = @codes[ix[:grad].upcase])
417
+ xml.RLV dict[:int]
396
418
  xml.RLVD dict[:txt]
397
- #xml.RLVF
419
+ # xml.RLVF
398
420
  end
399
421
  end
400
- #xml.EFFTXTD
401
- #xml.EFFTXTF
422
+ # xml.EFFTXTD
423
+ # xml.EFFTXTF
402
424
  xml.MECHD ix[:mechanism]
403
- #xml.MECHF
425
+ # xml.MECHF
404
426
  xml.MEASD ix[:measures]
405
- #xml.MEASF
406
- #xml.REMD
407
- #xml.REMF
408
- #xml.LIT
427
+ # xml.MEASF
428
+ # xml.REMD
429
+ # xml.REMF
430
+ # xml.LIT
409
431
  xml.DEL false
410
- #xml.IXMCH {
432
+ # xml.IXMCH {
411
433
  # xml.TYP
412
434
  # xml.TYPD
413
435
  # xml.TYPF
@@ -416,61 +438,61 @@ module Oddb2xml
416
438
  # xml.CDF
417
439
  # xml.TXTD
418
440
  # xml.TXTF
419
- #}
441
+ # }
420
442
  nbr_records += 1
421
443
  }
422
444
  end
423
445
  xml.RESULT {
424
- xml.OK_ERROR 'OK'
446
+ xml.OK_ERROR "OK"
425
447
  xml.NBR_RECORD nbr_records
426
- xml.ERROR_CODE ''
427
- xml.MESSAGE ''
448
+ xml.ERROR_CODE ""
449
+ xml.MESSAGE ""
428
450
  }
429
451
  }
430
452
  end
431
- Oddb2xml.add_hash(_builder.to_xml)
453
+ Oddb2xml.add_hash(a_builder.to_xml)
432
454
  end
455
+
433
456
  def build_code
434
457
  prepare_codes
435
458
  nbr_records = 0
436
459
  Oddb2xml.log "build_code #{@codes.size} codes"
437
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
460
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
438
461
  xml.doc.tag_suffix = @tag_suffix
439
- datetime = Time.new.strftime('%FT%T%z')
440
462
  xml.CODE(XML_OPTIONS) {
441
463
  @codes.each_pair do |val, definition|
442
- xml.CD('DT' => '') {
443
- xml.CDTYP definition[:int]
444
- xml.CDVAL val
445
- xml.DSCRSD definition[:txt]
446
- #xml.DSCRSF
447
- #xml.DSCRMD
448
- #xml.DSCRMF
449
- #xml.DSCRD
450
- #xml.DSCRF
451
- xml.DEL false
464
+ xml.CD("DT" => "") {
465
+ xml.CDTYP definition[:int]
466
+ xml.CDVAL val
467
+ xml.DSCRSD definition[:txt]
468
+ # xml.DSCRSF
469
+ # xml.DSCRMD
470
+ # xml.DSCRMF
471
+ # xml.DSCRD
472
+ # xml.DSCRF
473
+ xml.DEL false
452
474
  nbr_records += 1
453
475
  }
454
476
  end
455
477
  xml.RESULT {
456
- xml.OK_ERROR 'OK'
478
+ xml.OK_ERROR "OK"
457
479
  xml.NBR_RECORD nbr_records
458
- xml.ERROR_CODE ''
459
- xml.MESSAGE ''
480
+ xml.ERROR_CODE ""
481
+ xml.MESSAGE ""
460
482
  }
461
483
  }
462
484
  end
463
- Oddb2xml.add_hash(_builder.to_xml)
485
+ Oddb2xml.add_hash(a_builder.to_xml)
464
486
  end
487
+
465
488
  def add_missing_products_from_swissmedic(add_to_products = false)
466
489
  Oddb2xml.log "build_product add_missing_products_from_swissmedic. Starting with #{@products.size} products and #{@packs.size} @packs"
467
490
  ean13_to_product = {}
468
- @products.each{
469
- |ean13, obj|
470
- ean13_to_product[ean13] = obj
471
- obj[:pharmacode] ||= @refdata[ean13][:pharmacode] if @refdata[ean13]
491
+ @products.each { |ean13, obj|
492
+ ean13_to_product[ean13] = obj
493
+ obj[:pharmacode] ||= @refdata[ean13][:pharmacode] if @refdata[ean13]
472
494
  }
473
- ausgabe = File.open(File.join(WorkDir, 'missing_in_refdata.txt'), 'w+')
495
+ ausgabe = File.open(File.join(WORK_DIR, "missing_in_refdata.txt"), "w+")
474
496
  size_old = ean13_to_product.size
475
497
  @missing = []
476
498
  Oddb2xml.log "build_product add_missing_products_from_swissmedic. Imported #{size_old} ean13_to_product from @products. Checking #{@packs.size} @packs"
@@ -478,49 +500,48 @@ module Oddb2xml
478
500
  ean = de_idx[1][:ean13]
479
501
  next if @refdata[ean]
480
502
  list_code = de_idx[1][:list_code]
481
- next if list_code and /Tierarzneimittel/.match(list_code)
503
+ next if list_code && /Tierarzneimittel/.match(list_code)
482
504
  if add_to_products
483
- @products[ean] = { :seq=>
484
- {:name_de => de_idx.last[:sequence_name],
485
- :desc_de => '',
486
- :name_fr => '',
487
- :desc_fr => '',
488
- :atc_code => de_idx.last[:atc_code],
489
- },
490
- :pac=>nil,
491
- :sequence_name => de_idx.last[:sequence_name],
492
- :no8=> de_idx.last[:prodno],
493
- :ean13=> ean,
494
- :atc=> de_idx.last[:atc_code],
495
- :ith=> de_idx.last[:ith_swissmedic],
496
- :siz=> de_idx.last[:package_size],
497
- :eht=> de_idx.last[:einheit_swissmedic],
498
- :sub=> de_idx.last[:substance_swissmedic],
499
- :comp=> de_idx.last[:composition_swissmedic],
500
- :drug_index => de_idx.last[:drug_index],
501
- }
505
+ @products[ean] = {seq: {name_de: de_idx.last[:sequence_name],
506
+ desc_de: "",
507
+ name_fr: "",
508
+ desc_fr: "",
509
+ atc_code: de_idx.last[:atc_code]},
510
+ pac: nil,
511
+ sequence_name: de_idx.last[:sequence_name],
512
+ no8: de_idx.last[:prodno],
513
+ ean13: ean,
514
+ atc: de_idx.last[:atc_code],
515
+ ith: de_idx.last[:ith_swissmedic],
516
+ siz: de_idx.last[:package_size],
517
+ eht: de_idx.last[:einheit_swissmedic],
518
+ sub: de_idx.last[:substance_swissmedic],
519
+ comp: de_idx.last[:composition_swissmedic],
520
+ drug_index: de_idx.last[:drug_index]}
502
521
  end
503
522
  ean13_to_product[ean] = de_idx[1]
504
523
  @missing << de_idx[1]
505
524
  ausgabe.puts "#{ean},#{de_idx[1][:sequence_name]}"
506
525
  end
507
526
  corrected_size = ean13_to_product.size
508
- Oddb2xml.log "build_product add_missing_products_from_swissmedic. Added #{(corrected_size - size_old)} corrected_size #{corrected_size} size_old #{size_old} ean13_to_product."
527
+ Oddb2xml.log "build_product add_missing_products_from_swissmedic. Added #{corrected_size - size_old} corrected_size #{corrected_size} size_old #{size_old} ean13_to_product."
509
528
  end
510
529
 
511
530
  def build_product
512
- def check_name(obj, lang = :de)
513
- ean = obj[:ean13]
514
- refdata = @refdata[ean]
515
- if lang == :de
516
- name = (refdata && refdata[:desc_de]) ? refdata[:desc_de] : obj[:sequence_name]
517
- elsif lang == :fr
518
- name = (refdata && refdata[:desc_fr]) ? refdata[:desc_fr] : obj[:sequence_name]
519
- else
520
- return false
531
+ self.class.class_eval do
532
+ def check_name(obj, lang = :de)
533
+ ean = obj[:ean13]
534
+ refdata = @refdata[ean]
535
+ if lang == :de
536
+ name = refdata && refdata[:desc_de] ? refdata[:desc_de] : obj[:sequence_name]
537
+ elsif lang == :fr
538
+ name = refdata && refdata[:desc_fr] ? refdata[:desc_fr] : obj[:sequence_name]
539
+ else
540
+ return false
541
+ end
542
+ return false if !name || name.empty? || name.length < 3
543
+ name[0..119] # limit to maximal 120 chars as specified in the XSD
521
544
  end
522
- return false if !name || name.empty? || name.length < 3
523
- name[0..119] # limit to maximal 120 chars as specified in the XSD
524
545
  end
525
546
  prepare_substances
526
547
  prepare_products
@@ -528,303 +549,297 @@ module Oddb2xml
528
549
  prepare_codes
529
550
  add_missing_products_from_swissmedic
530
551
  nbr_products = 0
531
- Oddb2xml.log "build_product #{@products.size+@missing.size} products"
532
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
552
+ Oddb2xml.log "build_product #{@products.size + @missing.size} products"
553
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
533
554
  xml.doc.tag_suffix = @tag_suffix
534
- datetime = Time.new.strftime('%FT%T%z')
535
555
  emitted = []
536
556
  xml.PRODUCT(XML_OPTIONS) {
537
- list = []
538
557
  @missing.each do |obj|
539
558
  ean = obj[:ean13]
540
559
  next unless check_name(obj, :de)
541
560
  next unless check_name(obj, :fr)
542
- next if /^Q/i.match(obj[:atc])
561
+ next if /^Q/i.match?(obj[:atc])
543
562
  if obj[:prodno]
544
563
  next if emitted.index(obj[:prodno])
545
564
  emitted << obj[:prodno]
546
565
  end
547
- xml.PRD('DT' => obj[:last_change]) {
548
- nbr_products += 1
549
- xml.GTIN ean
550
- xml.PRODNO obj[:prodno] if obj[:prodno]
551
- xml.DSCRD check_name(obj, :de)
552
- xml.DSCRF check_name(obj, :fr)
553
- xml.ATC obj[:atc_code] unless obj[:atc_code].empty?
554
- xml.IT obj[:ith_swissmedic] if obj[:ith_swissmedic]
555
- xml.CPT
556
- xml.PackGrSwissmedic obj[:package_size] if obj[:package_size]
557
- xml.EinheitSwissmedic obj[:einheit_swissmedic] if obj[:einheit_swissmedic]
558
- xml.SubstanceSwissmedic obj[:substance_swissmedic] if obj[:substance_swissmedic]
559
- xml.CompositionSwissmedic obj[:composition_swissmedic] if obj[:composition_swissmedic]
560
- }
566
+ xml.PRD("DT" => obj[:last_change]) {
567
+ nbr_products += 1
568
+ xml.GTIN ean
569
+ xml.PRODNO obj[:prodno] if obj[:prodno]
570
+ xml.DSCRD check_name(obj, :de)
571
+ xml.DSCRF check_name(obj, :fr)
572
+ xml.ATC obj[:atc_code] unless obj[:atc_code].empty?
573
+ xml.IT obj[:ith_swissmedic] if obj[:ith_swissmedic]
574
+ xml.CPT
575
+ xml.PackGrSwissmedic obj[:package_size] if obj[:package_size]
576
+ xml.EinheitSwissmedic obj[:einheit_swissmedic] if obj[:einheit_swissmedic]
577
+ xml.SubstanceSwissmedic obj[:substance_swissmedic] if obj[:substance_swissmedic]
578
+ xml.CompositionSwissmedic obj[:composition_swissmedic] if obj[:composition_swissmedic]
579
+ }
561
580
  end
562
581
  @products.sort.to_h.each do |ean13, obj|
563
- next if /^Q/i.match(obj[:atc])
582
+ next if /^Q/i.match?(obj[:atc])
564
583
  seq = obj[:seq]
565
- ean = obj[:ean13]
566
- next unless check_name(obj, :de)
567
- next unless check_name(obj, :fr)
568
- xml.PRD('DT' => obj[:last_change]) do
584
+ ean = obj[:ean13]
585
+ next unless check_name(obj, :de)
586
+ next unless check_name(obj, :fr)
587
+ xml.PRD("DT" => obj[:last_change]) do
569
588
  nbr_products += 1
570
589
  xml.GTIN ean
571
- ppac = ((_ppac = @packs[ean.to_s[4..11]] and !_ppac[:is_tier]) ? _ppac : {})
572
- unless ppac
573
- ppac = @packs.find{|pac| pac.ean == ean }.first
574
- end
575
- xml.PRODNO ppac[:prodno] if ppac[:prodno] and !ppac[:prodno].empty?
576
- xml.DSCRD check_name(obj, :de)
577
- xml.DSCRF check_name(obj, :fr)
578
- #xml.BNAMD
579
- #xml.BNAMF
580
- #xml.ADNAMD
581
- #xml.ADNAMF
582
- #xml.SIZE
590
+ ppac = ((a_ppac = @packs[ean.to_s[4..11]]) && !a_ppac[:is_tier] ? a_ppac : {})
591
+ ppac ||= @packs.find { |pac| pac.ean == ean }.first
592
+ xml.PRODNO ppac[:prodno] if ppac[:prodno] && !ppac[:prodno].empty?
593
+ xml.DSCRD check_name(obj, :de)
594
+ xml.DSCRF check_name(obj, :fr)
595
+ # xml.BNAMD
596
+ # xml.BNAMF
597
+ # xml.ADNAMD
598
+ # xml.ADNAMF
599
+ # xml.SIZE
583
600
  if seq
584
- xml.ADINFD seq[:comment_de] unless seq[:comment_de] && seq[:comment_de].empty?
585
- xml.ADINFF seq[:comment_fr] unless seq[:comment_fr] && seq[:comment_fr].empty?
586
- xml.GENCD seq[:org_gen_code] unless seq[:org_gen_code] && seq[:org_gen_code].empty?
601
+ xml.ADINFD seq[:comment_de] unless seq[:comment_de] && seq[:comment_de].empty?
602
+ xml.ADINFF seq[:comment_fr] unless seq[:comment_fr] && seq[:comment_fr].empty?
603
+ xml.GENCD seq[:org_gen_code] unless seq[:org_gen_code] && seq[:org_gen_code].empty?
587
604
  end
588
- #xml.GENGRP
605
+ # xml.GENGRP
589
606
  xml.ATC obj[:atc] unless obj[:atc].empty?
590
- xml.IT obj[:ith] unless obj[:ith].empty?
591
- #xml.ITBAG
592
- #xml.KONO
593
- #xml.TRADE
594
- #xml.PRTNO
595
- #xml.MONO
596
- #xml.CDGALD
597
- #xml.CDGALF
598
- #xml.FORMD
599
- #xml.FORMF
600
- #xml.DOSE
601
- #xml.DOSEU
602
- #xml.DRGFD
603
- #xml.DRGFF
607
+ xml.IT obj[:ith] unless obj[:ith].empty?
608
+ # xml.ITBAG
609
+ # xml.KONO
610
+ # xml.TRADE
611
+ # xml.PRTNO
612
+ # xml.MONO
613
+ # xml.CDGALD
614
+ # xml.CDGALF
615
+ # xml.FORMD
616
+ # xml.FORMF
617
+ # xml.DOSE
618
+ # xml.DOSEU
619
+ # xml.DRGFD
620
+ # xml.DRGFF
604
621
  obj[:no8] =~ /(\d{5})(\d{3})/
605
622
  if @orphan.include?($1.to_s)
606
623
  xml.ORPH true
607
624
  end
608
- #xml.BIOPHA
609
- #xml.BIOSIM
610
- #xml.BFS
611
- #xml.BLOOD
612
- #xml.MSCD # always empty
613
- #xml.DEL
625
+ # xml.BIOPHA
626
+ # xml.BIOSIM
627
+ # xml.BFS
628
+ # xml.BLOOD
629
+ # xml.MSCD # always empty
630
+ # xml.DEL
614
631
  xml.CPT {
615
- #xml.CPTLNO
616
- #xml.CNAMED
617
- #xml.CNAMEF
618
- #xml.IDXIND
619
- #xml.DDDD
620
- #xml.DDDU
621
- #xml.DDDA
622
- #xml.IDXIA
623
- #xml.IXREL
624
- #xml.GALF
625
- #xml.DRGGRPCD
626
- #xml.PRBSUIT
627
- #xml.CSOLV
628
- #xml.CSOLVQ
629
- #xml.CSOLVQU
630
- #xml.PHVAL
631
- #xml.LSPNSOL
632
- #xml.APDURSOL
633
- #xml.EXCIP
634
- #xml.EXCIPQ
635
- #xml.EXCIPCD
636
- #xml.EXCIPCF
637
- #xml.PQTY
638
- #xml.PQTYU
639
- #xml.SIZEMM
640
- #xml.WEIGHT
641
- #xml.LOOKD
642
- #xml.LOOKF
643
- #xml.IMG2
632
+ # xml.CPTLNO
633
+ # xml.CNAMED
634
+ # xml.CNAMEF
635
+ # xml.IDXIND
636
+ # xml.DDDD
637
+ # xml.DDDU
638
+ # xml.DDDA
639
+ # xml.IDXIA
640
+ # xml.IXREL
641
+ # xml.GALF
642
+ # xml.DRGGRPCD
643
+ # xml.PRBSUIT
644
+ # xml.CSOLV
645
+ # xml.CSOLVQ
646
+ # xml.CSOLVQU
647
+ # xml.PHVAL
648
+ # xml.LSPNSOL
649
+ # xml.APDURSOL
650
+ # xml.EXCIP
651
+ # xml.EXCIPQ
652
+ # xml.EXCIPCD
653
+ # xml.EXCIPCF
654
+ # xml.PQTY
655
+ # xml.PQTYU
656
+ # xml.SIZEMM
657
+ # xml.WEIGHT
658
+ # xml.LOOKD
659
+ # xml.LOOKF
660
+ # xml.IMG2
644
661
  if seq
645
662
  seq[:substances].each do |sub|
646
663
  xml.CPTCMP {
647
- xml.LINE sub[:index] unless sub[:index].empty?
664
+ xml.LINE sub[:index] unless sub[:index].empty?
648
665
  xml.SUBNO(@substances.index(sub[:name]) + 1) if @substances.include?(sub[:name])
649
- xml.QTY sub[:quantity] unless sub[:quantity].empty?
650
- xml.QTYU sub[:unit] unless sub[:unit].empty?
651
- #xml.WHK
666
+ xml.QTY sub[:quantity] unless sub[:quantity].empty?
667
+ xml.QTYU sub[:unit] unless sub[:unit].empty?
668
+ # xml.WHK
652
669
  }
653
670
  end
654
671
  @interactions.each do |ix|
655
672
  if [ix[:act1], ix[:act2]].include?(seq[:atc_code])
656
673
  xml.CPTIX {
657
674
  xml.IXNO ix[:ixno]
658
- #xml.GRP
659
- xml.RLV @codes[ix[:grad]]
675
+ # xml.GRP
676
+ xml.RLV @codes[ix[:grad]]
660
677
  }
661
678
  end
662
679
  end
663
680
  end
664
- #xml.CPTROA {
665
- #xml.SYSLOC
666
- #xml.ROA
667
- #}
681
+ # xml.CPTROA {
682
+ # xml.SYSLOC
683
+ # xml.ROA
684
+ # }
668
685
  }
669
- #xml.PRDICD { # currently empty
670
- #xml.ICD
671
- #xml.RTYP
672
- #xml.RSIG
673
- #xml.REMD
674
- #xml.REMF
675
- #}
676
- xml.PackGrSwissmedic obj[:siz] unless obj[:siz].empty?
677
- xml.EinheitSwissmedic obj[:eht] unless obj[:eht].empty?
686
+ # xml.PRDICD { # currently empty
687
+ # xml.ICD
688
+ # xml.RTYP
689
+ # xml.RSIG
690
+ # xml.REMD
691
+ # xml.REMF
692
+ # }
693
+ xml.PackGrSwissmedic obj[:siz] unless obj[:siz].empty?
694
+ xml.EinheitSwissmedic obj[:eht] unless obj[:eht].empty?
678
695
  xml.SubstanceSwissmedic obj[:sub] unless obj[:sub].empty?
679
696
  xml.CompositionSwissmedic obj[:comp] unless obj[:comp].empty?
680
697
  end
681
698
  end
682
699
  xml.RESULT {
683
- xml.OK_ERROR 'OK'
700
+ xml.OK_ERROR "OK"
684
701
  xml.NBR_RECORD nbr_products
685
- xml.ERROR_CODE ''
686
- xml.MESSAGE ''
702
+ xml.ERROR_CODE ""
703
+ xml.MESSAGE ""
687
704
  }
688
705
  }
689
706
  end
690
- Oddb2xml.add_hash(_builder.to_xml)
707
+ Oddb2xml.add_hash(a_builder.to_xml)
691
708
  end
692
709
 
693
710
  def prepare_calc_items(suppress_composition_parsing: false)
694
711
  @calc_items = {}
695
- packungen_xlsx = File.join(Oddb2xml::WorkDir, "swissmedic_package.xlsx")
696
- idx = 0
697
- return unless File.exists?(packungen_xlsx)
712
+ packungen_xlsx = File.join(Oddb2xml::DOWNLOADS, "swissmedic_package.xlsx")
713
+ return unless File.exist?(packungen_xlsx)
698
714
  workbook = RubyXL::Parser.parse(packungen_xlsx)
699
715
  row_nr = 0
700
716
  workbook.worksheets[0].each do |row|
701
717
  row_nr += 1
702
- next unless row and row.cells[0] and row.cells[0].value and row.cells[0].value.to_i > 0
703
- iksnr = "%05i" % row.cells[0].value.to_i
704
- seqnr = "%02d" % row.cells[1].value.to_i
718
+ next unless row && row.cells[0] && row.cells[0].value && (row.cells[0].value.to_i > 0)
719
+ iksnr = "%05i" % row.cells[0].value.to_i
705
720
  if row_nr % 250 == 0
706
- puts "#{Time.now}: At row #{row_nr} iksnr #{iksnr}";
707
- $stdout.flush
721
+ puts "#{Time.now}: At row #{row_nr} iksnr #{iksnr}"
722
+ $stdout.flush
708
723
  end
709
- ith = COLUMNS_FEBRUARY_2019.keys.index(:index_therapeuticus)
710
- seq_name = COLUMNS_FEBRUARY_2019.keys.index(:name_base)
711
- i_3 = COLUMNS_FEBRUARY_2019.keys.index(:ikscd)
712
- p_1_2 = COLUMNS_FEBRUARY_2019.keys.index(:seqnr)
713
- cat = COLUMNS_FEBRUARY_2019.keys.index(:ikscat)
714
- siz = COLUMNS_FEBRUARY_2019.keys.index(:size)
715
- atc = COLUMNS_FEBRUARY_2019.keys.index(:atc_class)
724
+ seq_name = COLUMNS_FEBRUARY_2019.keys.index(:name_base)
725
+ i_3 = COLUMNS_FEBRUARY_2019.keys.index(:ikscd)
726
+ siz = COLUMNS_FEBRUARY_2019.keys.index(:size)
727
+ atc = COLUMNS_FEBRUARY_2019.keys.index(:atc_class)
716
728
  list_code = COLUMNS_FEBRUARY_2019.keys.index(:production_science)
717
- unit = COLUMNS_FEBRUARY_2019.keys.index(:unit)
718
- sub = COLUMNS_FEBRUARY_2019.keys.index(:substances)
719
- comp = COLUMNS_FEBRUARY_2019.keys.index(:composition)
729
+ unit = COLUMNS_FEBRUARY_2019.keys.index(:unit)
730
+ sub = COLUMNS_FEBRUARY_2019.keys.index(:substances)
731
+ comp = COLUMNS_FEBRUARY_2019.keys.index(:composition)
720
732
 
721
- no8 = iksnr + sprintf('%03d',row.cells[i_3].value.to_i)
722
- name = row.cells[seq_name] ? row.cells[seq_name].value : nil
723
- atc_code = row.cells[atc] ? row.cells[atc].value : nil
724
- list_code = row.cells[list_code] ? row.cells[list_code].value : nil
725
- package_size = row.cells[siz] ? row.cells[siz].value : nil
726
- unit = row.cells[unit] ? row.cells[unit].value : nil
727
- active_substance = row.cells[sub] ? row.cells[sub].value : nil
728
- composition = row.cells[comp] ? row.cells[comp].value : nil
733
+ no8 = iksnr + sprintf("%03d", row.cells[i_3].value.to_i)
734
+ name = row.cells[seq_name] ? row.cells[seq_name].value : nil
735
+ atc_code = row.cells[atc] ? row.cells[atc].value : nil
736
+ list_code = row.cells[list_code] ? row.cells[list_code].value : nil
737
+ package_size = row.cells[siz] ? row.cells[siz].value : nil
738
+ unit = row.cells[unit] ? row.cells[unit].value : nil
739
+ active_substance = row.cells[sub] ? row.cells[sub].value : nil
740
+ composition = row.cells[comp] ? row.cells[comp].value : nil
729
741
 
730
742
  # skip veterinary product
731
- next if atc_code and /^Q/i.match(atc_code)
732
- next if list_code and /Tierarzneimittel/.match(list_code)
743
+ next if atc_code && /^Q/i.match(atc_code)
744
+ next if list_code && /Tierarzneimittel/.match(list_code)
733
745
  info = nil
734
746
  begin
735
- if suppress_composition_parsing
736
- info = Calc.new(name, package_size, unit)
747
+ info = if suppress_composition_parsing
748
+ Calc.new(name, package_size, unit)
737
749
  else
738
- info = Calc.new(name, package_size, unit, active_substance, composition)
750
+ Calc.new(name, package_size, unit, active_substance, composition)
739
751
  end
740
752
  rescue
741
753
  puts "#{Time.now}: #{row_nr} iksnr #{iksnr} rescue from Calc.new"
742
754
  end
743
- ean12 = '7680' + no8
755
+ ean12 = "7680" + no8
744
756
  ean13 = (ean12 + Oddb2xml.calc_checksum(ean12))
745
757
  @calc_items[ean13] = info
746
758
  end
747
759
  end
748
- def build_calc
749
- def emit_substance(xml, substance, emit_active=false)
750
- xml.MORE_INFO substance.more_info if substance.more_info
751
- xml.SUBSTANCE_NAME substance.name
752
- xml.IS_ACTIVE_AGENT substance.is_active_agent if emit_active
753
- if substance.dose
754
- if substance.qty.is_a?(Float) or substance.qty.is_a?(Integer)
755
- xml.QTY substance.qty
756
- xml.UNIT substance.unit
757
- else
758
- xml.DOSE_TEXT substance.dose.to_s
759
- end
760
- end
761
- if substance.chemical_substance
762
- xml.CHEMICAL_SUBSTANCE {
763
- emit_substance(xml, substance.chemical_substance)
764
- }
765
- end
766
- if substance.salts and substance.salts.size > 0
767
- xml.SALTS do
768
- substance.salts.each do |salt|
769
- xml.SALT do
770
- emit_substance(xml, salt)
771
- end
772
- end
760
+
761
+ def emit_substance(xml, substance, emit_active = false)
762
+ xml.MORE_INFO substance.more_info if substance.more_info
763
+ xml.SUBSTANCE_NAME substance.name
764
+ xml.IS_ACTIVE_AGENT substance.is_active_agent if emit_active
765
+ if substance.dose
766
+ if substance.qty.is_a?(Float) || substance.qty.is_a?(Integer)
767
+ xml.QTY substance.qty
768
+ xml.UNIT substance.unit
769
+ else
770
+ xml.DOSE_TEXT substance.dose.to_s
771
+ end
772
+ end
773
+ if substance.chemical_substance
774
+ xml.CHEMICAL_SUBSTANCE {
775
+ emit_substance(xml, substance.chemical_substance)
776
+ }
777
+ end
778
+ if substance.salts && (substance.salts.size > 0)
779
+ xml.SALTS do
780
+ substance.salts.each do |salt|
781
+ xml.SALT do
782
+ emit_substance(xml, salt)
773
783
  end
774
784
  end
785
+ end
775
786
  end
787
+ end
788
+
789
+ def build_calc
776
790
  prepare_calc_items
777
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
791
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
778
792
  xml.doc.tag_suffix = @tag_suffix
779
- datetime = Time.new.strftime('%FT%T%z')
780
793
  xml.ARTICLES(XML_OPTIONS) do
781
794
  @calc_items.each do |ean13, info|
782
- xml.ARTICLE do
783
- xml.GTIN ean13
784
- xml.NAME info.column_c
785
- xml.PKG_SIZE info.pkg_size
786
- xml.SELLING_UNITS info.selling_units
787
- xml.MEASURE info.measure # Nur wenn Lösung wen Spalte M ml, Spritze
795
+ if info&.compositions
796
+ xml.ARTICLE do
797
+ xml.GTIN ean13
798
+ xml.NAME info.column_c
799
+ xml.PKG_SIZE info.pkg_size
800
+ xml.SELLING_UNITS info.selling_units
801
+ xml.MEASURE info.measure # Nur wenn Lösung wen Spalte M ml, Spritze
788
802
 
789
- if info.galenic_form.is_a?(String)
790
- xml.GALENIC_FORM info.galenic_form
791
- xml.GALENIC_GROUP "Unknown"
792
- else
793
- xml.GALENIC_FORM info.galenic_form.description
794
- xml.GALENIC_GROUP info.galenic_group ? info.galenic_group.description : "Unknown"
795
- end
796
- xml.COMPOSITIONS do
797
- info.compositions.each do |composition|
798
- xml.COMPOSITION do
799
- xml.EXCIPIENS { emit_substance(xml, composition.excipiens) } if composition.excipiens
800
- xml.LABEL composition.label if composition.label
801
- xml.LABEL_DESCRIPTION composition.label_description if composition.label_description
802
- xml.CORRESP composition.corresp if composition.corresp
803
- if composition.substances and composition.substances.size > 0
804
- xml.SUBSTANCES do
805
- composition.substances.each { |substance| xml.SUBSTANCE { emit_substance(xml, substance, true) }}
803
+ if info.galenic_form.is_a?(String)
804
+ xml.GALENIC_FORM info.galenic_form
805
+ xml.GALENIC_GROUP "Unknown"
806
+ else
807
+ xml.GALENIC_FORM info.galenic_form.description
808
+ xml.GALENIC_GROUP info.galenic_group ? info.galenic_group.description : "Unknown"
809
+ end
810
+ xml.COMPOSITIONS do
811
+ info.compositions.each do |composition|
812
+ xml.COMPOSITION do
813
+ xml.EXCIPIENS { emit_substance(xml, composition.excipiens) } if composition.excipiens
814
+ xml.LABEL composition.label if composition.label
815
+ xml.LABEL_DESCRIPTION composition.label_description if composition.label_description
816
+ xml.CORRESP composition.corresp if composition.corresp
817
+ if composition.substances && (composition.substances.size > 0)
818
+ xml.SUBSTANCES do
819
+ composition.substances.each { |substance| xml.SUBSTANCE { emit_substance(xml, substance, true) } }
820
+ end
806
821
  end
807
822
  end
808
823
  end
809
824
  end
810
825
  end
811
- end if info and info.compositions
826
+ end
812
827
  end
813
828
  end
814
829
  end
815
830
 
816
- csv_name = File.join(WorkDir, 'oddb_calc.csv')
817
- CSV.open(csv_name, "w+", :col_sep => ';') do |csv|
818
- csv << ['gtin'] + @calc_items.values.first.headers
831
+ csv_name = File.join(WORK_DIR, "oddb_calc.csv")
832
+ CSV.open(csv_name, "w+", col_sep: ";") do |csv|
833
+ csv << ["gtin"] + @calc_items.values.first.headers
819
834
  @calc_items.each do |key, value|
820
- if value and value.to_array
821
- csv << [key] + value.to_array
835
+ if value&.to_array
836
+ csv << [key] + value.to_array
822
837
  else
823
838
  puts "key #{key.inspect} WITHOUT #{value.inspect}"
824
839
  end
825
840
  end
826
841
  end
827
- Oddb2xml.add_hash(_builder.to_xml)
842
+ Oddb2xml.add_hash(a_builder.to_xml)
828
843
  end
829
844
 
830
845
  def build_article
@@ -834,21 +849,20 @@ module Oddb2xml
834
849
  idx = 0
835
850
  nbr_records = 0
836
851
  Oddb2xml.log "build_article #{idx} of #{@articles.size} articles"
837
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
852
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
838
853
  xml.doc.tag_suffix = @tag_suffix
839
- datetime = Time.new.strftime('%FT%T%z')
840
- eans_from_refdata = @articles.collect{|refdata| refdata[:ean13] }
854
+ eans_from_refdata = @articles.collect { |refdata| refdata[:ean13] }
841
855
  eans_from_preparations = @items.keys
842
856
  missing_eans = []
843
857
  eans_from_preparations.each do |ean|
844
858
  next if ean.to_i == 0
845
- unless @articles.collect {|x| x[:ean13] }.index(ean)
859
+ unless @articles.collect { |x| x[:ean13] }.index(ean)
846
860
  item = @items[ean].clone
847
- item[:pharmacode] ||= '123456' if defined?(RSpec)
861
+ item[:pharmacode] ||= "123456" if defined?(RSpec)
848
862
  item[:ean13] = ean
849
863
  item[:_type] = :preparations_xml
850
- item[:desc_de] = item[:name_de] + ' ' + item[:desc_de]
851
- item[:desc_fr] = item[:name_fr] + ' ' + item[:desc_fr]
864
+ item[:desc_de] = item[:name_de] + " " + item[:desc_de]
865
+ item[:desc_fr] = item[:name_fr] + " " + item[:desc_fr]
852
866
  @articles << item
853
867
  end
854
868
  unless eans_from_refdata.index(ean)
@@ -856,166 +870,166 @@ module Oddb2xml
856
870
  end
857
871
  end
858
872
  xml.ARTICLE(XML_OPTIONS) {
859
- @articles.sort! { |a,b| a[:ean13] <=> b[:ean13] }
860
- @articles.each do |obj|
861
- idx += 1
862
- Oddb2xml.log "build_article #{obj[:ean13]}: #{idx} of #{@articles.size} articles" if idx % 500 == 0
863
- item = @items[obj[:ean13]]
864
- pac,no8 = nil,obj[:ean13].to_s[4..11] # BAG-XML(SL/LS)
873
+ @articles.sort! { |a, b| a[:ean13] <=> b[:ean13] }
874
+ @articles.each do |obj|
875
+ idx += 1
876
+ Oddb2xml.log "build_article #{obj[:ean13]}: #{idx} of #{@articles.size} articles" if idx % 500 == 0
877
+ pac, no8 = nil, obj[:ean13].to_s[4..11] # BAG-XML(SL/LS)
865
878
  pack_info = nil
866
879
  pack_info = @packs[no8] if no8 # info from Packungen.xlsx from swissmedic_info
867
- ppac = nil # Packungen
880
+ ppac = nil # Packungen
868
881
  ean = obj[:ean13]
869
- next if pack_info and /Tierarzneimittel/.match(pack_info[:list_code])
870
- next if obj[:desc_de] and /ad us vet/i.match(obj[:desc_de])
882
+ next if pack_info && /Tierarzneimittel/.match(pack_info[:list_code])
883
+ next if obj[:desc_de] && /ad us vet/i.match(obj[:desc_de])
871
884
  pharma_code = obj[:pharmacode]
872
885
  # ean = 0 if sprintf('%013d', ean).match(/^000000/)
873
886
  if obj[:seq]
874
887
  pac = obj[:seq][:packages][obj[:pharmacode]]
875
- pac = obj[:seq][:packages][ean] unless pac
876
- else
877
- pac = @items[ean][:packages][ean] if @items and ean and @items[ean] and @items[ean][:packages]
888
+ pac ||= obj[:seq][:packages][ean]
889
+ elsif @items && ean && @items[ean] && @items[ean][:packages]
890
+ pac = @items[ean][:packages][ean]
878
891
  end
879
892
  if no8
880
- ppac = ((_ppac = pack_info and !_ppac[:is_tier]) ? _ppac : nil)
893
+ ppac = ((a_ppac = pack_info) && !a_ppac[:is_tier] ? a_ppac : nil)
881
894
  end
882
895
  zur_rose = nil
883
896
  if !@infos_zur_rose.empty? && ean && @infos_zur_rose[ean]
884
897
  zur_rose = @infos_zur_rose[ean] # zurrose
885
898
  end
886
- xml.ART('DT' => obj[:last_change] ? obj[:last_change] : '') do
899
+ xml.ART("DT" => obj[:last_change] || "") do
887
900
  nbr_records += 1
888
- xml.REF_DATA (obj[:refdata] || @migel[pharma_code]) ? '1' : '0'
901
+ # Ignore Lint/RequireParentheses warning on next line!
902
+ xml.REF_DATA obj[:refdata] || @migel[pharma_code] ? "1" : "0"
889
903
  if obj[:pharmacode] && obj[:pharmacode].length > 0
890
- xml.PHAR obj[:pharmacode]
904
+ xml.PHAR obj[:pharmacode]
891
905
  elsif zur_rose
892
906
  puts "Adding #{zur_rose[:pharmacode]} to article GTIN #{ean}"
893
- xml.PHAR zur_rose[:pharmacode]
907
+ xml.PHAR zur_rose[:pharmacode]
894
908
  end
895
- #xml.GRPCD
896
- #xml.CDS01
897
- #xml.CDS02
909
+ # xml.GRPCD
910
+ # xml.CDS01
911
+ # xml.CDS02
898
912
  if ppac
899
- xml.SMCAT ppac[:swissmedic_category] unless ppac[:swissmedic_category].empty?
900
- xml.GEN_PRODUCTION ppac[:gen_production] unless ppac[:gen_production].empty?
901
- xml.INSULIN_CATEGORY ppac[:insulin_category] unless ppac[:insulin_category].empty?
902
- xml.DRUG_INDEX ppac[:drug_index] unless ppac[:drug_index].empty?
913
+ xml.SMCAT ppac[:swissmedic_category] unless ppac[:swissmedic_category].empty?
914
+ xml.GEN_PRODUCTION ppac[:gen_production] unless ppac[:gen_production].empty?
915
+ xml.INSULIN_CATEGORY ppac[:insulin_category] unless ppac[:insulin_category].empty?
916
+ xml.DRUG_INDEX ppac[:drug_index] unless ppac[:drug_index].empty?
903
917
  end
904
- if no8 and !no8.to_s.empty?
905
- if ean and ean.to_s[0..3] == "7680"
918
+ if no8 && !no8.to_s.empty?
919
+ if ean && (ean.to_s[0..3] == "7680")
906
920
  xml.SMNO no8.to_s
907
921
  end
908
922
  end
909
923
  if ppac
910
- xml.PRODNO ppac[:prodno] if ppac[:prodno] and !ppac[:prodno].empty?
924
+ xml.PRODNO ppac[:prodno] if ppac[:prodno] && !ppac[:prodno].empty?
911
925
  end
912
- #xml.HOSPCD
913
- #xml.CLINCD
914
- #xml.ARTTYP
926
+ # xml.HOSPCD
927
+ # xml.CLINCD
928
+ # xml.ARTTYP
915
929
  if zur_rose
916
930
  xml.VAT zur_rose[:vat]
917
931
  end
918
932
  emit_salecd(xml, ean, obj)
919
- if pac and pac[:limitation_points]
920
- #xml.INSLIM
933
+ if pac && pac[:limitation_points]
934
+ # xml.INSLIM
921
935
  xml.LIMPTS pac[:limitation_points] unless pac[:limitation_points].empty?
922
936
  end
923
- #xml.GRDFR
937
+ # xml.GRDFR
924
938
  xml.COOL 1 if ppac && /Blutprodukte|impfstoffe/.match(ppac[:list_code])
925
- #xml.TEMP
939
+ # xml.TEMP
926
940
  if ean
927
- flag = (ppac && !ppac[:drug_index].empty?) ? true : false
941
+ flag = ppac && !ppac[:drug_index].empty? ? true : false
928
942
  # as same flag
929
- xml.CDBG(flag ? 'Y' : 'N')
930
- xml.BG(flag ? 'Y' : 'N')
943
+ xml.CDBG(flag ? "Y" : "N")
944
+ xml.BG(flag ? "Y" : "N")
931
945
  end
932
- #xml.EXP
933
- if item and item[:substances] and substance = item[:substances].first
934
- xml.QTY "#{substance[:quantity]}#{substance[:unit] ? ' ' + substance[:unit] : ''}"
935
- end if false # TODO: get qty/unit from refdata name
936
- xml.DSCRD obj[:desc_de] if obj[:desc_de] and not obj[:desc_de].empty?
937
- xml.DSCRF obj[:desc_fr] if obj[:desc_fr] and not obj[:desc_fr].empty?
938
- xml.DSCRF obj[:desc_de] if !obj[:desc_fr] or obj[:desc_fr].empty?
939
- xml.SORTD obj[:desc_de].upcase if obj[:desc_de] and not obj[:desc_de].empty?
940
- xml.SORTF obj[:desc_fr].upcase if obj[:desc_fr] and not obj[:desc_fr].empty?
941
- xml.SORTF obj[:desc_de].upcase if !obj[:desc_fr] or obj[:desc_fr].empty?
942
- #xml.QTYUD
943
- #xml.QTYUF
944
- #xml.IMG
945
- #xml.IMG2
946
- #xml.PCKTYPD
947
- #xml.PCKTYPF
948
- #xml.MULT
946
+ xml.DSCRD obj[:desc_de] if obj[:desc_de] && !obj[:desc_de].empty?
947
+ xml.DSCRF obj[:desc_fr] if obj[:desc_fr] && !obj[:desc_fr].empty?
948
+ xml.DSCRF obj[:desc_de] if !obj[:desc_fr] || obj[:desc_fr].empty?
949
+ xml.SORTD obj[:desc_de].upcase if obj[:desc_de] && !obj[:desc_de].empty?
950
+ xml.SORTF obj[:desc_fr].upcase if obj[:desc_fr] && !obj[:desc_fr].empty?
951
+ xml.SORTF obj[:desc_de].upcase if !obj[:desc_fr] || obj[:desc_fr].empty?
952
+ # xml.QTYUD
953
+ # xml.QTYUF
954
+ # xml.IMG
955
+ # xml.IMG2
956
+ # xml.PCKTYPD
957
+ # xml.PCKTYPF
958
+ # xml.MULT
949
959
  if obj[:seq]
950
960
  xml.SYN1D obj[:seq][:name_de] unless obj[:seq][:name_de].empty?
951
961
  xml.SYN1F obj[:seq][:name_fr] unless obj[:seq][:name_fr].empty?
952
962
  end
953
963
  if obj[:seq]
954
964
  case obj[:seq][:deductible]
955
- when 'Y'; xml.SLOPLUS 1; # 20%
956
- when 'N'; xml.SLOPLUS 2; # 10%
957
- else xml.SLOPLUS '' # k.A.
965
+ when "Y" then xml.SLOPLUS 1; # 20%
966
+ when "N" then xml.SLOPLUS 2; # 10%
967
+ else xml.SLOPLUS "" # k.A.
958
968
  end
959
969
  end
960
- #xml.NOPCS
961
- #xml.HSCD
962
- #xml.MINI
963
- #xml.DEPCD
964
- #xml.DEPOT
965
- #xml.BAGSL
966
- #xml.BAGSLC
967
- #xml.LOACD
970
+ # xml.NOPCS
971
+ # xml.HSCD
972
+ # xml.MINI
973
+ # xml.DEPCD
974
+ # xml.DEPOT
975
+ # xml.BAGSL
976
+ # xml.BAGSLC
977
+ # xml.LOACD
968
978
  if obj[:stat_date]
969
- xml.OUTSAL obj[:stat_date] if obj[:stat_date] and not obj[:stat_date].empty?
979
+ xml.OUTSAL obj[:stat_date] if obj[:stat_date] && !obj[:stat_date].empty?
970
980
  end
971
- #xml.STTOX
972
- #xml.NOTI
973
- #xml.GGL
974
- #xml.CE
975
- #xml.SMDAT
976
- #xml.SMCDAT
977
- #xml.SIST
978
- #xml.ESIST
979
- #xml.BIOCID
980
- #xml.BAGNO
981
- #xml.LIGHT
982
- #xml.DEL
981
+ # xml.STTOX
982
+ # xml.NOTI
983
+ # xml.GGL
984
+ # xml.CE
985
+ # xml.SMDAT
986
+ # xml.SMCDAT
987
+ # xml.SIST
988
+ # xml.ESIST
989
+ # xml.BIOCID
990
+ # xml.BAGNO
991
+ # xml.LIGHT
992
+ # xml.DEL
983
993
  xml.ARTCOMP {
984
994
  # use ean13(gln) as COMPNO
985
- xml.COMPNO obj[:company_ean] if obj[:company_ean] and obj[:company_ean].to_s.length > 1
986
- #xml.ROLE
987
- #xml.ARTNO1
988
- #xml.ARTNO2
989
- #xml.ARTNO3
995
+ xml.COMPNO obj[:company_ean] if obj[:company_ean] && (obj[:company_ean].to_s.length > 1)
996
+ # xml.ROLE
997
+ # xml.ARTNO1
998
+ # xml.ARTNO2
999
+ # xml.ARTNO3
990
1000
  }
991
- xml.ARTBAR {
992
- xml.CDTYP 'E13'
993
- xml.BC ean # /^9999|^0000|^0$/.match(ean.to_s) ? 0 : sprintf('%013d', ean)
994
- xml.BCSTAT 'A' # P is alternative
995
- } if ean
996
- if pac and pac[:prices]
1001
+ if ean
1002
+ xml.ARTBAR {
1003
+ xml.CDTYP "E13"
1004
+ xml.BC ean # /^9999|^0000|^0$/.match(ean.to_s) ? 0 : sprintf('%013d', ean)
1005
+ xml.BCSTAT "A" # P is alternative
1006
+ }
1007
+ end
1008
+ if pac && pac[:prices]
997
1009
  pac[:prices].each_pair do |key, price|
998
1010
  xml.ARTPRI {
999
- xml.VDAT price[:valid_date] unless price[:valid_date].empty?
1000
- xml.PTYP price[:price_code] unless price[:price_code].empty?
1001
- xml.PRICE price[:price] unless price[:price].empty?
1011
+ xml.VDAT price[:valid_date] unless price[:valid_date].empty?
1012
+ xml.PTYP price[:price_code] unless price[:price_code].empty?
1013
+ xml.PRICE price[:price] unless price[:price].empty?
1002
1014
  }
1003
1015
  end
1004
1016
  end
1005
1017
  if zur_rose
1006
1018
  price = zur_rose[:price]
1007
1019
  xml.ARTPRI {
1008
- xml.PTYP "ZURROSE"
1020
+ xml.PTYP "ZURROSE"
1009
1021
  xml.PRICE price
1010
1022
  }
1011
1023
  xml.ARTPRI {
1012
- xml.PTYP "ZURROSEPUB"
1024
+ xml.PTYP "ZURROSEPUB"
1013
1025
  xml.PRICE zur_rose[:pub_price]
1014
1026
  }
1015
- xml.ARTPRI {
1016
- xml.PTYP "RESELLERPUB"
1017
- xml.PRICE (price.to_f*(1 + (@options[:percent].to_f/100))).round_by(0.05).round(2)
1018
- } if @options[:percent] != nil
1027
+ unless @options[:percent].nil?
1028
+ xml.ARTPRI {
1029
+ xml.PTYP "RESELLERPUB"
1030
+ xml.PRICE (price.to_f * (1 + (@options[:percent].to_f / 100))).round_by(0.05).round(2)
1031
+ }
1032
+ end
1019
1033
  end
1020
1034
  nincd = detect_nincd(obj)
1021
1035
  if nincd
@@ -1026,29 +1040,29 @@ module Oddb2xml
1026
1040
  end
1027
1041
  end
1028
1042
  xml.RESULT {
1029
- xml.OK_ERROR 'OK'
1043
+ xml.OK_ERROR "OK"
1030
1044
  xml.NBR_RECORD nbr_records
1031
- xml.ERROR_CODE ''
1032
- xml.MESSAGE ''
1045
+ xml.ERROR_CODE ""
1046
+ xml.MESSAGE ""
1033
1047
  }
1034
1048
  }
1035
1049
  end
1036
1050
  Oddb2xml.log "build_article. Done #{idx} of #{@articles.size} articles. Overrode #{@overriden_salecd.size} SALECD"
1037
- Oddb2xml.add_hash(_builder.to_xml)
1051
+ Oddb2xml.add_hash(a_builder.to_xml)
1038
1052
  end
1053
+
1039
1054
  def build_fi
1040
1055
  nbr_records = 0
1041
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
1056
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
1042
1057
  xml.doc.tag_suffix = @tag_suffix
1043
- datetime = Time.new.strftime('%FT%T%z')
1044
1058
  xml.KOMPENDIUM(XML_OPTIONS) {
1045
1059
  %w[de fr].each do |lang|
1046
- infos = @infos[lang].uniq {|i| i[:monid] }
1060
+ infos = @infos[lang].uniq { |i| i[:monid] }
1047
1061
  infos.each do |info|
1048
1062
  xml.KMP(
1049
- 'MONTYPE' => 'fi', # only
1050
- 'LANG' => lang.upcase,
1051
- 'DT' => ''
1063
+ "MONTYPE" => "fi", # only
1064
+ "LANG" => lang.upcase,
1065
+ "DT" => ""
1052
1066
  ) {
1053
1067
  unless info[:name].empty?
1054
1068
  xml.name info[:name]
@@ -1056,29 +1070,29 @@ module Oddb2xml
1056
1070
  unless info[:owner].empty?
1057
1071
  xml.owner info[:owner]
1058
1072
  end
1059
- xml.monid info[:monid] unless info[:monid].empty?
1073
+ xml.monid info[:monid] unless info[:monid].empty?
1060
1074
  xml.style { xml.cdata(info[:style]) } if info[:style]
1061
- xml.paragraph { xml.cdata(Nokogiri::HTML.fragment(info[:paragraph].to_html).to_html(:encoding => 'UTF-8')) } if info[:paragraph]
1075
+ xml.paragraph { xml.cdata(Nokogiri::HTML.fragment(info[:paragraph].to_html).to_html(encoding: "UTF-8")) } if info[:paragraph]
1062
1076
  nbr_records += 1
1063
1077
  }
1064
1078
  end
1065
1079
  end
1066
1080
  xml.RESULT {
1067
- xml.OK_ERROR 'OK'
1081
+ xml.OK_ERROR "OK"
1068
1082
  xml.NBR_RECORD nbr_records
1069
- xml.ERROR_CODE ''
1070
- xml.MESSAGE ''
1083
+ xml.ERROR_CODE ""
1084
+ xml.MESSAGE ""
1071
1085
  }
1072
1086
  }
1073
1087
  end
1074
- Oddb2xml.add_hash(_builder.to_xml)
1088
+ Oddb2xml.add_hash(a_builder.to_xml)
1075
1089
  end
1090
+
1076
1091
  def build_fi_product
1077
1092
  prepare_products
1078
1093
  nbr_records = 0
1079
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
1094
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
1080
1095
  xml.doc.tag_suffix = @tag_suffix
1081
- datetime = Time.new.strftime('%FT%T%z')
1082
1096
  xml.KOMPENDIUM_PRODUCT(XML_OPTIONS) {
1083
1097
  info_index = {}
1084
1098
  %w[de fr].each do |lang|
@@ -1087,556 +1101,581 @@ module Oddb2xml
1087
1101
  end
1088
1102
  # prod
1089
1103
  @products.each do |ean13, prod|
1090
- next unless prod[:seq] and prod[:seq][:packages]
1104
+ next unless prod[:seq] && prod[:seq][:packages]
1091
1105
  seq = prod[:seq]
1092
- prod[:seq][:packages].each {
1093
- |phar, package|
1094
- next unless package[:swissmedic_number8]
1095
- m = /(\d{5})(\d{3})/.match(package[:swissmedic_number8])
1096
- next unless m
1097
- number = m[1].to_s
1098
- idx = info_index[number]
1099
- next unless idx
1100
- xml.KP('DT' => '') {
1101
- xml.MONID @infos[lang][idx][:monid]
1102
- xml.PRDNO seq[:product_key] unless seq[:product_key].empty?
1103
- # as orphan ?
1104
- xml.DEL @orphan.include?(number) ? true : false
1105
- nbr_records += 1
1106
- }
1107
- }
1108
- end
1106
+ prod[:seq][:packages].each { |phar, package|
1107
+ next unless package[:swissmedic_number8]
1108
+ m = /(\d{5})(\d{3})/.match(package[:swissmedic_number8])
1109
+ next unless m
1110
+ number = m[1].to_s
1111
+ idx = info_index[number]
1112
+ next unless idx
1113
+ xml.KP("DT" => "") {
1114
+ xml.MONID @infos[lang][idx][:monid]
1115
+ xml.PRDNO seq[:product_key] unless seq[:product_key].empty?
1116
+ # as orphan ?
1117
+ xml.DEL @orphan.include?(number) ? true : false
1118
+ nbr_records += 1
1119
+ }
1120
+ }
1109
1121
  end
1122
+ end
1110
1123
  xml.RESULT {
1111
- xml.OK_ERROR 'OK'
1124
+ xml.OK_ERROR "OK"
1112
1125
  xml.NBR_RECORD nbr_records
1113
- xml.ERROR_CODE ''
1114
- xml.MESSAGE ''
1126
+ xml.ERROR_CODE ""
1127
+ xml.MESSAGE ""
1115
1128
  }
1116
1129
  }
1117
1130
  end
1118
- Oddb2xml.add_hash(_builder.to_xml)
1131
+ Oddb2xml.add_hash(a_builder.to_xml)
1119
1132
  end
1133
+
1120
1134
  def build_company
1121
1135
  nbr_records = 0
1122
1136
  Oddb2xml.log "build_company #{@companies.size} companies"
1123
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
1137
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
1124
1138
  xml.doc.tag_suffix = @tag_suffix
1125
- datetime = Time.new.strftime('%FT%T%z')
1126
1139
  xml.Betriebe(XML_OPTIONS) {
1127
1140
  @companies.each do |c|
1128
- xml.Betrieb('DT' => '') {
1129
- xml.GLN_Betrieb c[:gln] unless c[:gln].empty?
1130
- xml.Betriebsname_1 c[:name_1] unless c[:name_1].empty?
1131
- xml.Betriebsname_2 c[:name_2] unless c[:name_2].empty?
1132
- xml.Strasse c[:address] unless c[:address].empty?
1133
- xml.Nummer c[:number] unless c[:number].empty?
1134
- xml.PLZ c[:post] unless c[:post].empty?
1135
- xml.Ort c[:place] unless c[:place].empty?
1136
- xml.Bewilligungskanton c[:region] unless c[:region].empty?
1137
- xml.Land c[:country] unless c[:country].empty?
1138
- xml.Betriebstyp c[:type] unless c[:type].empty?
1139
- xml.BTM_Berechtigung c[:authorization] unless c[:authorization].empty?
1141
+ xml.Betrieb("DT" => "") {
1142
+ xml.GLN_Betrieb c[:gln] unless c[:gln].empty?
1143
+ xml.Betriebsname_1 c[:name_1] unless c[:name_1].empty?
1144
+ xml.Betriebsname_2 c[:name_2] unless c[:name_2].empty?
1145
+ xml.Strasse c[:address] unless c[:address].empty?
1146
+ xml.Nummer c[:number] unless c[:number].empty?
1147
+ xml.PLZ c[:post] unless c[:post].empty?
1148
+ xml.Ort c[:place] unless c[:place].empty?
1149
+ xml.Bewilligungskanton c[:region] unless c[:region].empty?
1150
+ xml.Land c[:country] unless c[:country].empty?
1151
+ xml.Betriebstyp c[:type] unless c[:type].empty?
1152
+ xml.BTM_Berechtigung c[:authorization] unless c[:authorization].empty?
1140
1153
  nbr_records += 1
1141
1154
  }
1142
1155
  end
1143
1156
  xml.RESULT {
1144
- xml.OK_ERROR 'OK'
1157
+ xml.OK_ERROR "OK"
1145
1158
  xml.NBR_RECORD nbr_records
1146
- xml.ERROR_CODE ''
1147
- xml.MESSAGE ''
1159
+ xml.ERROR_CODE ""
1160
+ xml.MESSAGE ""
1148
1161
  }
1149
1162
  }
1150
1163
  end
1151
- Oddb2xml.add_hash(_builder.to_xml)
1164
+ Oddb2xml.add_hash(a_builder.to_xml)
1152
1165
  end
1166
+
1153
1167
  def build_person
1154
1168
  nbr_records = 0
1155
1169
  Oddb2xml.log "build_person #{@people.size} persons"
1156
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
1170
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
1157
1171
  xml.doc.tag_suffix = @tag_suffix
1158
- datetime = Time.new.strftime('%FT%T%z')
1159
1172
  xml.Personen(XML_OPTIONS) {
1160
1173
  @people.each do |p|
1161
- xml.Person('DT' => '') {
1162
- xml.GLN_Person p[:gln] unless p[:gln].empty?
1163
- xml.Name p[:last_name] unless p[:last_name].empty?
1164
- xml.Vorname p[:first_name] unless p[:first_name].empty?
1165
- xml.PLZ p[:post] unless p[:post].empty?
1166
- xml.Ort p[:place] unless p[:place].empty?
1167
- xml.Bewilligungskanton p[:region] unless p[:region].empty?
1168
- xml.Land p[:country] unless p[:country].empty?
1174
+ xml.Person("DT" => "") {
1175
+ xml.GLN_Person p[:gln] unless p[:gln].empty?
1176
+ xml.Name p[:last_name] unless p[:last_name].empty?
1177
+ xml.Vorname p[:first_name] unless p[:first_name].empty?
1178
+ xml.PLZ p[:post] unless p[:post].empty?
1179
+ xml.Ort p[:place] unless p[:place].empty?
1180
+ xml.Bewilligungskanton p[:region] unless p[:region].empty?
1181
+ xml.Land p[:country] unless p[:country].empty?
1169
1182
  xml.Bewilligung_Selbstdispensation p[:license] unless p[:license].empty?
1170
- xml.Diplom p[:certificate] unless p[:certificate].empty?
1171
- xml.BTM_Berechtigung p[:authorization] unless p[:authorization].empty?
1183
+ xml.Diplom p[:certificate] unless p[:certificate].empty?
1184
+ xml.BTM_Berechtigung p[:authorization] unless p[:authorization].empty?
1172
1185
  nbr_records += 1
1173
1186
  }
1174
1187
  end
1175
1188
  xml.RESULT {
1176
- xml.OK_ERROR 'OK'
1189
+ xml.OK_ERROR "OK"
1177
1190
  xml.NBR_RECORD nbr_records
1178
- xml.ERROR_CODE ''
1179
- xml.MESSAGE ''
1191
+ xml.ERROR_CODE ""
1192
+ xml.MESSAGE ""
1180
1193
  }
1181
1194
  }
1182
1195
  end
1183
- Oddb2xml.add_hash(_builder.to_xml)
1196
+ Oddb2xml.add_hash(a_builder.to_xml)
1184
1197
  end
1198
+
1185
1199
  def detect_nincd(de_idx)
1186
1200
  if @lppvs[de_idx[:ean13].to_s] # LPPV
1187
1201
  20
1188
1202
  elsif @items[de_idx[:pharmacode]] # BAG-XML (SL/LS)
1189
1203
  10
1190
- elsif (de_idx[:migel] or # MiGel (xls)
1191
- de_idx[:_type] == :nonpharma) # MiGel (swissindex)
1204
+ elsif de_idx[:migel] || # MiGel (xls)
1205
+ (de_idx[:_type] == :nonpharma) # MiGel (swissindex)
1192
1206
  13
1193
1207
  else
1194
1208
  # fallback via EAN
1195
1209
  bag_entry_via_ean = @items.values.select do |item|
1196
1210
  next unless item[:packages]
1197
- item[:packages].values.select {|_pac| _pac[:ean13].to_s.eql?(de_idx[:ean13].to_s) }.length != 0
1211
+ item[:packages].values.count { |a_pac| a_pac[:ean13].to_s.eql?(de_idx[:ean13].to_s) } != 0
1198
1212
  end
1199
1213
  if bag_entry_via_ean.length > 0
1200
1214
  10
1201
- else
1202
- nil
1203
1215
  end
1204
1216
  end
1205
1217
  end
1206
1218
 
1207
1219
  ### --- see oddb2tdat
1208
1220
  DAT_LEN = {
1209
- :RECA => 2,
1210
- :CMUT => 1,
1211
- :PHAR => 7,
1212
- :ABEZ => 50,
1213
- :PRMO => 6,
1214
- :PRPU => 6,
1215
- :CKZL => 1,
1216
- :CLAG => 1,
1217
- :CBGG => 1,
1218
- :CIKS => 1,
1219
- :ITHE => 7,
1220
- :CEAN => 13,
1221
- :CMWS => 1,
1221
+ RECA: 2,
1222
+ CMUT: 1,
1223
+ PHAR: 7,
1224
+ ABEZ: 50,
1225
+ PRMO: 6,
1226
+ PRPU: 6,
1227
+ CKZL: 1,
1228
+ CLAG: 1,
1229
+ CBGG: 1,
1230
+ CIKS: 1,
1231
+ ITHE: 7,
1232
+ CEAN: 13,
1233
+ CMWS: 1
1222
1234
  }
1223
- def format_price(price_str, len=6, int_len=4, frac_len=2)
1224
- price = price_str.split('.')
1225
- pre = ''
1226
- las = ''
1227
- pre = "%0#{int_len}d" % (price[0] ? price[0] : '0')
1235
+ def format_price(price_str, len = 6, int_len = 4, frac_len = 2)
1236
+ price = price_str.split(".")
1237
+ pre = "%0#{int_len}d" % (price[0] || "0")
1228
1238
  las = if price[1]
1229
- if price[1].size < frac_len
1230
- price[1] + "0"*(frac_len-price[2].to_s.size)
1231
- else
1232
- price[1][0,frac_len]
1233
- end
1234
- else
1235
- '0'*frac_len
1236
- end
1237
- (pre.to_s + las.to_s)[0,len]
1239
+ if price[1].size < frac_len
1240
+ price[1] + "0" * (frac_len - price[2].to_s.size)
1241
+ else
1242
+ price[1][0, frac_len]
1243
+ end
1244
+ else
1245
+ "0" * frac_len
1246
+ end
1247
+ (pre.to_s + las.to_s)[0, len]
1238
1248
  end
1239
- def format_date(date_str, len=7)
1240
- date = date_str.gsub('.','')
1249
+
1250
+ def format_date(date_str, len = 7)
1251
+ date = date_str.delete(".")
1241
1252
  if date.size < len
1242
- date = date + '0'*(len-date.size)
1253
+ date += "0" * (len - date.size)
1243
1254
  end
1244
- date[0,len]
1255
+ date[0, len]
1245
1256
  end
1246
1257
 
1247
1258
  # The migel name must be always 50 chars wide and in ISO 8859-1 format
1248
1259
  def format_name(name, length)
1249
- ("%-#{length}s" % name)[0..length-1]
1260
+ ("%-#{length}s" % name)[0..length - 1]
1250
1261
  end
1262
+
1251
1263
  def build_dat
1252
1264
  prepare_articles
1253
1265
  rows = []
1254
1266
  @articles.each do |obj|
1255
- ean = obj[:ean13]
1256
- next if ((ean.to_s.length != 13) and !ean14)
1257
- next if obj[:type] == :nonpharma
1258
- row = ''
1259
- pack_info = nil
1260
- if (x = @packs.find{|k,v| v[:ean13].eql?(ean)})
1261
- pack_info = x[1]
1262
- end
1263
- # Oddb2tdat.parse
1264
- pac,no8 = nil,nil
1265
- if obj[:seq] and obj[:seq][:packages]
1266
- pac = obj[:seq][:packages][obj[:pharmacode]]
1267
- pac = obj[:seq][:packages][ean] unless pac
1268
- else
1269
- pac = @items[ean][:packages][ean] if @items and @items[ean] and @items[ean][:packages]
1270
- end
1271
- # :swissmedic_numbers
1272
- if pac
1273
- no8 = pac[:swissmedic_number8]
1274
- end
1275
- if pac and pac[:prices] == nil and no8
1276
- ppac = ((ppac = pack_info and ppac[:is_tier]) ? ppac : nil)
1277
- pac = ppac if ppac
1278
- end
1279
- row << "%#{DAT_LEN[:RECA]}s" % '11'
1280
- zur_rose = @infos_zur_rose[ean] # zurrose
1281
- if zur_rose && zur_rose[:cmut]
1282
- row << zur_rose[:cmut]
1283
- else
1284
- row << '1'
1285
- end
1286
- row << "%0#{DAT_LEN[:PHAR]}d" % obj[:pharmacode].to_i
1287
- abez = ( # de name
1288
- obj[:desc_de].to_s + " " +
1289
- (pac ? pac[:name_de].to_s : '') +
1290
- (obj[:quantity] ? obj[:quantity] : '')
1291
- ).gsub(/"/, '')
1292
- if @infos_zur_rose[ean]
1293
- price_exf = sprintf('%06i', ((@infos_zur_rose[ean][:price].to_f)*100).to_i)
1294
- price_public = sprintf('%06i', ((@infos_zur_rose[ean][:pub_price].to_f)*100).to_i)
1295
- if @options[:percent] != nil
1296
- price_public = sprintf('%06i', (price_exf.to_f*(1 + (@options[:percent].to_f/100))).round_by(0.05).round(2))
1297
- end
1298
- elsif pac and pac[:prices]
1299
- price_exf = sprintf('%06i', (pac[:prices][:exf_price][:price].to_f*100).to_i) if pac[:prices][:exf_price] and pac[:prices][:exf_price][:price]
1300
- price_public = sprintf('%06i', (pac[:prices][:pub_price][:price].to_f*100).to_i) if pac[:prices][:pub_price] and pac[:prices][:pub_price][:price]
1301
- end
1302
- row << format_name(Oddb2xml.patch_some_utf8(abez), DAT_LEN[:ABEZ])
1303
- if price_exf.to_s.length > DAT_LEN[:PRMO] ||
1304
- price_public.to_s.length > DAT_LEN[:PRPU]
1305
- puts "Price exfactory #{price_exf} or public #{price_public} is too high to be added into transfer.dat"
1306
- break
1267
+ ean = obj[:ean13]
1268
+ next if (ean.to_s.length != 13) && !ean14
1269
+ next if obj[:type] == :nonpharma
1270
+ row = ""
1271
+ pack_info = nil
1272
+ if (x = @packs.find { |k, v| v[:ean13].eql?(ean) })
1273
+ pack_info = x[1]
1274
+ end
1275
+ # Oddb2tdat.parse
1276
+ pac, no8 = nil, nil
1277
+ if obj[:seq] && obj[:seq][:packages]
1278
+ pac = obj[:seq][:packages][obj[:pharmacode]]
1279
+ pac ||= obj[:seq][:packages][ean]
1280
+ elsif @items && @items[ean] && @items[ean][:packages]
1281
+ pac = @items[ean][:packages][ean]
1282
+ end
1283
+ # :swissmedic_numbers
1284
+ if pac
1285
+ no8 = pac[:swissmedic_number8]
1286
+ end
1287
+ if pac && pac[:prices].nil? && no8
1288
+ ppac = ((ppac = pack_info) && ppac[:is_tier] ? ppac : nil)
1289
+ pac = ppac if ppac
1290
+ end
1291
+ row << "%#{DAT_LEN[:RECA]}s" % "11"
1292
+ zur_rose = @infos_zur_rose[ean] # zurrose
1293
+ row << if zur_rose && zur_rose[:cmut]
1294
+ zur_rose[:cmut]
1295
+ else
1296
+ "1"
1297
+ end
1298
+ row << "%0#{DAT_LEN[:PHAR]}d" % obj[:pharmacode].to_i
1299
+ abez = ( # de name
1300
+ obj[:desc_de].to_s + " " +
1301
+ (pac ? pac[:name_de].to_s : "") +
1302
+ (obj[:quantity] || "")
1303
+ ).delete('"')
1304
+ if @infos_zur_rose[ean]
1305
+ price_exf = sprintf("%06i", (@infos_zur_rose[ean][:price].to_f * 100).to_i)
1306
+ price_public = sprintf("%06i", (@infos_zur_rose[ean][:pub_price].to_f * 100).to_i)
1307
+ if !@options[:percent].nil?
1308
+ price_public = sprintf("%06i", (price_exf.to_f * (1 + (@options[:percent].to_f / 100))).round_by(0.05).round(2))
1307
1309
  end
1308
- row << "%#{DAT_LEN[:PRMO]}s" % (price_exf ? price_exf.to_s : ('0' * DAT_LEN[:PRMO]))
1309
- row << "%#{DAT_LEN[:PRPU]}s" % (price_public ? price_public.to_s : ('0' * DAT_LEN[:PRPU]))
1310
- row << "%#{DAT_LEN[:CKZL]}s" % if (@lppvs[ean])
1311
- '2'
1312
- elsif pac # sl_entry
1313
- '1'
1314
- else
1315
- '3'
1316
- end
1317
- row << "%#{DAT_LEN[:CLAG]}s" % if ppac && /Blutproduct|impfstoffe/.match(ppac[:list_code]) # COOL
1318
- '1'
1319
- else
1320
- '0'
1321
- end
1322
- row << "%#{DAT_LEN[:CBGG]}s" % if (pack_info && pack_info[:drug_index])
1323
- '3'
1324
- else
1325
- '0'
1326
- end
1327
- row << "%#{DAT_LEN[:CIKS]}s" % if (no8 && pack_info && !pack_info[:is_tier]) # Packungen.xls
1328
- pack_info[:swissmedic_category]
1329
- else
1330
- '0'
1331
- end.gsub(/(\+|\s)/, '')
1332
- row << "%0#{DAT_LEN[:ITHE]}d" % if (no8 && pack_info && !pack_info[:is_tier])
1333
- format_date(pack_info[:ith_swissmedic])
1334
- else
1335
- ('0' * DAT_LEN[:ITHE])
1336
- end.to_i
1337
- row << "%0#{DAT_LEN[:CEAN]}d" % (sprintf('%013d', ean.to_i).match(/^000000/) ? 0 : ean.to_i)
1338
- row << "%#{DAT_LEN[:CMWS]}s" % '2' # pharma
1339
- rows << row
1310
+ elsif pac && pac[:prices]
1311
+ price_exf = sprintf("%06i", (pac[:prices][:exf_price][:price].to_f * 100).to_i) if pac[:prices][:exf_price] && pac[:prices][:exf_price][:price]
1312
+ price_public = sprintf("%06i", (pac[:prices][:pub_price][:price].to_f * 100).to_i) if pac[:prices][:pub_price] && pac[:prices][:pub_price][:price]
1313
+ end
1314
+ row << format_name(Oddb2xml.patch_some_utf8(abez), DAT_LEN[:ABEZ])
1315
+ if price_exf.to_s.length > DAT_LEN[:PRMO] ||
1316
+ price_public.to_s.length > DAT_LEN[:PRPU]
1317
+ puts "Price exfactory #{price_exf} or public #{price_public} is too high to be added into transfer.dat"
1318
+ break
1319
+ end
1320
+ row << "%#{DAT_LEN[:PRMO]}s" % (price_exf ? price_exf.to_s : ("0" * DAT_LEN[:PRMO]))
1321
+ row << "%#{DAT_LEN[:PRPU]}s" % (price_public ? price_public.to_s : ("0" * DAT_LEN[:PRPU]))
1322
+ row << "%#{DAT_LEN[:CKZL]}s" % if @lppvs[ean]
1323
+ "2"
1324
+ elsif pac # sl_entry
1325
+ "1"
1326
+ else
1327
+ "3"
1328
+ end
1329
+ row << "%#{DAT_LEN[:CLAG]}s" % if ppac && /Blutproduct|impfstoffe/.match(ppac[:list_code]) # COOL
1330
+ "1"
1331
+ else
1332
+ "0"
1333
+ end
1334
+ row << "%#{DAT_LEN[:CBGG]}s" % if pack_info && pack_info[:drug_index]
1335
+ "3"
1336
+ else
1337
+ "0"
1338
+ end
1339
+ row << "%#{DAT_LEN[:CIKS]}s" % if no8 && pack_info && !pack_info[:is_tier] # Packungen.xls
1340
+ pack_info[:swissmedic_category]
1341
+ else
1342
+ "0"
1343
+ end.gsub(/(\+|\s)/, "")
1344
+ row << "%0#{DAT_LEN[:ITHE]}d" % if no8 && pack_info && !pack_info[:is_tier]
1345
+ format_date(pack_info[:ith_swissmedic])
1346
+ else
1347
+ ("0" * DAT_LEN[:ITHE])
1348
+ end.to_i
1349
+ row << "%0#{DAT_LEN[:CEAN]}d" % (/^000000/.match?(sprintf("%013d", ean.to_i)) ? 0 : ean.to_i)
1350
+ row << "%#{DAT_LEN[:CMWS]}s" % "2" # pharma
1351
+ rows << row
1340
1352
  end
1341
1353
  rows.join("\n")
1342
1354
  end
1355
+
1343
1356
  def build_with_migel_dat
1344
1357
  reset = true
1345
1358
  prepare_articles(reset)
1346
1359
  rows = []
1347
1360
  @articles.each do |obj|
1348
- row = ''
1349
- next if ((obj[:ean13].to_s.length != 13) and !ean14)
1350
- # Oddb2tdat.parse_migel
1351
- row << "%#{DAT_LEN[:RECA]}s" % '11'
1352
- row << "%#{DAT_LEN[:CMUT]}s" % if (phar = obj[:pharmacode] and phar.size > 3)
1353
- '1'
1354
- else
1355
- '3'
1356
- end
1357
- row << "%0#{DAT_LEN[:PHAR]}d" % obj[:pharmacode].to_i
1358
- abez = ( # de name
1359
- obj[:desc_de].to_s + " " +
1360
- (obj[:quantity] ? obj[:quantity] : '')
1361
- ).gsub(/"/, '')
1362
- row << format_name(Oddb2xml.patch_some_utf8(abez), DAT_LEN[:ABEZ])
1363
- row << '0' * DAT_LEN[:PRMO]
1364
- row << '0' * DAT_LEN[:PRPU]
1365
- row << "%#{DAT_LEN[:CKZL]}s" % '3' # sl_entry and lppv
1366
- row << "%#{DAT_LEN[:CLAG]}s" % '0'
1367
- row << "%#{DAT_LEN[:CBGG]}s" % '0'
1368
- row << "%#{DAT_LEN[:CIKS]}s" % ' ' # no category
1369
- row << "%0#{DAT_LEN[:ITHE]}d" % 0
1370
- row << obj[:ean13].to_s.rjust(DAT_LEN[:CEAN], '0')
1371
- row << "%#{DAT_LEN[:CMWS]}s" % '1' # nonpharma
1372
- rows << row
1373
- end
1361
+ row = ""
1362
+ next if (obj[:ean13].to_s.length != 13) && !ean14
1363
+ # Oddb2tdat.parse_migel
1364
+ row << "%#{DAT_LEN[:RECA]}s" % "11"
1365
+ row << "%#{DAT_LEN[:CMUT]}s" % if (phar = obj[:pharmacode]) && (phar.size > 3)
1366
+ "1"
1367
+ else
1368
+ "3"
1369
+ end
1370
+ row << "%0#{DAT_LEN[:PHAR]}d" % obj[:pharmacode].to_i
1371
+ abez = ( # de name
1372
+ obj[:desc_de].to_s + " " +
1373
+ (obj[:quantity] || "")
1374
+ ).delete('"')
1375
+ row << format_name(Oddb2xml.patch_some_utf8(abez), DAT_LEN[:ABEZ])
1376
+ row << "0" * DAT_LEN[:PRMO]
1377
+ row << "0" * DAT_LEN[:PRPU]
1378
+ row << "%#{DAT_LEN[:CKZL]}s" % "3" # sl_entry and lppv
1379
+ row << "%#{DAT_LEN[:CLAG]}s" % "0"
1380
+ row << "%#{DAT_LEN[:CBGG]}s" % "0"
1381
+ row << "%#{DAT_LEN[:CIKS]}s" % " " # no category
1382
+ row << "%0#{DAT_LEN[:ITHE]}d" % 0
1383
+ row << obj[:ean13].to_s.rjust(DAT_LEN[:CEAN], "0")
1384
+ row << "%#{DAT_LEN[:CMWS]}s" % "1" # nonpharma
1385
+ rows << row
1386
+ end
1374
1387
  rows.join("\n")
1375
1388
  end
1389
+
1376
1390
  def emit_salecd(xml, ean13, obj)
1377
1391
  zur_rose = nil
1378
1392
  if !@infos_zur_rose.empty? && ean13 && @infos_zur_rose[ean13]
1379
1393
  zur_rose = @infos_zur_rose[ean13] # zurrose
1380
1394
  end
1381
1395
  nincd = detect_nincd(obj)
1382
- in_refdata = !!( obj[:seq] && obj[:seq][:packages] && obj[:seq][:packages][ean13] && obj[:seq][:packages][ean13][:swissmedic_number8])
1383
- status = (nincd && nincd == 13) ? 'A' : (zur_rose && zur_rose[:cmut] != '3') ? 'A' : 'I'
1384
- if in_refdata && !'A'.eql?(status)
1396
+ in_refdata = !!(obj[:seq] && obj[:seq][:packages] && obj[:seq][:packages][ean13] && obj[:seq][:packages][ean13][:swissmedic_number8])
1397
+ status = if nincd && nincd == 13
1398
+ "A"
1399
+ else
1400
+ zur_rose && zur_rose[:cmut] != "3" ? "A" : "I"
1401
+ end
1402
+ if in_refdata && !"A".eql?(status)
1385
1403
  msg = "Overriding status #{status} nincd #{nincd} for #{ean13} as in refdata_pharma"
1386
1404
  # Oddb2xml.log msg
1387
1405
  @overriden_salecd << ean13
1388
- xml.SALECD('A') { xml.comment(msg)}
1406
+ xml.SALECD("A") { xml.comment(msg) }
1389
1407
  else
1390
- xml.SALECD(status) { xml.comment( "expiry_date #{obj[:expiry_date]}") if obj[:expiry_date] }
1408
+ xml.SALECD(status) { xml.comment("expiry_date #{obj[:expiry_date]}") if obj[:expiry_date] }
1391
1409
  end
1392
1410
  end
1393
1411
 
1394
1412
  def build_artikelstamm
1395
1413
  @@emitted_v5_gtins = []
1396
- @csv_file = CSV.open(File.join(WorkDir, "artikelstamm_#{Date.today.strftime('%d%m%Y')}_v5.csv"), "w+")
1397
- @csv_file << ['gtin', 'name', 'pkg_size', 'galenic_form', 'price_ex_factory', 'price_public', 'prodno', 'atc_code', 'active_substance', 'original', 'it-code', 'sl-liste']
1414
+ @csv_file = CSV.open(File.join(WORK_DIR, "artikelstamm_#{Date.today.strftime("%d%m%Y")}_v5.csv"), "w+")
1415
+ @csv_file << ["gtin", "name", "pkg_size", "galenic_form", "price_ex_factory", "price_public", "prodno", "atc_code", "active_substance", "original", "it-code", "sl-liste"]
1398
1416
  @csv_file.sync = true
1399
1417
  variant = "build_artikelstamm"
1400
1418
  # @infos_zur_rose.delete_if { |key, val| val[:cmut].eql?('3') } # collect only active zur rose item
1401
1419
  # No. Marco did not filter it, eg. 8804121 in rtikelstamm_oddb2xml_051217_v5.xm
1402
- def check_name(obj, lang = :de)
1403
- ean = obj[:ean13]
1404
- refdata = @refdata[ean]
1405
- if lang == :de
1406
- name = (refdata && refdata[:desc_de]) ? refdata[:desc_de] : obj[:sequence_name]
1407
- elsif lang == :fr
1408
- name = (refdata && refdata[:desc_fr]) ? refdata[:desc_fr] : obj[:sequence_name]
1409
- else
1410
- return '--missing--'
1420
+ self.class.class_eval do
1421
+ def check_article_name(obj, lang = :de)
1422
+ ean = obj[:ean13]
1423
+ refdata = @refdata[ean]
1424
+ if lang == :de
1425
+ name = refdata && refdata[:desc_de] ? refdata[:desc_de] : obj[:sequence_name]
1426
+ elsif lang == :fr
1427
+ name = refdata && refdata[:desc_fr] ? refdata[:desc_fr] : obj[:sequence_name]
1428
+ else
1429
+ return "--missing--"
1430
+ end
1431
+ return "--missing--" if !name || name.empty? || name.length < 3
1432
+ name[0..119] # limit to maximal 120 chars as specified in the XSD
1411
1433
  end
1412
- return '--missing--' if !name || name.empty? || name.length < 3
1413
- name[0..119] # limit to maximal 120 chars as specified in the XSD
1414
1434
  end
1415
- def override(xml, id, field, default_value)
1416
- has_overrides = /\d{13}/.match(id.to_s) ? @@article_overrides[id.to_i] : @@product_overrides[id.to_i]
1417
- unless (has_overrides && has_overrides[field.to_s])
1418
- cmd = "xml.#{field} \"#{default_value.to_s.gsub('"','')}\""
1419
- else
1420
- new_value = has_overrides[field.to_s]
1421
- if new_value.to_s.eql?(default_value.to_s)
1422
- xml.comment('obsolete override')
1435
+ self.class.class_eval do
1436
+ def override(xml, id, field, default_value)
1437
+ has_overrides = /\d{13}/.match?(id.to_s) ? @@article_overrides[id.to_i] : @@product_overrides[id.to_i]
1438
+ if has_overrides && has_overrides[field.to_s]
1439
+ new_value = has_overrides[field.to_s]
1440
+ if new_value.to_s.eql?(default_value.to_s)
1441
+ xml.comment("obsolete override")
1442
+ else
1443
+ xml.comment("override #{default_value} with")
1444
+ end
1423
1445
  cmd = "xml.#{field} \"#{new_value}\""
1424
1446
  else
1425
- xml.comment("override #{default_value.to_s} with")
1426
- cmd ="xml.#{field} \"#{new_value}\""
1447
+ cmd = "xml.#{field} \"#{default_value.to_s.delete('"')}\""
1427
1448
  end
1449
+ eval cmd if default_value
1428
1450
  end
1429
- eval cmd if default_value
1430
1451
  end
1431
- def emit_items(xml)
1432
- nr_items = 0
1433
- gtins_to_article = {}
1434
- @articles.each {|article| gtins_to_article[article[:ean13]] = article }
1435
- sl_gtins = @items.values.collect{|x| x[:packages].keys}.flatten.uniq;
1436
- gtins = gtins_to_article.keys + @infos_zur_rose.keys + @packs.values.collect{|x| x[:ean13]} + sl_gtins
1437
- gtins = (gtins-@@gtin2ignore)
1438
- gtins.sort!.uniq!
1439
- gtins.each do |ean13|
1440
- pac,no8 = nil,ean13.to_s[4..11] # BAG-XML(SL/LS)
1441
- next if ean13 == 0
1442
- obj = gtins_to_article[ean13] || @items.values.find{|x| x[:packages].keys.index(ean13) } || @infos_zur_rose[ean13]
1443
- if obj
1444
- obj = @packs[no8].merge(obj) if @packs[no8]
1445
- else
1446
- obj = @packs[no8] # obj not yet in refdata. Use data from swissmedic_package.xlsx
1447
- end
1448
- nr_items += 1
1449
- Oddb2xml.log "build_artikelstamm #{ean13}: #{nr_items} of #{gtins.size} articles" if nr_items % 5000 == 0
1450
- item = @items[ean13]
1451
- pack_info = nil
1452
- pack_info = @packs[no8] if no8 && /#{ean13}/.match(@packs[no8].to_s) # info from Packungen.xlsx from swissmedic_info
1453
- next if pack_info && /Tierarzneimittel/.match(pack_info[:list_code])
1454
- next if obj[:desc_de] && /ad us vet/i.match(obj[:desc_de])
1455
- sequence = obj[:seq]
1456
- if sequence.nil? && @packs[no8] && /#{ean13}/.match(@packs[no8].to_s)
1457
- sequence = {:packages =>{ean13 => @packs[no8]}}
1458
- obj[:seq] = sequence.clone
1459
- end
1460
- if sequence.nil? && @items[ean13] && @items[ean13][:packages][ean13]
1461
- sequence = @items[ean13]
1462
- end
1463
- if sequence
1464
- if obj[:seq] && !obj[:seq][:packages].keys.index(ean13)
1465
- # puts "unable to find #{ean13} in #{obj[:seq][:packages].keys}"
1466
- next
1452
+ self.class.class_eval do
1453
+ def emit_items(xml)
1454
+ nr_items = 0
1455
+ gtins_to_article = {}
1456
+ @articles.each { |article| gtins_to_article[article[:ean13]] = article }
1457
+ sl_gtins = @items.values.collect { |x| x[:packages].keys }.flatten.uniq
1458
+ gtins = gtins_to_article.keys + @infos_zur_rose.keys + @packs.values.collect { |x| x[:ean13] } + sl_gtins
1459
+ gtins = (gtins - @@gtin2ignore)
1460
+ gtins.sort!.uniq!
1461
+ gtins.each do |ean13|
1462
+ no8 = ean13.to_s[4..11] # BAG-XML(SL/LS)
1463
+ next if ean13 == 0
1464
+ obj = gtins_to_article[ean13] || @items.values.find { |x| x[:packages].keys.index(ean13) } || @infos_zur_rose[ean13]
1465
+ if obj
1466
+ obj = @packs[no8].merge(obj) if @packs[no8]
1467
+ else
1468
+ obj = @packs[no8] # obj not yet in refdata. Use data from swissmedic_package.xlsx
1467
1469
  end
1468
- sequence[:packages].each do |gtin, package|
1469
- pkg_gtin = package[:ean13].clone
1470
- if package[:no8] && (newEan13 = Oddb2xml.getEan13forNo8(package[:no8]))
1471
- if !newEan13.eql?(pkg_gtin)
1472
- puts "Setting #{newEan13} for #{pkg_gtin}"
1473
- pkg_gtin = newEan13
1474
- end
1475
- end
1476
- pharma_code = @refdata[pkg_gtin]
1477
- if @refdata[pkg_gtin] && @refdata[pkg_gtin][:pharmacode]
1478
- pharma_code = @refdata[pkg_gtin][:pharmacode]
1479
- elsif obj[:pharmacode]
1480
- pharma_code = obj[:pharmacode]
1481
- elsif @infos_zur_rose[ean13]
1482
- pharma_code = @infos_zur_rose[ean13][:pharmacode]
1483
- end
1484
- info = @calc_items[pkg_gtin]
1485
- if @@emitted_v5_gtins.index(pkg_gtin)
1470
+ nr_items += 1
1471
+ Oddb2xml.log "build_artikelstamm #{ean13}: #{nr_items} of #{gtins.size} articles" if nr_items % 5000 == 0
1472
+ item = @items[ean13]
1473
+ pack_info = nil
1474
+ pack_info = @packs[no8] if no8 && /#{ean13}/.match(@packs[no8].to_s) # info from Packungen.xlsx from swissmedic_info
1475
+ next if pack_info && /Tierarzneimittel/.match(pack_info[:list_code])
1476
+ next if obj[:desc_de] && /ad us vet/i.match(obj[:desc_de])
1477
+ sequence = obj[:seq]
1478
+ if sequence.nil? && @packs[no8] && /#{ean13}/.match(@packs[no8].to_s)
1479
+ sequence = {packages: {ean13 => @packs[no8]}}
1480
+ obj[:seq] = sequence.clone
1481
+ end
1482
+ if sequence.nil? && @items[ean13] && @items[ean13][:packages][ean13]
1483
+ sequence = @items[ean13]
1484
+ end
1485
+ if sequence
1486
+ if obj[:seq] && !obj[:seq][:packages].keys.index(ean13)
1487
+ # puts "unable to find #{ean13} in #{obj[:seq][:packages].keys}"
1486
1488
  next
1487
- else
1488
- @@emitted_v5_gtins << pkg_gtin.clone
1489
1489
  end
1490
- options = {'PHARMATYPE' => 'P'}
1491
- xml.ITEM(options) do
1492
- name = item[:name_de] + ' ' + item[:desc_de].strip + ' ' + package[:desc_de] if package && package[:desc_de]
1493
- name ||= @refdata[pkg_gtin] ? @refdata[pkg_gtin][:desc_de] : nil
1494
- name ||= @infos_zur_rose[ean13][:description] if @infos_zur_rose[ean13]
1495
- name ||= obj[:name_de] + ', ' + obj[:desc_de].strip if obj[:name_de]
1496
- name ||= (item[:desc_de] + item[:name_de]) if item
1497
- name ||= obj[:sequence_name]
1498
- xml.GTIN pkg_gtin.to_s.rjust(13, '0')
1499
- xml.SALECD('A')
1500
- # maxLength for DSCR is 50 for Artikelstamm v3
1501
- xml.DSCR(name) # for description for zur_rose
1502
- name_fr = item[:name_fr] + ' ' + item[:desc_fr].strip + ' ' + package[:desc_fr] if package && package[:desc_fr]
1503
- name_fr ||= @refdata[pkg_gtin] ? @refdata[pkg_gtin][:desc_fr] : nil
1504
- # Zugelassenen Packungen has only german names
1505
- name_fr ||= (obj[:name_fr] + ', ' + obj[:desc_fr]).strip if obj[:name_fr]
1506
- # ZuRorse has only german names
1507
- name_fr ||= (item[:name_fr] + ', ' + item[:desc_fr]) if item
1508
- name_fr ||= name
1509
- xml.DSCRF(name_fr)
1510
- xml.COMP do # Manufacturer
1511
- xml.NAME obj[:company_name]
1512
- xml.GLN obj[:company_ean]
1513
- end if obj[:company_name] || obj[:company_ean]
1514
- pexf = ppub = nil
1515
- if package[:prices]
1516
- pexf ||= package[:prices][:exf_price][:price]
1517
- ppub ||= package[:prices][:pub_price][:price]
1518
- elsif @items[ean13] && @items[ean13][:packages] && @items[ean13][:packages][ean13] && (bag_prices = @items[ean13][:packages][ean13][:prices])
1519
- pexf ||= bag_prices[:exf_price][:price]
1520
- ppub ||= bag_prices[:pub_price][:price]
1490
+ sequence[:packages].each do |gtin, package|
1491
+ pkg_gtin = package[:ean13].clone
1492
+ if package[:no8] && (new_ean_13 = Oddb2xml.getEan13forNo8(package[:no8]))
1493
+ if !new_ean_13.eql?(pkg_gtin)
1494
+ puts "Setting #{new_ean_13} for #{pkg_gtin}"
1495
+ pkg_gtin = new_ean_13
1496
+ end
1497
+ end
1498
+ info = @calc_items[pkg_gtin]
1499
+ if @@emitted_v5_gtins.index(pkg_gtin)
1500
+ next
1521
1501
  else
1522
- pexf ||= obj[:price]
1523
- ppub ||= obj[:pub_price]
1502
+ @@emitted_v5_gtins << pkg_gtin.clone
1524
1503
  end
1525
- ppub = nil if ppub && ppub.size == 0
1526
- pexf = nil if pexf && pexf.size == 0
1527
- xml.PEXF pexf if pexf
1528
- xml.PPUB ppub if ppub
1529
- measure = ''
1530
- if info
1531
- # MEASSURE Measurement Unit,e.g. Pills or milliliters
1532
- # <DSCR>HIRUDOID Creme 3 mg/g 40 g</DSCR>
1533
- xml.PKG_SIZE info.pkg_size.to_i if info.pkg_size
1534
- if info.measure
1535
- measure = info.measure
1536
- elsif info.pkg_size && info.unit
1537
- measure = info.pkg_size + ' ' + info.unit
1538
- elsif info.pkg_size
1539
- measure = info.pkg_size
1504
+ options = {"PHARMATYPE" => "P"}
1505
+ xml.ITEM(options) do
1506
+ name = item[:name_de] + " " + item[:desc_de].strip + " " + package[:desc_de] if package && package[:desc_de]
1507
+ name ||= @refdata[pkg_gtin] ? @refdata[pkg_gtin][:desc_de] : nil
1508
+ name ||= @infos_zur_rose[ean13][:description] if @infos_zur_rose[ean13]
1509
+ name ||= obj[:name_de] + ", " + obj[:desc_de].strip if obj[:name_de]
1510
+ name ||= (item[:desc_de] + item[:name_de]) if item
1511
+ name ||= obj[:sequence_name]
1512
+ xml.GTIN pkg_gtin.to_s.rjust(13, "0")
1513
+ xml.SALECD("A")
1514
+ # maxLength for DSCR is 50 for Artikelstamm v3
1515
+ xml.DSCR(name) # for description for zur_rose
1516
+ name_fr = item[:name_fr] + " " + item[:desc_fr].strip + " " + package[:desc_fr] if package && package[:desc_fr]
1517
+ name_fr ||= @refdata[pkg_gtin] ? @refdata[pkg_gtin][:desc_fr] : nil
1518
+ # Zugelassenen Packungen has only german names
1519
+ name_fr ||= (obj[:name_fr] + ", " + obj[:desc_fr]).strip if obj[:name_fr]
1520
+ # ZuRorse has only german names
1521
+ name_fr ||= (item[:name_fr] + ", " + item[:desc_fr]) if item
1522
+ name_fr ||= name
1523
+ xml.DSCRF(name_fr)
1524
+ if obj[:company_name] || obj[:company_ean]
1525
+ xml.COMP do # Manufacturer
1526
+ xml.NAME obj[:company_name][0..99] # limit to 100 chars as in XSD
1527
+ xml.GLN obj[:company_ean]
1528
+ end
1540
1529
  end
1541
- xml.MEASURE measure
1542
- xml.MEASUREF measure
1543
- # Die Darreichungsform dieses Items. zB Tablette(n) oder Spritze(n)
1544
- xml.DOSAGE_FORM info.galenic_form.descriptions['de'] if info.galenic_form.descriptions['de']
1545
- xml.DOSAGE_FORMF info.galenic_form.descriptions['fr'] if info.galenic_form.descriptions['fr']
1546
- end
1547
- xml.SL_ENTRY 'true' if sl_gtins.index(pkg_gtin)
1548
- xml.IKSCAT package[:swissmedic_category] if package[:swissmedic_category] && package[:swissmedic_category].length > 0
1549
- xml.GENERIC_TYPE sequence[:org_gen_code] if sequence[:org_gen_code] && !sequence[:org_gen_code].empty?
1550
- xml.LPPV 'true' if @lppvs[pkg_gtin.to_s] # detect_nincd
1551
- case item[:deductible]
1552
- when 'Y'; xml.DEDUCTIBLE 20; # 20%
1553
- when 'N'; xml.DEDUCTIBLE 10; # 10%
1554
- end if item && item[:deductible]
1555
- prodno = Oddb2xml.getProdnoForEan13(pkg_gtin)
1556
- atc = package[:atc_code]
1557
- atc ||= @refdata[pkg_gtin][:seq][:atc_code] if @refdata[pkg_gtin]
1558
- unless prodno # find a prodno from packages for vaccinations
1559
- if atc && /^J07/.match(atc) && !/^J07AX/.match(atc)
1560
- pack = @packs.values.find{ |v| v && v[:atc_code].eql?(atc)}
1561
- if pack
1562
- prodno = pack[:prodno]
1563
- Oddb2xml.log "Patching vaccination for #{pkg_gtin} #{atc} #{name} via prodno #{prodno}"
1564
- else
1565
- Oddb2xml.log "unable to find a pack/prodno for vaccination for #{pkg_gtin} #{atc} #{name}"
1530
+ pexf = ppub = nil
1531
+ if package[:prices]
1532
+ pexf ||= package[:prices][:exf_price][:price]
1533
+ ppub ||= package[:prices][:pub_price][:price]
1534
+ elsif @items[ean13] && @items[ean13][:packages] && @items[ean13][:packages][ean13] && (bag_prices = @items[ean13][:packages][ean13][:prices])
1535
+ pexf ||= bag_prices[:exf_price][:price]
1536
+ ppub ||= bag_prices[:pub_price][:price]
1537
+ else
1538
+ pexf ||= obj[:price]
1539
+ ppub ||= obj[:pub_price]
1540
+ end
1541
+ ppub = nil if ppub && ppub.size == 0
1542
+ pexf = nil if pexf && pexf.size == 0
1543
+ if !(obj[:price] && !obj[:price].empty?) || !(obj[:pub_price] && !obj[:pub_price].empty?)
1544
+ zur_rose_detail = @infos_zur_rose.values.find { |x| x[:ean13].to_i == ean13.to_i }
1545
+ if zur_rose_detail
1546
+ pexf ||= zur_rose_detail[:price]
1547
+ ppub ||= zur_rose_detail[:pub_price]
1548
+ end
1549
+ end
1550
+ xml.PEXF pexf if pexf
1551
+ xml.PPUB ppub if ppub
1552
+ measure = ""
1553
+ if info
1554
+ # MEASSURE Measurement Unit,e.g. Pills or milliliters
1555
+ # <DSCR>HIRUDOID Creme 3 mg/g 40 g</DSCR>
1556
+ xml.PKG_SIZE info.pkg_size.to_i if info.pkg_size
1557
+ if info.measure
1558
+ measure = info.measure
1559
+ elsif info.pkg_size && info.unit
1560
+ measure = info.pkg_size + " " + info.unit
1561
+ elsif info.pkg_size
1562
+ measure = info.pkg_size
1563
+ end
1564
+ xml.MEASURE measure
1565
+ xml.MEASUREF measure
1566
+ # Die Darreichungsform dieses Items. zB Tablette(n) oder Spritze(n)
1567
+ xml.DOSAGE_FORM info.galenic_form.descriptions["de"] if info.galenic_form.descriptions["de"]
1568
+ xml.DOSAGE_FORMF info.galenic_form.descriptions["fr"] if info.galenic_form.descriptions["fr"]
1569
+ end
1570
+ xml.SL_ENTRY "true" if sl_gtins.index(pkg_gtin)
1571
+ xml.IKSCAT package[:swissmedic_category] if package[:swissmedic_category] && package[:swissmedic_category].length > 0
1572
+ xml.GENERIC_TYPE sequence[:org_gen_code] if sequence[:org_gen_code] && !sequence[:org_gen_code].empty?
1573
+ xml.LPPV "true" if @lppvs[pkg_gtin.to_s] # detect_nincd
1574
+ if item && item[:deductible]
1575
+ case item[:deductible]
1576
+ when "Y" then xml.DEDUCTIBLE 20; # 20%
1577
+ when "N" then xml.DEDUCTIBLE 10; # 10%
1578
+ end
1579
+ end
1580
+ prodno = Oddb2xml.getProdnoForEan13(pkg_gtin)
1581
+ atc = package[:atc_code]
1582
+ refdata_atc = @refdata[pkg_gtin][:atc_code] if @refdata && @refdata[pkg_gtin] && @refdata[pkg_gtin]
1583
+ if refdata_atc && atc.nil?
1584
+ puts "WARNING: #{pkg_gtin} ATC-code from refdata #{refdata_atc} as Swissmedic ATC is nil #{name}"
1585
+ atc = refdata_atc
1586
+ end
1587
+ unless prodno # find a prodno from packages for vaccinations
1588
+ if atc && /^J07/.match(atc) && !/^J07AX/.match(atc)
1589
+ pack = @packs.values.find { |v| v && v[:atc_code].eql?(atc) }
1590
+ if pack
1591
+ prodno = pack[:prodno]
1592
+ Oddb2xml.log "Patching vaccination for #{pkg_gtin} #{atc} #{name} via prodno #{prodno}"
1593
+ else
1594
+ Oddb2xml.log "unable to find a pack/prodno for vaccination for #{pkg_gtin} #{atc} #{name}"
1595
+ end
1566
1596
  end
1567
1597
  end
1598
+ xml.PRODNO prodno if prodno
1599
+ @csv_file << [pkg_gtin, name, package[:unit], measure,
1600
+ pexf || "",
1601
+ ppub || "",
1602
+ prodno, atc, package[:substance_swissmedic],
1603
+ sequence[:org_gen_code], package[:ith_swissmedic],
1604
+ @items[pkg_gtin] ? "SL" : ""]
1568
1605
  end
1569
- xml.PRODNO prodno if prodno
1570
- csv = []
1571
- @csv_file << [pkg_gtin, name, package[:unit], measure,
1572
- pexf ? pexf : '',
1573
- ppub ? ppub : '',
1574
- prodno, atc, package[:substance_swissmedic],
1575
- sequence[:org_gen_code], package[:ith_swissmedic],
1576
- @items[pkg_gtin] ? 'SL' : '',
1577
- ]
1578
1606
  end
1579
- end
1580
- else # non pharma
1581
- if @@emitted_v5_gtins.index(ean13)
1582
- next
1583
- else
1584
- @@emitted_v5_gtins << ean13.clone
1585
- end
1586
- # Set the pharmatype to 'Y' for outdated products, which are no longer found
1587
- # in refdata/packungen
1588
- chap70 = nil
1589
- if @chapter70items.values.find {|x| x[:pharmacode] && x[:pharmacode].eql?(obj[:pharmacode])}
1590
- Oddb2xml.log "found chapter #{obj[:pharmacode]}" if $VERBOSE
1591
- chap70 = true
1592
- end
1593
- patched_pharma_type = (/^7680/.match(ean13.to_s.rjust(13, '0')) || chap70 ? 'P': 'N' )
1594
- next if /^#{Oddb2xml::FAKE_GTIN_START}/.match(ean13.to_s)
1595
- xml.ITEM({'PHARMATYPE' => patched_pharma_type }) do
1596
- xml.GTIN ean13.to_s.rjust(13, '0')
1597
- xml.PHAR obj[:pharmacode] if obj[:pharmacode] && obj[:pharmacode].length > 0
1598
- emit_salecd(xml, ean13, obj)
1599
- description = obj[:desc_de] || obj[:description] # for description for zur_rose
1600
- xml.DSCR(description)
1601
- xml.DSCRF(obj[:desc_fr] || '--missing--')
1602
- xml.COMP do
1603
- xml.GLN obj[:company_ean]
1604
- end if obj[:company_ean] && !obj[:company_ean].empty?
1605
- if !(obj[:price] && !obj[:price].empty?) || !(obj[:pub_price] && !obj[:pub_price].empty?)
1606
- zur_rose_detail = @infos_zur_rose.values.find{|x| x[:ean13].to_i == ean13.to_i}
1607
+ else # non pharma
1608
+ if @@emitted_v5_gtins.index(ean13)
1609
+ next
1610
+ else
1611
+ @@emitted_v5_gtins << ean13.clone
1607
1612
  end
1608
- ppub = nil; pexf=nil
1609
- if obj[:price] && !obj[:price].empty?
1610
- xml.PEXF (pexf = obj[:price])
1611
- elsif zur_rose_detail
1612
- if zur_rose_detail[:price] && !zur_rose_detail[:price].empty? && !zur_rose_detail[:price].eql?('0.00')
1613
- Oddb2xml.log "NonPharma: #{ean13} adding PEXF #{zur_rose_detail[:price]} #{description}"
1614
- xml.PEXF (pexf = zur_rose_detail[:price])
1615
- end
1613
+ # Set the pharmatype to 'Y' for outdated products, which are no longer found
1614
+ # in refdata/packungen
1615
+ chap70 = nil
1616
+ if @chapter70items.values.find { |x| x[:pharmacode]&.eql?(obj[:pharmacode]) }
1617
+ Oddb2xml.log "found chapter #{obj[:pharmacode]}" if $VERBOSE
1618
+ chap70 = true
1616
1619
  end
1617
- if obj[:pub_price] && !obj[:pub_price].empty?
1618
- xml.PPUB (ppub = obj[:pub_price])
1619
- elsif zur_rose_detail
1620
- if zur_rose_detail[:pub_price] && !zur_rose_detail[:pub_price].empty? && !zur_rose_detail[:pub_price].eql?('0.00')
1621
- Oddb2xml.log "NonPharma: #{ean13} adding PPUB #{zur_rose_detail[:pub_price]} #{description}"
1622
- xml.PPUB (ppub = zur_rose_detail[:pub_price])
1620
+ patched_pharma_type = (/^7680/.match(ean13.to_s.rjust(13, "0")) || chap70 ? "P" : "N")
1621
+ next if /^#{Oddb2xml::FAKE_GTIN_START}/o.match?(ean13.to_s)
1622
+ next if obj[:data_origin].eql?("zur_rose") && /^7680/.match(ean13) # must skip inactiv items
1623
+ xml.ITEM({"PHARMATYPE" => patched_pharma_type}) do
1624
+ xml.GTIN ean13.to_s.rjust(13, "0")
1625
+ if obj[:pharmacode] && obj[:pharmacode].length > 0
1626
+ xml.PHAR obj[:pharmacode]
1627
+ elsif (zur_rose = @infos_zur_rose[ean13])
1628
+ puts "Artikelstamm: Adding #{zur_rose[:pharmacode]} to article GTIN #{ean13}"
1629
+ xml.PHAR zur_rose[:pharmacode]
1630
+ elsif /^7680/.match?(ean13)
1631
+ puts "Artikelstamm: No pharmacode for article GTIN #{ean13} via ZurRose"
1632
+ end
1633
+ emit_salecd(xml, ean13, obj)
1634
+ description = obj[:desc_de] || obj[:description] # for description for zur_rose
1635
+ xml.DSCR(description)
1636
+ xml.DSCRF(obj[:desc_fr] || "--missing--")
1637
+ if obj[:company_ean] && !obj[:company_ean].empty?
1638
+ xml.COMP do
1639
+ xml.GLN obj[:company_ean]
1640
+ end
1641
+ end
1642
+ if !(obj[:price] && !obj[:price].empty?) || !(obj[:pub_price] && !obj[:pub_price].empty?)
1643
+ zur_rose_detail = @infos_zur_rose.values.find { |x| x[:ean13].to_i == ean13.to_i }
1644
+ end
1645
+ ppub = nil
1646
+ pexf = nil
1647
+ if obj[:price] && !obj[:price].empty?
1648
+ xml.PEXF(pexf = obj[:price])
1649
+ elsif zur_rose_detail
1650
+ if zur_rose_detail[:price] && !zur_rose_detail[:price].empty? && !zur_rose_detail[:price].eql?("0.00")
1651
+ # Oddb2xml.log "NonPharma: #{ean13} adding PEXF #{zur_rose_detail[:price]} #{description}"
1652
+ xml.PEXF(pexf = zur_rose_detail[:price])
1653
+ end
1654
+ end
1655
+ if obj[:pub_price] && !obj[:pub_price].empty?
1656
+ xml.PPUB(ppub = obj[:pub_price])
1657
+ elsif zur_rose_detail
1658
+ if zur_rose_detail[:pub_price] && !zur_rose_detail[:pub_price].empty? && !zur_rose_detail[:pub_price].eql?("0.00")
1659
+ # Oddb2xml.log "NonPharma: #{ean13} adding PPUB #{zur_rose_detail[:pub_price]} #{description}"
1660
+ xml.PPUB(ppub = zur_rose_detail[:pub_price])
1661
+ end
1662
+ end
1663
+ @csv_file << [ean13, description, "", "", pexf, ppub, "", "", "", "", "", ""]
1664
+ if chap70
1665
+ xml.comment "Chapter70 hack #{ean13.to_s.rjust(13, "0")} #{description.encode(xml: :text).gsub("--", "-")}"
1666
+ xml.SL_ENTRY "true"
1667
+ xml.PRODNO obj[:pharmacode]
1623
1668
  end
1624
- end
1625
- @csv_file << [ ean13, description, '', '', pexf, ppub, '', '', '', '', '', '' ]
1626
- if chap70
1627
- xml.comment "Chapter70 hack #{ean13.to_s.rjust(13, '0')} #{description.encode(:xml => :text).gsub('--','-')}"
1628
- xml.SL_ENTRY 'true'
1629
- xml.PRODNO obj[:pharmacode]
1630
1669
  end
1631
1670
  end
1632
1671
  end
1672
+ @csv_file.close if @csv_file && !@csv_file.closed?
1673
+ nr_items
1633
1674
  end
1634
- @csv_file.close if @csv_file && !@csv_file.closed?
1635
- nr_items
1636
1675
  end
1637
1676
  unless @prepared
1638
- require 'oddb2xml/chapter_70_hack'
1639
- Oddb2xml::Chapter70xtractor.parse()
1677
+ require "oddb2xml/chapter_70_hack"
1678
+ Oddb2xml::Chapter70xtractor.parse
1640
1679
  @chapter70items = Oddb2xml::Chapter70xtractor.items
1641
1680
  prepare_limitations
1642
1681
  prepare_articles
@@ -1645,33 +1684,25 @@ module Oddb2xml
1645
1684
  prepare_calc_items(suppress_composition_parsing: true)
1646
1685
  @prepared = true
1647
1686
  @old_rose_size = @infos_zur_rose.size
1648
- @infos_zur_rose.each do |ean13, value|
1649
- if /^7680/.match(ean13.to_s) && @options[:artikelstamm]
1650
- @infos_zur_rose.delete(ean13)
1651
- end
1652
- end if false
1653
- @new_rose_size = @infos_zur_rose.size
1654
1687
  end
1655
1688
  nr_products = 0
1656
1689
  nr_articles = 0
1657
1690
  @nr_articles = 0
1658
1691
  used_limitations = []
1659
- Oddb2xml.log "#{variant}: Deleted #{@old_rose_size - @new_rose_size} entries from ZurRose where GTIN start with 7680 (Swissmedic)"
1660
1692
  # Oddb2xml.log "#{variant} #{nr_products} of #{@products.size} articles and ignore #{@@gtin2ignore.size} gtins specified via #{@@ignore_file}"
1661
- _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
1693
+ a_builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
1662
1694
  xml.doc.tag_suffix = @tag_suffix
1663
- datetime = Time.new.strftime('%FT%T%z')
1664
1695
  elexis_strftime_format = "%FT%T\.%L%:z"
1665
- @@cumul_ver = (Date.today.year-2013)*12+Date.today.month
1666
- options_xml = {
1667
- 'xmlns' => 'http://elexis.ch/Elexis_Artikelstamm_v5',
1668
- 'CREATION_DATETIME' => Time.new.strftime(elexis_strftime_format),
1669
- 'BUILD_DATETIME' => Time.new.strftime(elexis_strftime_format),
1670
- 'DATA_SOURCE' => 'oddb2xml'
1696
+ @@cumul_ver = (Date.today.year - 2013) * 12 + Date.today.month
1697
+ options_xml = {
1698
+ "xmlns" => "http://elexis.ch/Elexis_Artikelstamm_v5",
1699
+ "CREATION_DATETIME" => Time.new.strftime(elexis_strftime_format),
1700
+ "BUILD_DATETIME" => Time.new.strftime(elexis_strftime_format),
1701
+ "DATA_SOURCE" => "oddb2xml"
1671
1702
  }
1672
1703
  emitted_prodno = []
1673
1704
  no8_to_prodno = {}
1674
- @packs.collect{ |key, val| no8_to_prodno[key] = val [:prodno] }
1705
+ @packs.collect { |key, val| no8_to_prodno[key] = val [:prodno] }
1675
1706
  xml.comment("Produced by #{__FILE__} version #{VERSION} at #{Time.now}")
1676
1707
  xml.ARTIKELSTAMM(options_xml) do
1677
1708
  xml.PRODUCTS do
@@ -1679,22 +1710,22 @@ module Oddb2xml
1679
1710
  products.each do |product|
1680
1711
  ean13 = product[0]
1681
1712
  obj = product[1]
1682
- next if /^Q/i.match(obj[:atc])
1713
+ next if /^Q/i.match?(obj[:atc])
1683
1714
  ean = obj[:ean13]
1684
1715
  sequence = obj[:seq]
1685
1716
  sequence ||= @products[ean][:seq] if @products[ean]
1686
- next unless check_name(obj, :de)
1687
- ppac = ((_ppac = @packs[ean.to_s[4..11]] and !_ppac[:is_tier]) ? _ppac : {})
1688
- prodno = ppac[:prodno] if ppac[:prodno] and !ppac[:prodno].empty?
1717
+ next unless check_article_name(obj, :de)
1718
+ ppac = ((a_ppac = @packs[ean.to_s[4..11]]) && !a_ppac[:is_tier] ? a_ppac : {})
1719
+ prodno = ppac[:prodno] if ppac[:prodno] && !ppac[:prodno].empty?
1689
1720
  prodno = obj[:pharmacode] if obj[:chapter70]
1690
- myPack = @packs.values.find{ |x| x[:iksnr].to_i == obj[:seq][:swissmedic_number5].to_i } if obj[:seq]
1691
- if myPack && !prodno
1692
- prodno ||= myPack[:prodno]
1693
- puts "Setting prodno #{prodno} for #{ean13} #{myPack[:sequence_name]}"
1721
+ my_pack = @packs.values.find { |x| x[:iksnr].to_i == obj[:seq][:swissmedic_number5].to_i } if obj[:seq]
1722
+ if my_pack && !prodno
1723
+ prodno ||= my_pack[:prodno]
1724
+ puts "Setting prodno #{prodno} for #{ean13} #{my_pack[:sequence_name]}"
1694
1725
  end
1695
1726
  next unless prodno
1696
1727
  next if emitted_prodno.index(prodno)
1697
- sequence ||= @articles.find{|x| x[:ean13].eql?(ean)}
1728
+ sequence ||= @articles.find { |x| x[:ean13].eql?(ean) }
1698
1729
  unless obj[:chapter70]
1699
1730
  next unless sequence && (sequence[:name_de] || sequence[:desc_de])
1700
1731
  if Oddb2xml.getEan13forProdno(prodno).size == 0 && !obj[:no8].eql?(Oddb2xml.getNo8ForEan13(ean))
@@ -1707,44 +1738,43 @@ module Oddb2xml
1707
1738
  xml.PRODUCT do
1708
1739
  xml.PRODNO prodno
1709
1740
  if sequence
1710
- xml.SALECD('A') # these products are always active!
1741
+ xml.SALECD("A") # these products are always active!
1711
1742
  name_de = "#{sequence[:name_de]} #{sequence[:desc_de]}".strip if sequence[:name_de]
1712
- unless name_de # eg. 7680002770014 Coeur-Vaisseaux Sérocytol, suppositoire
1713
- if ppac && /stk/i.match( sequence[:desc_de])
1714
- name_de = ppac[:sequence_name]
1715
- else
1716
- name_de = sequence[:desc_de]
1717
- end
1743
+ name_de ||= if ppac && /stk/i.match(sequence[:desc_de])
1744
+ ppac[:sequence_name]
1745
+ else
1746
+ sequence[:desc_de]
1718
1747
  end
1719
1748
  name_fr = "#{sequence[:name_fr]} #{sequence[:desc_fr]}".strip if sequence[:name_fr]
1720
1749
  name_fr ||= (ppac && ppac[:sequence_name])
1721
- override(xml, prodno, :DSCR, name_de.strip)
1750
+ override(xml, prodno, :DSCR, name_de.strip)
1722
1751
  override(xml, prodno, :DSCRF, name_fr.strip)
1752
+ # use overriden ATC if possibel
1753
+ atc = sequence[:atc] || sequence[:atc_code]
1754
+ xml.ATC atc if atc && !atc.empty?
1723
1755
  end
1724
- xml.ATC sequence[:atc_code] if sequence && sequence[:atc_code] && !sequence[:atc_code].empty?
1725
1756
  if sequence && sequence[:packages] && (first_package = sequence[:packages].values.first) &&
1726
- (first_limitation = first_package[:limitations].first)
1757
+ (first_limitation = first_package[:limitations].first)
1727
1758
  lim_code = first_limitation[:code]
1728
1759
  used_limitations << lim_code unless used_limitations.index(lim_code)
1729
1760
  xml.LIMNAMEBAG lim_code
1730
1761
  elsif obj[:chapter70]
1731
- xml.comment "Chapter70 hack prodno #{prodno} #{obj[:description].encode(:xml => :text).gsub('--','-')}"
1732
- xml.SALECD('A') # these products are always active!
1762
+ xml.comment "Chapter70 hack prodno #{prodno} #{obj[:description].encode(xml: :text).gsub("--", "-")}"
1763
+ xml.SALECD("A") # these products are always active!
1733
1764
  xml.DSCR obj[:description]
1734
- xml.DSCRF ''
1765
+ xml.DSCRF ""
1735
1766
  if @limitations.index(obj[:code])
1736
1767
  xml.LIMNAMEBAG obj[:code]
1737
1768
  used_limitations << obj[:code]
1738
1769
  end
1739
1770
  end
1740
1771
  if sequence && sequence[:substances]
1741
- value = nil
1742
- if sequence[:substances].size > 1
1743
- value = 'Verschiedene Kombinationen'
1772
+ value = if sequence[:substances].size > 1
1773
+ "Verschiedene Kombinationen"
1744
1774
  elsif sequence[:substances].first
1745
- value = sequence[:substances].first[:name]
1775
+ sequence[:substances].first[:name]
1746
1776
  else
1747
- value = obj[:sub]
1777
+ obj[:sub]
1748
1778
  end
1749
1779
  override(xml, prodno, :SUBSTANCE, value) if value
1750
1780
  end
@@ -1763,9 +1793,9 @@ module Oddb2xml
1763
1793
  xml.LIMITATION do
1764
1794
  xml.comment "Chapter70 2 hack" if lim[:chap70]
1765
1795
  xml.LIMNAMEBAG lim[:code] # original LIMCD
1766
- xml.DSCR Oddb2xml.html_decode(lim[:desc_de])
1767
- xml.DSCRF Oddb2xml.html_decode(lim[:desc_fr])
1768
- xml.LIMITATION_PTS (lim[:value].to_s.length > 1 ? lim[:value] : 1)
1796
+ xml.DSCR Oddb2xml.html_decode(lim[:desc_de])
1797
+ xml.DSCRF Oddb2xml.html_decode(lim[:desc_fr])
1798
+ xml.LIMITATION_PTS(lim[:value].to_s.length > 1 ? lim[:value] : 1)
1769
1799
  end
1770
1800
  end
1771
1801
  end
@@ -1776,17 +1806,19 @@ module Oddb2xml
1776
1806
  end
1777
1807
  Oddb2xml.log "#{variant}. Done #{nr_products} of #{@products.size} products, #{@limitations.size} limitations and #{nr_articles}/#{@nr_articles} articles. @@emitted_v5_gtins #{@@emitted_v5_gtins.size}"
1778
1808
  # we don't add a SHA256 hash for each element in the article
1779
- # Oddb2xml.add_hash(_builder.to_xml)
1809
+ # Oddb2xml.add_hash(a_builder.to_xml)
1780
1810
  # doc = REXML::Document.new( source, { :raw => :all })
1781
1811
  # doc.write( $stdout, 0 )
1782
1812
  lines = []
1783
- lines << " - #{sprintf('%5d', @products.size)} products"
1784
- lines << " - #{sprintf('%5d', @limitations.size)} limitations"
1785
- lines << " - #{sprintf('%5d', @nr_articles)} articles"
1786
- lines << " - #{sprintf('%5d', @@gtin2ignore.size)} ignored GTINS"
1813
+ lines << " - #{sprintf("%5d", @products.size)} products"
1814
+ lines << " - #{sprintf("%5d", @limitations.size)} limitations"
1815
+ lines << " - #{sprintf("%5d", @nr_articles)} articles"
1816
+ lines << " - #{sprintf("%5d", @@gtin2ignore.size)} ignored GTINS"
1787
1817
  @@articlestamm_v5_info_lines = lines
1788
- _builder.to_xml({:indent => 4, :encoding => 'UTF-8'})
1818
+ a_builder.to_xml({indent: 4, encoding: "UTF-8"})
1789
1819
  end
1820
+
1821
+ private_class_method
1790
1822
  def self.articlestamm_v5_info_lines
1791
1823
  @@articlestamm_v5_info_lines
1792
1824
  end