Looking for a good example for drug with two ROAs and different DDD.
We have
Analysing another reported error for A03AX13 DISFLATYL Tropfen Fl 30 ml, which should have a ddd-price of 2.69 instead of 0.43 as displayed at http://ch.oddb.org/de/gcc/ddd_price/reg/52051/seq/01/pack/010/search_query/A03AX13/search_type/st_sequence with
Tageskosten für Disflatyl Tagesdosis 0.5 g Publikumspreis 6.45 CHF Stärke 40 mg/ml Packungsgrösse 30 ml Berechnung ( 0.5 g / 40 mg/ml ) x ( 6.45 / 30 ml ) = 0.43 CHF / Tag TwitterShare
Galenic form as display by oddb.org is 1 ml enthält 40 mg Simeticon.. Who says at https://www.whocc.no/atc_ddd_index/?code=A03AX13
ATC code Name DDD U Adm.R Note A03AX13 silicones 0.5 g O
Here our calculation is wrong as we should first calculate the package contains in total 30ml*40mg/ml=1200mg silicones. Therefore for a ddd of 0.5 = 500mg the price is 6.45/1200*500=2.69 SFr. Creating a test case. This is quite some work and now I am getting a very different result than on ch.oddb.org, namely
1) Failure: TestPackage#test_ddd_Diflatyl [test/test_model/package.rb:650]: Expected: "2.69" Actual: "215000.00"
After adding part.multi = 1 and part.measure = ODDB::Dose.new('30 ml') for the part my test now fails with
1) Failure: TestPackage#test_ddd_Diflatyl [test/test_model/package.rb:652]: Expected: "2.69" Actual: "0.22"
But it is still different from the 0.43 reported on ch.oddb.org. Adding a prodedure ddd_calulation into package, to show how the prices is calculated. This should replace a good part of the method calculation of src/view/drugs/ddd_price.rb. Look like this is not a good idea, as "calculation" involves lnf.lookup for many variables depending on different strategies.
Also we have two different implementation of calculation in src/view/ajax/ddd_price.rb and src/view/drugs/ddd_price.rb. In the ajax variant their is an additional conversion
wanted = wanted_unit(mdose, ddose) mdose = model.dose.want(wanted) ddose = ddd.dose.want(wanted)
Why?
Adding debug output I see that when displaying I get a debug output of _ddd_price 3 0.43 = 6.45 / 30 ml / 40 mg/ml.to_g).to_f / 0.0005)) / 1.0 wherease in my unit-test I have _ddd_price 3 0.43 = 6.45 / 30 ml / 40 mg/ml.to_g).to_f / 0.0005)) / 1.0, which means that in my unit-test I the expression (grp = galenic_group) && grp.match(ddd_galforms) returns true and not false. The mock for galenic_group therefore is incomplete. After adding the statements part.measure = ODDB::Dose.new('30','ml')@@ and returning false in the group flexmock I can reproduce the error now. As I finally got
TestPackage#test_ddd_Diflatyl [test/test_model/package.rb:658]: Expected: "2.69" Actual: "0.43"
It shows the necessity to add unit test for the other 3 cases in ddd_price!
For Case 4 I have (when visiting http://oddb-ci2.dyndns.org/de/gcc/search/zone/drugs/search_query/NITROGLYCERIN%20Streuli%20Kaukaps/search_type/st_oddb#best_result)
@@ddd_galforms (?i-mx:tabletten?) galenic_group Kaugummi _ddd_price 4 1.54 = 7.40 / 30 * 0.8 mg.to_f / 4.9999999999999996e-06)) / 1.0
This testcase now also returns 0.77 as on ch.oddb.org.
For Case 2 we have the unit test test_ddd_dafalgan_kinder. Now only Case missing is 1. Found another problem. For Aspirin Cardio 100 IKSNR 51795, Seq 01, Pack 68 there is no DDD calculated as we got the following RuntimeError #<RuntimeError: not same unit: tablet != mg>
Looking via bin/admin
ch.oddb> registration('51795').package('068').dose
-> 100 mg
ch.oddb> registration('51795').package('068').parts.size
-> 1
ch.oddb> registration('51795').package('068').atc_class
-> Acetylsalicylsäure
ch.oddb> registration('51795').package('068').atc_class.ddds.keys
-> ["O", "OIndependent of strength"]
ch.oddb> registration('51795').package('068').atc_class.ddds.values.first.dose
-> 1 tablet
ch.oddb> registration('51795').package('068').atc_class.ddds.values.last.dose
-> 1 tablet
ch.oddb> registration('51795').package('068').parts.size
-> 1
ch.oddb> registration('51795').package('068').parts.first
-> #<ODDB::Part:0x007fc72cf4d7d8>
ch.oddb> registration('51795').package('068').parts.first.size
-> 28 Tablette(n)
ch.oddb> registration('51795').package('068').parts.first.multi
-> 1
ch.oddb> registration('51795').package('068').parts.first.measure
->
ch.oddb> registration('51795').package('068').parts.first.measure.class
-> NilClass
ch.oddb> registration('51795').package('068').parts.first.count
-> 28
Here there the package.part.measure is nil where it should be a Kautablette.
Using ruby-units in model/package.rb to be able to rewrite the calculation for Disflatyl as _ddd_price = price / ((mdose * size).base / ddose.base)
Now DISFLATYL and FLATULEX display the correct values. But not "ZOFRAN Sirup 4 mg/5ml 50 ml" with Pharmacode 1800487 as http://oddb-ci2.dyndns.org/de/gcc/ddd_price/reg/53591/seq/01/pack/019/search_query/Zofran/search_type/st_oddb displays:
Tagesdosis 16 mg Publikumspreis 72.65 CHF Stärke 4mg / 5ml Packungsgrösse 50 ml Berechnung ( 16 mg / 4mg / 5ml ) x ( 72.65 / 50 ml ) = 0.0 CHF / Tag
Here the problem is that the galenic_group Lösbar cannot be matched. bin/admin show
ch.oddb> registration('53591').package('019').price_public
-> 72.65
ch.oddb> registration('53591').package('019').galenic_forms.size
-> 1
ch.oddb> registration('53591').package('019').galenic_forms.first
-> Sirup
ch.oddb> registration('53591').package('019').galenic_group
-> Lösbar zur Einnahme
ch.oddb> registration('53591').package('019').galenic_group.route_of_administration
-> roa_O
ch.oddb> registration('53591').package('019').sequence.route_of_administration
-> roa_O
ch.oddb> registration('53591').package('019').atc_class
-> Ondansetron
ch.oddb> registration('53591').package('019').atc_class.ddds.keys
-> ["O", "P", "R"]
ch.oddb> registration('53591').package('019').atc_class.ddds['O']
-> #<ODDB::AtcClass::DDD:0x007fc7283d9518>
ch.oddb> registration('53591').package('019').atc_class.ddds['O'].dose
-> 16 mg
The problem was simpler. ruby-unit does not handle the case of '4 mg / 5 ml', Bug '4 mg/5ml' is okay.
Next problem is with with Emend http://ch.oddb.org/de/gcc/ddd_price/reg/56359/seq/02/pack/002/search_query/EMEND/search_type/st_oddb, where we display a way too high price as it displays
Tagesdosis 95 mg Publikumspreis 103.40 CHF Stärke 125 mg Packungsgrösse 3 Kapsel(n) à 125 mg Berechnung ( 95 mg / 125 mg ) x ( 103.40 / 3 Kapsel(n) à 125 mg ) = 275733.33 CHF / Tag
And here we found the test case for the first case statement in ddd_price. Gathering the needed elements to create a test case
ch.oddb> registration('56359').package('02').atc_class.ddds.keys
-> ["O", "Pexpressed as fosaprepitant", "Pexpressed as fosaprepitant *"]
ch.oddb> registration('56359').package('02').atc_class.ddds['O'].dose
-> 95 mg
ch.oddb> registration('56359').package('02').price_public
-> 103.40
ch.oddb> registration('56359').package('02').dose
-> 125 mg
ch.oddb> registration('56359').package('02').parts.size
-> 1
ch.oddb> registration('56359').package('02').parts.size
-> 1
ch.oddb> registration('56359').package('02').parts.first.size
-> 3 Kapsel(n) à 125 mg
ch.oddb> registration('56359').package('02').parts.first.multi
-> 1
ch.oddb> registration('56359').package('02').parts.first.measure
-> 125 mg
ch.oddb> registration('56359').package('02').parts.first.size
-> 3 Kapsel(n) à 125 mg
ch.oddb> registration('56359').package('02').galenic_forms.first
-> Kapseln
ch.oddb> registration('56359').package('02').galenic_forms.first.galenic_group
-> Tabletten
Ursofalk reg/54634/seq/01/pack/021 is another problem as it has the following composition_text acidum ursodeoxycholicum 250 mg, natrii cyclamas, aromatica, conserv.: E 210, excipiens ad suspensionem pro 5 ml.
I think it is good idea to create now a list of all packages and their ddd_price in order to compare them easily with our list of errors and ensuring that we do not introduce errors.
Added a job/export_ddd_csv. After 14448 items I get the following error
ddd_price Cannot convert '16 mg' to Float unless unitless. Use Unit#scalar 53591 pack 019 from "/var/www/oddb.org/vendor/ruby/2.4.0/gems/ruby-units-2.1.0/lib/ruby_units/unit.rb:1120:in `to_f'", "/var/www/oddb.org/src/model/package.rb:296:in `ddd_price'", "/var/www/oddb.org/vendor/ruby/2.4.0/gems/odba-1.1.2/lib/odba/stub.rb:112:in `method_missing'", "/var/www/oddb.org/src/plugin/csv_export.rb:165:in `block (2 levels) in export_ddd_csv'", "/var/www/oddb.org/src/plugin/csv_export.rb:158:in `each'", "/var/www/oddb.org/src/plugin/csv_export.rb:158:in `block in export_ddd_csv'"]
This should be easy to fix, as it is only in a debug statement. Saving current situation in Attach:fix_ddd_price.txt