Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
/home/masa/ywesee/oddb.org/src/model/package.rb | 358 | 354 | 98.04%
|
98.02%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
1 #!/usr/bin/env ruby |
2 # Package -- oddb -- 25.02.2003 -- hwyss@ywesee.com |
3 |
4 require 'util/persistence' |
5 require 'util/money' |
6 require 'util/today' |
7 require 'model/slentry' |
8 require 'model/ean13' |
9 require 'model/feedback_observer' |
10 require 'model/part' |
11 |
12 module ODDB |
13 class PackageCommon |
14 include Persistence |
15 @@ddd_galforms = /tabletten?/iu |
16 class << self |
17 def price_internal(price, type=nil) |
18 unless(price.is_a?(Util::Money)) |
19 price = Util::Money.new(price, type, 'CH') |
20 end |
21 price |
22 end |
23 def registration_data(*names) |
24 names.each { |name| |
25 define_method(name) { |
26 if(@sequence && (reg = @sequence.registration)) |
27 reg.send(name) |
28 end |
29 } |
30 } |
31 end |
32 def sequence_data(*names) |
33 names.each { |name| |
34 define_method(name) { |
35 @sequence && @sequence.send(name) |
36 } |
37 } |
38 end |
39 end |
40 attr_reader :ikscd, :sl_entry, :narcotics, :parts, :pharmacode |
41 attr_accessor :sequence, :ikscat, :generic_group, :sl_generic_type, |
42 :price_exfactory, :price_public, :pretty_dose, :market_date, |
43 :medwin_ikscd, :out_of_trade, :refdata_override, :deductible, :lppv, |
44 :disable, :swissmedic_source, :descr, :preview_with_market_date, |
45 :generic_group_factor, :photo_link, :disable_ddd_price, :ddd_dose, |
46 :deductible_m # for just-medical |
47 alias :pointer_descr :ikscd |
48 registration_data :comarketing_with, :complementary_type, :expiration_date, |
49 :expired?, :export_flag, :fachinfo_active?, :generic_type, |
50 :inactive_date, :pdf_fachinfos, :registration_date, :revision_date, |
51 :patent, :patent_protected?, :vaccine, :parallel_import, :minifi, |
52 :source, :index_therapeuticus, :ith_swissmedic, :has_fachinfo?, :production_science |
53 sequence_data :atc_class, :basename, :company, :composition_text, :ddds, |
54 :fachinfo, :galenic_forms, :galenic_group, :has_patinfo?, :longevity, |
55 :iksnr, :indication, :name, :name_base, :patinfo, :pdf_patinfo, |
56 :registration, :route_of_administration, :sequence_date |
57 def initialize(ikscd) |
58 super() |
59 @ikscd = sprintf('%03d', ikscd.to_i) |
60 @narcotics = [] |
61 @parts = [] |
62 end |
63 def active? |
64 !@disable && (@preview_with_market_date || @market_date.nil? \ |
65 || @market_date <= @@today) |
66 end |
67 def active_agents |
68 @parts.inject([]) { |acts, part| acts.concat part.active_agents } |
69 end |
70 def add_narcotic(narc) |
71 unless(narc.nil? || @narcotics.include?(narc)) |
72 @narcotics.push(narc) |
73 @narcotics.odba_isolated_store |
74 narc.add_package(self) |
75 end |
76 narc |
77 end |
78 def barcode |
79 if(key = ikskey) |
80 Ean13.new_unchecked('7680'+key).to_s |
81 end |
82 end |
83 def checkout |
84 checkout_helper([@generic_group], :remove_package) |
85 @narcotics.each { |narc| |
86 narc.remove_package(self) |
87 } if @narcotics |
88 @parts.dup.each { |part| |
89 part.checkout |
90 part.odba_delete |
91 } |
92 @parts.odba_delete |
93 if(@sl_entry.respond_to?(:checkout)) |
94 @sl_entry.checkout |
95 @sl_entry.odba_delete |
96 end |
97 end |
98 def commercial_forms |
99 @parts.collect { |part| part.commercial_form } |
100 end |
101 def company_name |
102 (cmp = company) && cmp.name |
103 end |
104 def compositions |
105 @parts.inject([]) { |comps, part| comps.push part.composition }.compact |
106 end |
107 def comparable?(bottom, top, pack) |
108 begin |
109 pack != self \ |
110 && (other = pack.comparable_size) \ |
111 && bottom < other \ |
112 && top > other \ |
113 && !pack.basename.nil? |
114 rescue RuntimeError => e |
115 false |
116 end |
117 end |
118 def comparables |
119 cs = comparable_size |
120 bottom = cs * 0.75 |
121 top = cs * 1.25 |
122 comparables = generic_group_comparables |
123 @sequence.comparables.each { |seq| |
124 comparables.concat seq.public_packages.select { |pack| |
125 comparable?(bottom, top, pack) |
126 } |
127 } |
128 comparables.concat @sequence.public_packages.select { |pack| |
129 comparable?(bottom, top, pack) |
130 } |
131 comparables.uniq |
132 end |
133 def comparable_size |
134 @parts.collect { |part| part.comparable_size }.inject{ |a, b| a + b } or raise RuntimeError |
135 rescue RuntimeError |
136 @parts.inject(Dose.new(0)) { |comp, part| |
137 ODDB::Dose.new(comp.qty + part.comparable_size.qty) |
138 } rescue nil |
139 end |
140 def create_part |
141 part = Part.new |
142 part.package = self |
143 @parts.push part |
144 part |
145 end |
146 def create_sl_entry |
147 @sl_entry = SlEntry.new |
148 end |
149 def ddd |
150 if (atc = atc_class) && atc.has_ddd? |
151 atc.ddds['O'] |
152 end |
153 end |
154 def ddd_price |
155 if(!@disable_ddd_price && (ddd = self.ddd) \ |
156 && (grp = galenic_group) && grp.match(@@ddd_galforms) \ |
157 && (price = price_public) && (ddose = ddd.dose) && (mdose = dose) \ |
158 && size = comparable_size) |
159 factor = (longevity || 1).to_f |
160 if(mdose > (ddose * factor)) |
161 (price / size.to_f) / factor |
162 else |
163 (price / size.to_f) \ |
164 * (ddose.to_f * factor / mdose.want(ddose.unit).to_f) / factor |
165 end |
166 end |
167 rescue RuntimeError |
168 end |
169 def delete_part(oid) |
170 @parts.delete_if { |comp| comp.oid == oid } |
171 end |
172 def delete_sl_entry |
173 @sl_entry = nil |
174 @deductible = nil |
175 @sl_generic_type = nil |
176 reg = @sequence.registration |
177 unless reg.nil? || reg.packages.any? do |pac| pac.sl_entry end |
178 reg.generic_type = nil |
179 reg.odba_isolated_store |
180 end |
181 self.odba_isolated_store |
182 nil |
183 end |
184 def dose |
185 @ddd_dose || (@sequence.dose if @sequence) |
186 end |
187 def fix_pointers |
188 @pointer = @sequence.pointer + [:package, @ikscd] |
189 if(sl = @sl_entry) |
190 sl.pointer = @pointer + [:sl_entry] |
191 sl.odba_store |
192 end |
193 @parts.each { |part| |
194 part.fix_pointers |
195 } |
196 odba_store |
197 end |
198 def generic_group_comparables(filters=[]) |
199 if @generic_group \ |
200 && !((go = data_origins['generic_group']) && filters.include?(go)) |
201 @generic_group.packages - [self] |
202 else |
203 [] |
204 end |
205 end |
206 def good_result?(query) |
207 query = query.to_s.downcase |
208 basename.to_s.downcase[0,query.length] == query |
209 end |
210 def has_generic? |
211 @generic_type == :original && !comparables.empty? |
212 end |
213 def ikscd=(ikscd) |
214 if(/^[0-9]{3}$/u.match(ikscd)) |
215 pacs = @sequence.packages |
216 pacs.delete(@ikscd) |
217 pacs.store(ikscd, self) |
218 pacs.odba_store |
219 @out_of_trade = false |
220 @ikscd = ikscd |
221 fix_pointers |
222 end |
223 end |
224 def localized_name(language) |
225 @sequence.localized_name(language) |
226 end |
227 def ikskey |
228 if(nr = iksnr) |
229 nr + @ikscd |
230 end |
231 end |
232 def limitation |
233 @sl_entry.limitation unless @sl_entry.nil? |
234 end |
235 def limitation_text |
236 @sl_entry.limitation_text unless @sl_entry.nil? |
237 end |
238 def most_precise_dose |
239 @pretty_dose || dose |
240 end |
241 def name_with_size |
242 [name_base, size].join(', ') |
243 end |
244 def narcotic? |
245 @narcotics.any? { |narc| narc.category == 'a' } |
246 end |
247 def part(oid) |
248 @parts.find { |part| part.oid == oid } |
249 end |
250 def pharmacode= pcode |
251 @pharmacode = pcode ? pcode.to_i.to_s : nil |
252 end |
253 def preview? |
254 @preview_with_market_date && @market_date && @market_date > @@today |
255 end |
256 def public? |
257 active? && (@refdata_override || !@out_of_trade \ |
258 || registration.active?) |
259 end |
260 def remove_narcotic(narc) |
261 if(res = @narcotics.delete(narc)) |
262 @narcotics.odba_isolated_store |
263 narc.remove_package(self) |
264 end |
265 res |
266 end |
267 def size |
268 @parts.collect { |part| part.size }.compact.join(' + ') |
269 end |
270 def substances |
271 active_agents.collect { |active| active.substance }.compact |
272 end |
273 def <=>(other) |
274 [self.basename, self.dose.to_f, self.comparable_size.to_f] <=> \ |
275 [other.basename, other.dose.to_f, other.comparable_size.to_f] |
276 end |
277 private |
278 def adjust_types(values, app=nil) |
279 values = values.dup |
280 values.each { |key, value| |
281 case key |
282 when :generic_group |
283 values[key] = value.resolve(app) |
284 when :price_public, :price_exfactory |
285 values[key] = Package.price_internal(value, key) |
286 when :pretty_dose, :ddd_dose |
287 values[key] = if(value.is_a? Dose) |
288 value |
289 elsif(value.is_a?(Array)) |
290 Dose.new(*value) |
291 end |
292 end unless(value.nil?) |
293 } |
294 values |
295 end |
296 end |
297 class Package < PackageCommon |
298 ODBA_SERIALIZABLE = [ '@prices', '@ancestors', '@swissmedic_source' ] |
299 include ODBA::Persistable ## include directly to get odba_index |
300 odba_index :pharmacode |
301 odba_index :name_with_size |
302 attr_accessor :medwin_ikscd, :ancestors |
303 include FeedbackObserver |
304 def initialize(ikscd) |
305 super |
306 @feedbacks = [] |
307 end |
308 def checkout |
309 super |
310 if(@feedbacks) |
311 @feedbacks.dup.each { |fb| fb.item = nil; fb.odba_store } |
312 @feedbacks.odba_delete |
313 end |
314 end |
315 def generic_group=(generic_group) |
316 unless(@generic_group.nil?) |
317 @generic_group.remove_package(self) |
318 end |
319 unless(generic_group.nil?) |
320 generic_group.add_package(self) |
321 end |
322 @generic_group = generic_group |
323 end |
324 def has_price? |
325 prices.any? do |key, values| !values.empty? end |
326 end |
327 def has_price_history? |
328 prices.any? do |key, values| values.size > 1 end |
329 end |
330 def price(type, ord_or_time=0) |
331 candidates = (prices[type] ||= []) |
332 if(ord_or_time.is_a?(Time)) |
333 candidates.find { |price| price.valid_from < ord_or_time } |
334 else |
335 candidates[ord_or_time.to_i] |
336 end |
337 end |
338 def price_exfactory(ord_or_time=0) |
339 price(:exfactory, ord_or_time) |
340 end |
341 def price_exfactory=(price) |
342 return price_exfactory if(price == price_exfactory) |
343 (prices[:exfactory] ||= []).unshift(price) |
344 price |
345 end |
346 def price_public(ord_or_time=0) |
347 price(:public, ord_or_time) |
348 end |
349 def price_public=(price) |
350 return price_public if(price == price_public) |
351 (prices[:public] ||= []).unshift(price) |
352 price |
353 end |
354 def prices |
355 @prices ||= {} |
356 end |
357 end |
358 end |
Generated on Fri Feb 04 07:35:27 +0100 2011 with rcov 0.9.8