From 337200f0ae5253208f9fc3998cd91389aa4ad29f Mon Sep 17 00:00:00 2001 From: Niklaus Giger Date: Wed, 15 Feb 2017 17:15:47 +0100 Subject: [PATCH] Correct display for DDD price --- spec/smoketest_spec.rb | 9 +++ src/model/package.rb | 69 ++++++++++------- src/view/drugs/ddd_price.rb | 32 ++++---- test/stub/oddbapp.rb | 2 +- test/test_model/package.rb | 158 +++++++++++++++++++++++++++----------- test/test_view/drugs/ddd_price.rb | 9 ++- test/test_view/suite.rb | 1 + 7 files changed, 187 insertions(+), 93 deletions(-) mode change 100644 => 100755 src/view/drugs/ddd_price.rb diff --git a/spec/smoketest_spec.rb b/spec/smoketest_spec.rb index 0a5d4e7..90516af 100755 --- a/spec/smoketest_spec.rb +++ b/spec/smoketest_spec.rb @@ -394,6 +394,15 @@ describe "ch.oddb.org" do check_search_with_type end + it 'should display the correct calculation for Bicalutamid Actavis' do + @browser.goto(OddbUrl + '/de/gcc/ddd_price/reg/59111/seq/02/pack/004/search_query/Bicalutamid+Actavis%22/search_type/st_sequence') + tageskosten = @browser.trs.find{|x| /^Tageskosten/.match(x.text)}.text + expect(tageskosten).to match 'Tagesdosis 50 mg' + expect(tageskosten).to match 'Publikumspreis 645.10 CHF' + expect(tageskosten).to match '6.45 CHF / Tag' + expect(tageskosten).to match 'Stärke 150 mg Packungsgrösse 100 Tablette' + expect(tageskosten).to match 'Berechnung xxx' + end after :all do @browser.close end diff --git a/src/model/package.rb b/src/model/package.rb index ce591ae..6b6ed69 100644 --- a/src/model/package.rb +++ b/src/model/package.rb @@ -284,14 +284,19 @@ module ODDB nil end # some constant to simplify testing - SHOW_PRICE_CALCULATION = false + SHOW_PRICE_CALCULATION = true CUM_LIBERATION_REGEXP = /cum Liberatione ([\d\.]+\s*[µm]g\/\d*\s*h)$/i AD_GRANULATUM_REGEXP = /ad Granulatum[^\d]+([\d\.]+\s[mugl]+)$/i def ddd_price + price, calc, variant = ddd_price_calc_variant + return price + end + def ddd_price_calc_variant + variant = -1 + calc = 'no calculation done' if(!@disable_ddd_price && (ddd = self.ddd) \ && (price = price_public) && (ddose = ddd.dose) && (mdose = dose) \ && size = comparable_size) - # return nil if sequence.active_agents.size != 1 _ddd_price = 0.00 factor = (longevity || 1).to_f if sequence.compositions.first @@ -299,7 +304,6 @@ module ODDB else excipiens = nil end - variant = -1 puts "#{pointer} @@ddd_galforms #{@@ddd_galforms} galenic_group #{galenic_group} match #{(grp = galenic_group) && grp.match(@@ddd_galforms)} excipiens #{excipiens}" if SHOW_PRICE_CALCULATION u_mdose = quanty_to_unit(mdose) u_size = quanty_to_unit(size) @@ -310,50 +314,56 @@ module ODDB puts "IKSRN #{iksnr} u_adose (dose of first active agent #{u_adose} != dose of package #{u_mdose}" if SHOW_PRICE_CALCULATION end if catch_ui && u_ddose.compatible?(Unit.new('1 TU')) - variant = 40 if /[\d.-]+ TU/.match(ddose.to_s) + variant = 41 ddd_dose_tu = u_ddose.scalar * 1000 elsif /[\d.-]+ MU/.match(ddose.to_s) + variant = 42 ddd_dose_tu = u_ddose.scalar * 1000 * 1000 # MU = milllion unit elsif /([\d.-])+ U/.match(ddose.to_s) + variant = 43 ddd_dose_tu = u_ddose.scalar else - puts "Unable to match ddose #{ddose.to_s}" - return nil + variant = 44 + calc = "Unable to match ddose #{ddose.to_s}" + puts calc + return nil, calc, 41 end if dose.unit.index('/ml') + variant = variant + 10 measure = Unit.new(parts.first.measure.to_s) pack_dose_u = ((u_mdose.base * measure.base)).scalar else pack_dose_u = catch_ui[1].to_i end - _ddd_price = (price / parts.first.count / parts.first.multi / (pack_dose_u/ ddd_dose_tu)) - puts "_ddd_price #{variant}: #{_ddd_price} = price #{price} / count #{parts.first.count} / multi #{ parts.first.multi} / ( pack_dose_u #{pack_dose_u} /ddd_dose_tu #{ddd_dose_tu})" if SHOW_PRICE_CALCULATION + _ddd_price = price / parts.first.count / parts.first.multi / (pack_dose_u/ ddd_dose_tu) + calc = "#{price} / #{parts.first.count} / #{ parts.first.multi} / ( #{pack_dose_u} / #{ddd_dose_tu})" elsif excipiens && (per_unit = /ad pulverem\s+pro\s*([\d.]+\s*[mg])/i.match(sequence.composition_text)) variant = 32 _ddd_price = (price / ((u_size.base / (u_ddose.base/u_mdose.base))/Unit.new(per_unit[1].to_s).base)) - puts "_ddd_price #{variant}: #{_ddd_price} =price #{price} / u_size #{u_size} /u_ddose (#{u_ddose} /u_mdose #{u_mdose})" if SHOW_PRICE_CALCULATION + calc = "#{price} / ( ( #{u_size} / ( #{u_ddose} / #{u_mdose} / #{Unit.new(per_unit[1].to_s)} ) )" elsif excipiens && /pro compresso$/i.match(excipiens) && sequence.active_agents.size > 1 variant = 30 u_mdose = Unit.new(sequence.active_agents.first.dose.to_s) _ddd_price = price * (u_ddose.base / ((u_mdose * u_size).base )) - puts "_ddd_price #{variant}: #{_ddd_price} =price #{price} / u_size #{u_size} /u_ddose (#{u_ddose} /u_mdose #{u_mdose})" if SHOW_PRICE_CALCULATION + calc = "#{price} x ( #{u_ddose} / ( #{u_mdose} x #{u_size} )" elsif excipiens && /capsula/i.match(excipiens) && u_ddose && u_mdose && u_size - _ddd_price = price * (u_ddose.base / ((u_mdose * u_size).base )) - puts "_ddd_price 0 #{_ddd_price} = #{price} * (#{u_ddose} / #{u_size}" if SHOW_PRICE_CALCULATION + variant = 31 + _ddd_price = price * (u_ddose.base / ((u_mdose * u_size).base )) + calc = "#{price} x ( #{u_ddose} / ( #{u_mdose} x #{u_size} ))" elsif excipiens && (m = CUM_LIBERATION_REGEXP.match(excipiens.downcase)) variant = 10 # we cannot mix units 'h' and 'H', therefore we downcase the excipiens u_mdose = (Unit.new(m[1])*Unit.new('24 h')) # per day u_ddose = Unit.new(ddd_pflaster.dose.to_s) _ddd_price = price / u_size / (u_ddose.base / u_mdose.base ) - puts "_ddd_price #{variant}: #{_ddd_price} =price #{price} / u_size #{u_size} /u_ddose (#{u_ddose} /u_mdose #{u_mdose})" if SHOW_PRICE_CALCULATION + calc = "#{price} / #{u_size} / (#{u_ddose} / #{u_mdose})" elsif excipiens && (m = AD_GRANULATUM_REGEXP.match(excipiens.downcase)) variant = 20 u_mdose = Unit.new(mdose.to_s) u_pro = Unit.new(m[1]) - _ddd_price = price / (u_size.base * u_mdose.base/u_pro.base/ u_ddose.base) - puts "_ddd_price #{variant}: #{_ddd_price} =price #{price} / u_size #{u_size} /u_ddose (#{u_ddose} /u_mdose #{u_mdose})" if SHOW_PRICE_CALCULATION + _ddd_price = price / (u_size.base * (u_mdose.base/u_pro.base)/ u_ddose.base) + calc = "#{price} / #{u_size} x (#{u_mdose.base/u_pro.base} / #{u_ddose})" elsif (grp = galenic_group.to_s) && grp.match(@@ddd_galforms) if (u_mdose && (u_mdose > (u_ddose * factor))) || /retard/i.match(grp) if @parts.size != 1 @@ -361,13 +371,13 @@ module ODDB _ddd_price = nil else variant = 13 - _ddd_price = (price / @parts.first.count) / factor - puts "_ddd_price #{variant}: #{_ddd_price} = #{price} / #{size} / #{factor}" if SHOW_PRICE_CALCULATION + _ddd_price = price / @parts.first.count / factor + calc = "#{price} / #{size} / #{factor}" end else variant = 14 _ddd_price = (price / @parts.first.count) * (ddose.to_f / mdose.want(ddose.unit).to_f) / factor - puts "_ddd_price #{variant}: #{_ddd_price} = #{price} / count #{@parts.first.count} * ( #{ddose} / #{mdose.want(ddose.unit)})" if SHOW_PRICE_CALCULATION + calc = "#{price} / #{@parts.first.count} x ( #{ddose} / #{mdose} ) / #{factor}" end else # This is valid only for the following case, for example, mdose unit: mg/ml, size unit: ml @@ -385,47 +395,54 @@ module ODDB if u_ddose.compatible?((u_mdose * u_size)) variant = 1 _ddd_price = price * (u_ddose.base / ((u_mdose * u_size).base )) + calc = "#{price} x #{u_ddose} / ( #{u_mdose} x #{u_size} )" elsif u_mdose.compatible?(u_ddose) && excipiens && (m = /\d+\s*\S*/.match(excipiens)) exc_dose = quanty_to_unit(m[0].sub('Ml', 'ml')) comparable_unit = quanty_to_unit(comparable_size.to_s) variant = 2 _ddd_price = price / ( (u_mdose/exc_dose).base / (u_ddose/comparable_unit).base) + calc = "#{price} / ( #{u_ddose} / #{exc_dose} / ( #{u_ddose} / #{comparable_size}) )" elsif excipiens && (/Ad\s+Solutionem$/i.match(excipiens)) if u_mdose.compatible?(u_ddose) variant = 33 _ddd_price = (price / (u_mdose.base/u_ddose.base)) - puts "_ddd_price #{variant}: #{_ddd_price} =price #{price} / u_mdose #{u_mdose} /u_ddose (#{u_ddose})" if SHOW_PRICE_CALCULATION + calc = "#{price} / (#{u_mdose} / #{u_ddose})" elsif u_ddose.compatible?((u_mdose * u_size)) variant = 35 _ddd_price = price * (u_ddose.base / ((u_mdose * u_size).base )) - puts "_ddd_price #{variant}: u_mdose #{u_mdose} incompatible with u_ddose #{u_ddose} and u_adose #{u_adose}" if SHOW_PRICE_CALCULATION + calc = "u_mdose #{u_mdose} incompatible with u_ddose #{u_ddose} and u_adose #{u_adose}" elsif u_mdose.compatible?(u_adose) variant = 34 - _ddd_price = (price / (u_mdose.base/u_adose.base)) - puts "_ddd_price #{variant}: #{_ddd_price} =price #{price} / u_mdose #{u_mdose} /u_adose (#{u_adose})" if SHOW_PRICE_CALCULATION + _ddd_price = price / (u_mdose.base/u_adose.base) + calc = "#{price} / ( #{u_mdose} / #{u_adose} )" else variant = 36 - puts "_ddd_price #{variant}: u_mdose #{u_mdose} incompatible with u_ddose #{u_ddose} and u_adose #{u_adose}" if SHOW_PRICE_CALCULATION + calc = "u_mdose #{u_mdose} incompatible with u_ddose #{u_ddose} and u_adose #{u_adose}" _ddd_price = 0 end else variant = 3 _ddd_price = price * (u_ddose.base / ((u_mdose * u_size).base )) + calc = "#{_ddd_price} = #{price} / size #{size} / mdose #{mdose}.to_g).to_f / ddose #{u_ddose})) / #{factor}" end - puts "_ddd_price #{variant} #{_ddd_price} = #{price} / size #{size} / mdose #{mdose}.to_g).to_f / ddose #{u_ddose})) / #{factor}" if SHOW_PRICE_CALCULATION end else variant = 4 - _ddd_price = (price / ((size * mdose).to_f / ddose.to_f)) / factor - puts "_ddd_price #{variant} #{_ddd_price} = #{price} / #{size} * #{mdose}.to_f / #{ddose.to_f})) / #{factor}" if SHOW_PRICE_CALCULATION + _ddd_price = price / ((size * mdose).to_f / ddose.to_f) / factor + calc = "#{price} / #{size} x #{mdose} / #{ddose} / #{factor}" end end _ddd_price = nil if _ddd_price && _ddd_price.amount.to_i > 10000 _ddd_price.to_s.match(/^0\.0*$/u) ? nil : _ddd_price + puts "#{calc}" + return _ddd_price, calc, variant + else + return _ddd_price, "Disabled or invalid", -2 end rescue StandardError, NoMethodError, RuntimeError, ArgumentError => e puts "_ddd_price RuntimeError #{e} #{iksnr} pack #{ikscd} #{name} from \n#{e.backtrace[0..5].join("\n")}" if SHOW_PRICE_CALCULATION _ddd_price = nil + return _ddd_price, e.to_s, variant end def delete_part(oid) @parts.delete_if { |comp| comp.oid == oid } diff --git a/src/view/drugs/ddd_price.rb b/src/view/drugs/ddd_price.rb old mode 100644 new mode 100755 index 1f021d4..5833675 --- a/src/view/drugs/ddd_price.rb +++ b/src/view/drugs/ddd_price.rb @@ -15,17 +15,18 @@ class DDDPriceTable < HtmlGrid::Composite include View::DataFormat include View::AdditionalInformation COMPONENTS = { - [0,0] => :ddd_oral, - [2,0] => :price_public, + [0,0] => :atc_class, + [2,0] => :ddd_oral, + [4,0] => :price_public, [0,1] => :dose, [2,1] => :size, [0,2] => :calculation, } COLSPAN_MAP = { - [1,2] => 3, + [1,2,3] => 3, } CSS_MAP = { - [0,0,4,2] => 'list', + [0,0,6,2] => 'list', [0,2,2] => 'list nowrap' } LABELS = true @@ -39,6 +40,14 @@ class DDDPriceTable < HtmlGrid::Composite comp end end + def atc_class(model) + if (model && (atc = model.atc_class)) + comp = HtmlGrid::Value.new(:atc_class, model.atc_class.code, @session, self) + comp.value = model.atc_class.code + comp + end + end + def dose(model) if(model && (atc = model.atc_class) && (ddd = atc.ddd('O')) && model.dose && ddd.dose) comp = HtmlGrid::Value.new(:dose, model, @session, self) @@ -52,24 +61,13 @@ class DDDPriceTable < HtmlGrid::Composite currency = @session.currency mprice = model.price_public mprice = convert_price(mprice, currency) - dprice = model.ddd_price + dprice, calculation, variant = model.ddd_price_calc_variant dprice = convert_price(dprice, currency) mdose = model.dose ddose = ddd.dose curr = @session.currency comp = HtmlGrid::Value.new(:ddd_calculation, model, @session, self) - if(factor = model.longevity) - comp.value = @lookandfeel.lookup(:ddd_calc_long, factor, mprice, - model.size, dprice, curr) - - elsif(mdose > ddose and model.galenic_group =~ /tabletten?/iu) - comp.value = @lookandfeel.lookup(:ddd_calc_tablet, mprice, - model.size, dprice, curr) - else - comp.value = @lookandfeel.lookup(:ddd_calculation, ddose, - mdose, mprice, model.size, - dprice, curr) - end + comp.value = calculation comp end end diff --git a/test/stub/oddbapp.rb b/test/stub/oddbapp.rb index 3fa203c..9e6d942 100755 --- a/test/stub/oddbapp.rb +++ b/test/stub/oddbapp.rb @@ -22,7 +22,7 @@ class OddbPrevalence end end module ODDB - ODDB_VERSION = 'version' + ODDB_VERSION = 'version' class App < SBSM::DRbServer remove_const :RUN_CLEANER remove_const :RUN_UPDATER diff --git a/test/test_model/package.rb b/test/test_model/package.rb index 7dcaae0..db25f90 100755 --- a/test/test_model/package.rb +++ b/test/test_model/package.rb @@ -132,7 +132,6 @@ class TestPackage ODDB::Dose.new(12, 'Sachet(s)') @package.parts.push part - price = @package.ddd_price + price, calc, variant = @package.ddd_price_calc_variant + assert_equal(price, @package.ddd_price) + assert_equal(4, variant) assert_equal ODDB::Util::Money.new(1.40, 'CHF').to_s, @package.ddd_price.to_s + assert_equal('1.40 / 12 x 250 mg / 3 g / 1.0', calc) end def test_delete_part part = flexmock(:oid => 4) @@ -674,8 +676,11 @@ class TestPackage 'composition_text', :longevity => nil @package.sequence = seq2 - price = @package.ddd_price + price, calc, variant = @package.ddd_price_calc_variant + assert_equal(price, @package.ddd_price) + assert_equal(4, variant) # We just wanted to receive a different price. No real example! assert_equal ODDB::Util::Money.new(17.93, 'CHF').to_s, price ? price.to_s : DDD_PRICE_NIL + assert_equal('18.65 / 8 x 390 µg / 3 mg / 1.0', calc) end def test_cum_liberation allowed_failures = [ @@ -856,11 +869,11 @@ class TestPackage 10TU=11 Fr. assert_equal(ODDB::Util::Money.new(11.00, 'CHF').to_s, (price ? price.to_s : DDD_PRICE_NIL)) + assert_equal('22.00 / 1 / 1 / ( 20000 / 10000)', calc) end def test_ddd_Urokinase_iksnr_46240 create_test_package(iksnr: 46240, ikscd: 66, price_public: 219.15, @@ -1300,8 +1360,11 @@ Solvens: glycerolum, conserv.: metacresolum 3 mg, aqua ad iniectabilia q.s. ad s part.addition = 0 part.measure = nil @package.parts.push part - price = @package.ddd_price + price, calc, variant = @package.ddd_price_calc_variant + assert_equal(price, @package.ddd_price) + assert_equal(42, variant) assert_equal(ODDB::Util::Money.new(1314.90, 'CHF').to_s, (price ? price.to_s : DDD_PRICE_NIL)) + assert_equal('219.15 / 1 / 1 / ( 500000 / 3000000)', calc) end end @@ -1323,8 +1386,11 @@ excipiens pro compresso obducto. part.addition = 0 part.measure = ODDB::Dose.new(30, 'mg') @package.parts.push part - price = @package.ddd_price + price, calc, variant = @package.ddd_price_calc_variant + assert_equal(price, @package.ddd_price) + assert_equal(14, variant) assert_equal(ODDB::Util::Money.new(2.83, 'CHF').to_s, (price ? price.to_s : DDD_PRICE_NIL)) + assert_equal('39.65 / 28 x ( 60 mg / 30 mg ) / 1.0', calc) end # Luveris reg/55430/seq/01 Praeparatio cryodesiccata: lutropinum alfa 3.7 µg, saccharum, dinatrii phosphas dihydricus, natrii dihydrogenophosphas monohydricus, polysorbatum 20, methioninum, nitrogenium, pro vitro. diff --git a/test/test_view/drugs/ddd_price.rb b/test/test_view/drugs/ddd_price.rb index 07cf79c..f11a4bb 100755 --- a/test/test_view/drugs/ddd_price.rb +++ b/test/test_view/drugs/ddd_price.rb @@ -50,12 +50,13 @@ class TestDDDPriceTable 'want' ) @ddd = flexmock('ddd', :dose => dose) - atc_class = flexmock('atc_class', :ddd => @ddd) + atc_class = flexmock('atc_class', :ddd => @ddd, :code => 'atc_code') @model = flexmock('model', :atc_class => atc_class, :dose => dose, :price_public => 'price_public', :ddd_price => 'ddd_price', + :ddd_price_calc_variant => ['ddd_price', 'calculation', 'variant_14'], :longevity => 'longevity', :size => 'size' ) @@ -115,7 +116,7 @@ class TestDDDPriceComposite 'want' ) @ddd = flexmock('ddd', :dose => dose) - atc_class = flexmock('atc_class', :ddd => @ddd) + atc_class = flexmock('atc_class', :ddd => @ddd, :code => 'atc_code') commercial_form = flexmock('commercial_form', :language => 'language') part = flexmock('part', :multi => 'multi', @@ -130,6 +131,7 @@ class TestDDDPriceComposite dose, :price_public => 'price_public', :ddd_price => 'ddd_price', + :ddd_price_calc_variant => ['ddd_price', 'calculation', 'variant_14'], :longevity => 'longevity', :size => 'size', :commercial_forms => ['commercial_form'], @@ -192,7 +194,7 @@ class TestDDDPrice 'want' ) ddd = flexmock('ddd', :dose => dose) - atc_class = flexmock('atc_class', :ddd => ddd) + atc_class = flexmock('atc_class', :ddd => ddd, :code => 'atc_code') commercial_form = flexmock('commercial_form', :language => 'language') part = flexmock('part', :multi => 'multi', @@ -207,6 +209,7 @@ class TestDDDPrice dose, :price_public => 'price_public', :ddd_price => 'ddd_price', + :ddd_price_calc_variant => ['ddd_price', 'calculation', 'variant_14'], :longevity => 'longevity', :size => 'size', :commercial_forms => [commercial_form], diff --git a/test/test_view/suite.rb b/test/test_view/suite.rb index c980aa9..bc5a544 100755 --- a/test/test_view/suite.rb +++ b/test/test_view/suite.rb @@ -8,6 +8,7 @@ run_isolated = ['searchbar.rb', 'navigationfoot.rb', 'drugs/fachinfo.rb', 'drugs/fachinfo_change_logs.rb', + 'drugs/javascript.rb', ] require File.join(File.expand_path(File.dirname(File.dirname(__FILE__))), 'helpers.rb') runner = OddbTestRunner.new(File.dirname(__FILE__), run_isolated) -- 2.10.2