oddb2xml 1.9.4 → 1.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/Gemfile.lock +10 -11
- data/History.txt +7 -0
- data/README.md +14 -9
- data/data/gal_forms.yaml +4704 -0
- data/data/gal_groups.yaml +217 -0
- data/lib/oddb2xml/builder.rb +73 -1
- data/lib/oddb2xml/calc.rb +327 -0
- data/lib/oddb2xml/cli.rb +23 -7
- data/lib/oddb2xml/downloader.rb +10 -4
- data/lib/oddb2xml/extractor.rb +5 -11
- data/lib/oddb2xml/options.rb +3 -0
- data/lib/oddb2xml/util.rb +12 -1
- data/lib/oddb2xml/version.rb +1 -1
- data/oddb2xml.xsd +7 -1
- data/spec/builder_spec.rb +2 -0
- data/spec/calc_spec.rb +324 -0
- data/spec/data/swissmedic_package-galenic.xlsx +0 -0
- data/spec/options_spec.rb +11 -0
- data/spec/spec_helper.rb +3 -3
- metadata +41 -34
@@ -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
|
data/lib/oddb2xml/builder.rb
CHANGED
@@ -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
|
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
|