| 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