oddb2xml 1.9.4 → 1.9.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,217 @@
1
+ ---
2
+ 754720: !ruby/struct:Struct::GalenicGroup
3
+ oid: 754720
4
+ descriptions:
5
+ de: Kaugummi
6
+ en: Chewing Gum
7
+ fr: Chewing Gum
8
+ 890150: !ruby/struct:Struct::GalenicGroup
9
+ oid: 890150
10
+ descriptions:
11
+ de: Brausetabletten
12
+ en: Solutabs
13
+ fr: Comprimés Effervescents
14
+ 754487: !ruby/struct:Struct::GalenicGroup
15
+ oid: 754487
16
+ descriptions:
17
+ de: Dialyse
18
+ en: Dialysis
19
+ fr: Dialyse
20
+ 890432: !ruby/struct:Struct::GalenicGroup
21
+ oid: 890432
22
+ descriptions:
23
+ de: Tropfen
24
+ en: Drops
25
+ fr: Gouttes
26
+ 7830083: !ruby/struct:Struct::GalenicGroup
27
+ oid: 7830083
28
+ descriptions:
29
+ de: Lösbar zur Einnahme Retard
30
+ en: Delayed releas soluble for ingestion
31
+ fr: Soluble pour ingestion retard
32
+ 1470796: !ruby/struct:Struct::GalenicGroup
33
+ oid: 1470796
34
+ descriptions:
35
+ de: Klistiere
36
+ en: Enemas
37
+ fr: Lavements
38
+ 714576: !ruby/struct:Struct::GalenicGroup
39
+ oid: 714576
40
+ descriptions:
41
+ de: Klebstoff
42
+ en: Adhesive
43
+ fr: Gluten
44
+ 1479254: !ruby/struct:Struct::GalenicGroup
45
+ oid: 1479254
46
+ descriptions:
47
+ de: Tests
48
+ en: Tests
49
+ fr: Tests
50
+ 9672801: !ruby/struct:Struct::GalenicGroup
51
+ oid: 9672801
52
+ descriptions:
53
+ de: Lösungsmittel
54
+ en: Solvent
55
+ fr: Solvant
56
+ 1470567: !ruby/struct:Struct::GalenicGroup
57
+ oid: 1470567
58
+ descriptions:
59
+ de: Subkutane Implantate
60
+ en: Hypodermic Implants
61
+ fr: Implants hypodermiques
62
+ 890480: !ruby/struct:Struct::GalenicGroup
63
+ oid: 890480
64
+ descriptions:
65
+ de: Gastrointenstinales Therapiesystem
66
+ en: Gastro-Intestinal Therapeutic System
67
+ fr: Système Therapeutique Gastro-Intestinale
68
+ 9672817: !ruby/struct:Struct::GalenicGroup
69
+ oid: 9672817
70
+ descriptions:
71
+ de: Tupfer/Gaze
72
+ en: Swab/Gauze
73
+ fr: Compresse/Gaze
74
+ 1478018: !ruby/struct:Struct::GalenicGroup
75
+ oid: 1478018
76
+ descriptions:
77
+ de: Tinkturen/Desinfektion
78
+ en: Tinctures/Disinfection
79
+ fr: Teintures/Désinfection
80
+ 1471897: !ruby/struct:Struct::GalenicGroup
81
+ oid: 1471897
82
+ descriptions:
83
+ de: Lösbar zur Injektion/Infusion
84
+ en: Soluble for injection/infusion
85
+ fr: Soluble pour injection/infusion
86
+ 1472921: !ruby/struct:Struct::GalenicGroup
87
+ oid: 1472921
88
+ descriptions:
89
+ de: Rektal-Produkte
90
+ en: Rectal Products
91
+ fr: Produits Rectaux
92
+ 1471899: !ruby/struct:Struct::GalenicGroup
93
+ oid: 1471899
94
+ descriptions:
95
+ de: Seifen und Shampoos
96
+ en: Soaps and Shampoos
97
+ fr: Savons et Shampoos
98
+ 1472699: !ruby/struct:Struct::GalenicGroup
99
+ oid: 1472699
100
+ descriptions:
101
+ de: Buccal-/Dentalprodukte
102
+ en: Buccal/dental products
103
+ fr: Produits buccodentaires
104
+ 1472713: !ruby/struct:Struct::GalenicGroup
105
+ oid: 1472713
106
+ descriptions:
107
+ de: Spray/Puder
108
+ en: Spray/Powder
109
+ fr: Spray/Poudre
110
+ 1472742: !ruby/struct:Struct::GalenicGroup
111
+ oid: 1472742
112
+ descriptions:
113
+ de: Trinkflüssigkeiten Retard
114
+ en: Delayed release drinkable liquids
115
+ fr: Liquides buvables retard
116
+ 1: !ruby/struct:Struct::GalenicGroup
117
+ oid: 1
118
+ descriptions:
119
+ de: unbekannt
120
+ en: unbekannt
121
+ fr: unbekannt
122
+ 2: !ruby/struct:Struct::GalenicGroup
123
+ oid: 2
124
+ descriptions:
125
+ de: Tabletten
126
+ en: Tablets
127
+ fr: Comprimés
128
+ 3: !ruby/struct:Struct::GalenicGroup
129
+ oid: 3
130
+ descriptions:
131
+ de: Injektion/Infusion
132
+ en: Injection/Infusion
133
+ fr: Injection/Infusion
134
+ 4: !ruby/struct:Struct::GalenicGroup
135
+ oid: 4
136
+ descriptions:
137
+ de: Salben
138
+ en: Ointments
139
+ fr: Onguents
140
+ 5: !ruby/struct:Struct::GalenicGroup
141
+ oid: 5
142
+ descriptions:
143
+ de: Augenmittel
144
+ en: Ophtalmics
145
+ fr: Préparations oculaires
146
+ 6: !ruby/struct:Struct::GalenicGroup
147
+ oid: 6
148
+ descriptions:
149
+ de: Inhalation
150
+ en: Inhalation
151
+ fr: Inhalation
152
+ 7: !ruby/struct:Struct::GalenicGroup
153
+ oid: 7
154
+ descriptions:
155
+ de: Lösbar zur Einnahme
156
+ en: Soluble for ingestion
157
+ fr: Soluble pour ingestion
158
+ 8: !ruby/struct:Struct::GalenicGroup
159
+ oid: 8
160
+ descriptions:
161
+ de: Badezusatz
162
+ en: Bath additives
163
+ fr: Bains
164
+ 9: !ruby/struct:Struct::GalenicGroup
165
+ oid: 9
166
+ descriptions:
167
+ de: Essbare
168
+ en: Edibles
169
+ fr: Denrées
170
+ 10: !ruby/struct:Struct::GalenicGroup
171
+ oid: 10
172
+ descriptions:
173
+ de: Lutschtabletten
174
+ en: Lozenges
175
+ fr: Comprimés à succer
176
+ 11: !ruby/struct:Struct::GalenicGroup
177
+ oid: 11
178
+ descriptions:
179
+ de: Trinkflüssigkeiten
180
+ en: Drinkable liquids
181
+ fr: Liquides buvables
182
+ 12: !ruby/struct:Struct::GalenicGroup
183
+ oid: 12
184
+ descriptions:
185
+ de: Zubehör
186
+ en: Other
187
+ fr: Autres
188
+ 13: !ruby/struct:Struct::GalenicGroup
189
+ oid: 13
190
+ descriptions:
191
+ de: Nasenmittel
192
+ en: Nasal products
193
+ fr: Remèdes nasales
194
+ 14: !ruby/struct:Struct::GalenicGroup
195
+ oid: 14
196
+ descriptions:
197
+ de: Retard-Tabletten
198
+ en: Delayed release tablets
199
+ fr: Comprimés retards
200
+ 15: !ruby/struct:Struct::GalenicGroup
201
+ oid: 15
202
+ descriptions:
203
+ de: Vaginal-Produkte
204
+ en: Vaginal products
205
+ fr: Produits Vaginaux
206
+ 16: !ruby/struct:Struct::GalenicGroup
207
+ oid: 16
208
+ descriptions:
209
+ de: Pflaster/Transdermale Systeme
210
+ en: Patches/Transdermal Systems
211
+ fr: Pansements/Systèmes transdermales
212
+ 17: !ruby/struct:Struct::GalenicGroup
213
+ oid: 17
214
+ descriptions:
215
+ de: Suppositorien
216
+ en: Suppositories
217
+ fr: Suppositoires
@@ -1,6 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'nokogiri'
4
+ require 'oddb2xml/util'
5
+ require 'oddb2xml/calc'
6
+ require 'csv'
7
+
4
8
  class Numeric
5
9
  # round a given number to the nearest step
6
10
  def round_by(increment)
@@ -60,7 +64,7 @@ module Oddb2xml
60
64
  end
61
65
  end
62
66
  def to_xml(subject=nil)
63
- Oddb2xml.log "to_xml subject #{subject ? subject.to_s : @subject.to_s} for #{self.class}"
67
+ Oddb2xml.log "to_xml subject #{subject} #{@subject} for #{self.class}"
64
68
  if subject
65
69
  self.send('build_' + subject.to_s)
66
70
  elsif @subject
@@ -232,6 +236,7 @@ module Oddb2xml
232
236
  @products = []
233
237
  @index['DE'].each_pair do |phar, indices|
234
238
  indices.each_with_index do |index, i|
239
+ next if index and index.is_a?(Hash) and index[:atc_code] and /^Q/i.match(index[:atc_code])
235
240
  obj = {
236
241
  :seq => @items[phar] ? @items[phar] : @items[index[:ean]],
237
242
  :pac => nil,
@@ -246,6 +251,7 @@ module Oddb2xml
246
251
  :siz => '',
247
252
  :eht => '',
248
253
  :sub => '',
254
+ :comp => '',
249
255
  }
250
256
  if obj[:ean] # via EAN-Code
251
257
  obj[:no8] = obj[:ean][4..11]
@@ -264,6 +270,7 @@ module Oddb2xml
264
270
  obj[:siz] = ppac[:package_size]
265
271
  obj[:eht] = ppac[:einheit_swissmedic]
266
272
  obj[:sub] = ppac[:substance_swissmedic]
273
+ obj[:comp] = ppac[:composition_swissmedic]
267
274
  end
268
275
  if obj[:ean][0..3] == '7680'
269
276
  @products << obj
@@ -443,6 +450,7 @@ module Oddb2xml
443
450
  list = []
444
451
  length = 0
445
452
  @products.each do |obj|
453
+ next if /^Q/i.match(obj[:atc])
446
454
  seq = obj[:seq]
447
455
  length += 1
448
456
  xml.PRD('DT' => '') {
@@ -567,6 +575,7 @@ module Oddb2xml
567
575
  xml.PackGrSwissmedic obj[:siz] unless obj[:siz].empty?
568
576
  xml.EinheitSwissmedic obj[:eht] unless obj[:eht].empty?
569
577
  xml.SubstanceSwissmedic obj[:sub] unless obj[:sub].empty?
578
+ xml.CompositionSwissmedic obj[:comp] unless obj[:comp].empty?
570
579
  }
571
580
  end
572
581
  xml.RESULT {
@@ -579,6 +588,69 @@ module Oddb2xml
579
588
  end
580
589
  _builder.to_xml
581
590
  end
591
+
592
+ def build_calc
593
+ packungen_xlsx = File.join(Oddb2xml::WorkDir, "swissmedic_package.xlsx")
594
+ idx = 0
595
+ workbook = RubyXL::Parser.parse(packungen_xlsx)
596
+ items = {}
597
+ row_nr = 0
598
+ _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
599
+ xml.doc.tag_suffix = @tag_suffix
600
+ datetime = Time.new.strftime('%FT%T%z')
601
+ xml.ARTICLES(XML_OPTIONS) {
602
+ workbook.worksheets[0].each do |row|
603
+ row_nr += 1
604
+ next unless row and row.cells[0] and row.cells[0].value and row.cells[0].value.to_i > 0
605
+ iksnr = "%05i" % row.cells[0].value.to_i
606
+ seqnr = "%02d" % row.cells[1].value.to_i
607
+ no8 = sprintf('%05d',row.cells[0].value.to_i) + sprintf('%03d',row.cells[10].value.to_i)
608
+ name = row.cells[2].value
609
+ atc_code = row.cells[5] ? row.cells[5].value : nil
610
+ list_code = row.cells[6] ? row.cells[6].value : nil
611
+ package_size = row.cells[11] ? row.cells[11].value : nil
612
+ unit = row.cells[12] ? row.cells[12].value : nil
613
+ active_substance = row.cells[14] ? row.cells[14].value : nil
614
+ composition = row.cells[15] ? row.cells[15].value : nil
615
+
616
+ # skip veterinary product
617
+ next if atc_code and /^Q/i.match(atc_code)
618
+ next if list_code and /Tierarzneimittel/.match(list_code)
619
+
620
+ info = Calc.new(name, package_size, unit, composition)
621
+ ean12 = '7680' + no8
622
+ ean13 = (ean12 + Oddb2xml.calc_checksum(ean12))
623
+ items[ean13] = info
624
+ xml.ARTICLE {
625
+ xml.GTIN ean13
626
+ xml.NAME name
627
+ xml.PKG_SIZE package_size
628
+ xml.SELLING_UNITS info.selling_units
629
+ # xml.COUNT info.count
630
+ # xml.MULTI info.multi
631
+ xml.MEASURE info.measure # Nur wenn Lösung wen Spalte M ml, Spritze
632
+ # xml.ADDITION info.addition
633
+ # xml.SCALE info.scale
634
+ if info.galenic_form.is_a?(String)
635
+ xml.GALENIC_FORM info.galenic_form
636
+ xml.GALENIC_GROUP "Unknown"
637
+ else
638
+ xml.GALENIC_FORM info.galenic_form.description
639
+ xml.GALENIC_GROUP info.galenic_group ? info.galenic_group.description : "Unknown"
640
+ end
641
+ }
642
+ end
643
+ }
644
+ end
645
+ csv_name = File.join(WorkDir, 'oddb_calc.csv')
646
+ CSV.open(csv_name, "w+", :col_sep => ';') do |csv|
647
+ csv << ['gtin'] + items.values.first.headers
648
+ items.each do |key, value|
649
+ csv << [key] + value.to_array
650
+ end
651
+ end
652
+ _builder.to_xml
653
+ end
582
654
  def build_article
583
655
  prepare_limitations
584
656
  prepare_articles
@@ -0,0 +1,327 @@
1
+ # encoding: utf-8
2
+
3
+ require 'oddb2xml/util'
4
+ require 'yaml'
5
+
6
+ module Oddb2xml
7
+ # Calc is responsible for analysing the columns "Packungsgrösse" and "Einheit"
8
+ #
9
+ GalenicGroup = Struct.new("GalenicGroup", :oid, :descriptions)
10
+ GalenicForm = Struct.new("GalenicForm", :oid, :descriptions, :galenic_group)
11
+
12
+ class GalenicGroup
13
+ def description(lang = 'de')
14
+ descriptions[lang]
15
+ end
16
+ end
17
+
18
+ class GalenicForm
19
+ def description(lang = 'de')
20
+ descriptions[lang]
21
+ end
22
+ end
23
+
24
+ class Calc
25
+ FluidForms = [
26
+ 'Ampulle(n)',
27
+ 'Beutel',
28
+ 'Bolus/Boli',
29
+ 'Bq',
30
+ 'Dose(n)',
31
+ 'Durchstechflasche(n)',
32
+ 'Einmaldosenbehälter',
33
+ 'Einzeldose(n)',
34
+ 'Fertigspritze',
35
+ 'Fertigspritze(n)',
36
+ 'Flasche(n)',
37
+ 'I.E.',
38
+ 'Infusionskonzentrat',
39
+ 'Infusionslösung',
40
+ 'Inhalationen',
41
+ 'Inhalator',
42
+ 'Injektions-Set',
43
+ 'Injektions-Sets',
44
+ 'Injektor(en), vorgefüllt/Pen',
45
+ 'Klistier(e)',
46
+ 'MBq',
47
+ 'Pipetten',
48
+ 'Sachet(s)',
49
+ 'Spritze(n)',
50
+ 'Sprühstösse',
51
+ 'Stechampulle (Lyophilisat) und Ampulle (Solvens)',
52
+ 'Stechampulle',
53
+ 'Suspension',
54
+ 'Zylinderampulle(n)',
55
+ 'cartouches',
56
+ 'dose(s)',
57
+ 'flacon perforable',
58
+ 'sacchetto',
59
+ 'vorgefüllter Injektor',
60
+ ]
61
+ FesteFormen = [
62
+ 'Depotabs',
63
+ 'Dragée(s)',
64
+ 'Generator mit folgenden Aktivitäten:',
65
+ 'Filmtabletten',
66
+ 'Gerät',
67
+ 'Kapsel(n)',
68
+ 'Kautabletten',
69
+ 'Lutschtabletten',
70
+ 'Kugeln',
71
+ 'Ovulum',
72
+ 'Packung(en)',
73
+ 'Pflaster',
74
+ 'Schmelzfilme',
75
+ 'Set',
76
+ 'Strips',
77
+ 'Stück',
78
+ 'Suppositorien',
79
+ 'Tablette(n)',
80
+ 'Tüchlein',
81
+ 'Urethrastab',
82
+ 'Vaginalzäpfchen',
83
+ 'comprimé',
84
+ 'comprimé pelliculé',
85
+ 'comprimés',
86
+ 'comprimés à libération modifiée',
87
+ 'comprimés à croquer sécables',
88
+ 'imprägnierter Verband',
89
+ 'magensaftresistente Filmtabletten',
90
+ 'ovale Körper',
91
+ 'tube(s)',
92
+ ]
93
+ Mesurements = [ 'g', 'kg', 'l', 'mg', 'ml', 'cm', 'GBq']
94
+ Others = ['Kombipackung', 'emballage combiné' ]
95
+ UnknownGalenicForm = 140
96
+ UnknownGalenicGroup = 1
97
+ Data_dir = File.expand_path(File.join(File.dirname(__FILE__),'..','..', 'data'))
98
+ @@galenic_groups = YAML.load_file(File.join(Data_dir, 'gal_groups.yaml'))
99
+ @@galenic_forms = YAML.load_file(File.join(Data_dir, 'gal_forms.yaml'))
100
+ @@new_galenic_forms = []
101
+ @@names_without_galenic_forms = []
102
+ @@rules_counter = {}
103
+ attr_accessor :galenic_form, :unit, :pkg_size
104
+ attr_reader :name, :substances, :composition
105
+ attr_reader :selling_units, :count, :multi, :measure, :addition, :scale # s.a. commercial_form in oddb.org/src/model/part.rb
106
+ def self.get_galenic_group(name, lang = 'de')
107
+ @@galenic_groups.values.collect { |galenic_group|
108
+ return galenic_group if galenic_group.descriptions[lang].eql?(name)
109
+ }
110
+ @@galenic_groups[1]
111
+ end
112
+
113
+ def self.report_conversion
114
+ lines = [ '', '',
115
+ 'Report of used conversion rules',
116
+ '-------------------------------',
117
+ ''
118
+ ]
119
+ @@rules_counter.each{
120
+ | key, value|
121
+ lines << "#{key}: #{value} occurrences"
122
+ }
123
+ lines << ''
124
+ lines << ''
125
+ lines
126
+ end
127
+
128
+ def self.get_galenic_form(name, lang = 'de')
129
+ @@galenic_forms.values.collect { |galenic_form|
130
+ return galenic_form if galenic_form.descriptions[lang].eql?(name)
131
+ if name and galenic_form.descriptions[lang].eql?(name.sub(' / ', '/'))
132
+ return galenic_form
133
+ end
134
+ }
135
+ @@galenic_forms[UnknownGalenicForm]
136
+ end
137
+
138
+ def self.dump_new_galenic_forms
139
+ if @@new_galenic_forms.size > 0
140
+ "\n\n\nAdded the following galenic_forms\n"+ @@new_galenic_forms.uniq.join("\n")
141
+ else
142
+ "\n\n\nNo new galenic forms added"
143
+ end
144
+ end
145
+ def self.dump_names_without_galenic_forms
146
+ if @@names_without_galenic_forms.size > 0
147
+ "\n\n\nThe following products did not have a galenic form in column Präparateliste\n"+ @@names_without_galenic_forms.sort.uniq.join("\n")
148
+ else
149
+ "\n\n\nColumn Präparateliste has everywhere a name\n"
150
+ end
151
+ end
152
+
153
+ def initialize(name = nil, size = nil, unit = nil, composition= nil)
154
+ @name = name
155
+ @pkg_size = size
156
+ @unit = unit
157
+ # @pkg_size, @galenic_group, @galenic_form =
158
+ search_galenic_info
159
+ @composition = composition
160
+ @measure = unit if unit and not @measure
161
+ @measure = @galenic_form.description if @galenic_form and not @measure
162
+ @galenic_form ||= @@galenic_forms[UnknownGalenicForm]
163
+ end
164
+
165
+ def galenic_group
166
+ @@galenic_groups[@galenic_form.galenic_group]
167
+ end
168
+
169
+ # helper for generating csv
170
+ def headers
171
+ [ "name", "pkg_size", "selling_units", "measure",
172
+ # "count", "multi", "addition", "scale", "unit",
173
+ "galenic_form",
174
+ "galenic_group"
175
+ ]
176
+ end
177
+ def to_array
178
+ [ @name, @pkg_size, @selling_units, @measure,
179
+ # @count, @multi, @addition, @scale, @unit,
180
+ galenic_form ? galenic_form.description : '' ,
181
+ galenic_group ? galenic_group.description : ''
182
+ ]
183
+ end
184
+ def galenic_form__xxx
185
+ @galenic_form.description
186
+ end
187
+ private
188
+ def capitalize(string)
189
+ string.split(/\s+/u).collect { |word| word.capitalize }.join(' ')
190
+ end
191
+
192
+ def update_rule(rulename)
193
+ @@rules_counter[rulename] ||= 0
194
+ @@rules_counter[rulename] += 1
195
+ end
196
+
197
+ def get_selling_units(part_from_name_C, pkg_size_L, einheit_M)
198
+ begin
199
+ return pkg_size_to_int(pkg_size_L) unless part_from_name_C
200
+ part_from_name_C = part_from_name_C.gsub(/[()]/, '_')
201
+ FesteFormen.each{ |x|
202
+ if part_from_name_C and (x.gsub(/[()]/, '_')).match(part_from_name_C)
203
+ puts "feste_form in #{part_from_name_C} matched: #{x}" if $VERBOSE
204
+ update_rule('feste_form name_C')
205
+ @measure = x
206
+ return pkg_size_to_int(pkg_size_L)
207
+ end
208
+ if einheit_M and x.eql?(einheit_M)
209
+ puts "feste_form in einheit_M #{einheit_M} matched: #{x}" if $VERBOSE
210
+ update_rule('feste_form einheit_M')
211
+ @measure = x
212
+ return pkg_size_to_int(pkg_size_L)
213
+ end
214
+ }
215
+ FluidForms.each{ |x|
216
+ if part_from_name_C and x.match(part_from_name_C)
217
+ puts "liquid_form in #{part_from_name_C} matched: #{x}" if $VERBOSE
218
+ update_rule('liquid_form name_C')
219
+ @measure = x
220
+ return pkg_size_to_int(pkg_size_L, true)
221
+ end
222
+ if part_from_name_C and x.match(part_from_name_C.split(' ')[0])
223
+ puts "liquid_form in #{part_from_name_C} matched: #{x}" if $VERBOSE
224
+ update_rule('liquid_form first_part')
225
+ return pkg_size_to_int(pkg_size_L, true)
226
+ end
227
+ if einheit_M and x.eql?(einheit_M)
228
+ puts "liquid_form in einheit_M #{einheit_M} matched: #{x}" if $VERBOSE
229
+ update_rule('liquid_form einheit_M')
230
+ @measure = x
231
+ return pkg_size_to_int(pkg_size_L, true)
232
+ end
233
+ }
234
+ Mesurements.each{ |x|
235
+ if pkg_size_L and pkg_size_L.split(' ').index(x)
236
+ puts "measurement in pkg_size_L #{pkg_size_L} matched: #{x}" if $VERBOSE
237
+ update_rule('measurement pkg_size_L')
238
+ @measure = x
239
+ return pkg_size_to_int(pkg_size_L, true)
240
+ end
241
+ if einheit_M and /^#{x}$/i.match(einheit_M)
242
+ puts "measurement in einheit_M #{einheit_M} matched: #{x}" if $VERBOSE
243
+ update_rule('measurement einheit_M')
244
+ @measure = x
245
+ return pkg_size_to_int(pkg_size_L, true)
246
+ end
247
+ }
248
+ puts "Could not find anything for name_C #{part_from_name_C} pkg_size_L: #{pkg_size_L} einheit_M #{einheit_M}" if $VERBOSE
249
+ update_rule('unbekannt')
250
+ return 'unbekannt'
251
+ rescue RegexpError => e
252
+ puts "RegexpError for M: #{einheit_M} pkg_size_L #{pkg_size_L} C: #{part_from_name_C}"
253
+ update_rule('RegexpError')
254
+ return 'error'
255
+ end
256
+ end
257
+
258
+ def pkg_size_to_int(pkg_size, skip_last_part = false)
259
+ return pkg_size if pkg_size.is_a?(Fixnum)
260
+ return 1 unless pkg_size
261
+ parts = pkg_size.split(/\s*x\s*/i)
262
+ parts = parts[0..-2] if skip_last_part and parts.size > 1
263
+ last_multiplier = parts[-1].to_i > 0 ? parts[-1].to_i : 1
264
+ if parts.size == 3
265
+ return parts[0].to_i * parts[1].to_i * last_multiplier
266
+ elsif parts.size == 2
267
+ return parts[0].to_i * last_multiplier
268
+ elsif parts.size == 1
269
+ return last_multiplier
270
+ else
271
+ return 1
272
+ end
273
+ end
274
+ # Parse a string for a numerical value and unit, e.g. 1.5 ml
275
+ def self.check_for_value_and_units(what)
276
+ if m = /^([\d.]+)\s*(\D+)/.match(what)
277
+ # return [m[1], m[2] ]
278
+ return m[0].to_s
279
+ else
280
+ nil
281
+ end
282
+ end
283
+ def search_galenic_info
284
+ @substances = nil
285
+ @substances = @composition.split(/\s*,(?!\d|[^(]+\))\s*/u).collect { |name| capitalize(name) }.uniq if @composition
286
+
287
+ name = @name.clone
288
+ parts = name.split(',')
289
+ if parts.size == 1
290
+ @@names_without_galenic_forms << name
291
+ else
292
+ form_name = parts[-1].strip
293
+ @galenic_form = Calc.get_galenic_form(form_name)
294
+ # puts "oid #{UnknownGalenicForm} #{@galenic_form.oid} for #{name}"
295
+ if @galenic_form.oid == UnknownGalenicForm
296
+ @galenic_form = GalenicForm.new(0, {'de' => form_name}, @@galenic_forms[UnknownGalenicForm] )
297
+ @@new_galenic_forms << form_name
298
+ end
299
+ end
300
+ @name = name.strip
301
+ if @pkg_size.is_a?(Fixnum)
302
+ @count = @pkg_size
303
+ res = [@pkg_size]
304
+ else
305
+ res = @pkg_size ? @pkg_size.split(/x/i) : []
306
+ if res.size >= 1
307
+ @count = res[0].to_i
308
+ else
309
+ @count = 1
310
+ end
311
+ end
312
+ # check whether we find numerical and units
313
+ if res.size >= 2
314
+ if (result = Calc.check_for_value_and_units(res[1].strip)) != nil
315
+ @multi = result[1].to_f
316
+ else
317
+ @multi = res[1].to_i
318
+ end
319
+ else
320
+ @multi = 1
321
+ end
322
+ @addition = 0
323
+ @scale = 1
324
+ @selling_units = get_selling_units(form_name, @pkg_size, @unit)
325
+ end
326
+ end
327
+ end