oddb2xml 1.9.4 → 1.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|