de.oddb 2.0.0

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.
Files changed (431) hide show
  1. data/Guide.txt +3 -0
  2. data/History.txt +5 -0
  3. data/LICENCE.txt +339 -0
  4. data/Manifest.txt +430 -0
  5. data/README +423 -0
  6. data/README.txt +25 -0
  7. data/Rakefile +28 -0
  8. data/bin/admin +71 -0
  9. data/bin/exportd +44 -0
  10. data/bin/oddbd +33 -0
  11. data/data/fulltext/data/dicts/french/fulltext.aff +1057 -0
  12. data/data/fulltext/data/dicts/french/fulltext.dict +91189 -0
  13. data/data/fulltext/data/dicts/french/fulltext.stop +135 -0
  14. data/data/fulltext/data/dicts/german/fulltext.aff +1233 -0
  15. data/data/fulltext/data/dicts/german/fulltext.dict +287574 -0
  16. data/data/fulltext/data/dicts/german/fulltext.stop +133 -0
  17. data/data/fulltext/data/german_compound/README +15 -0
  18. data/data/fulltext/data/german_compound/compound.pl +63 -0
  19. data/data/fulltext/data/german_compound/german.stop +20 -0
  20. data/data/fulltext/data/ispell-german-compound.tar.gz +0 -0
  21. data/data/fulltext/redist/dict_french/Makefile +12 -0
  22. data/data/fulltext/redist/dict_french/README.french +1 -0
  23. data/data/fulltext/redist/dict_french/dict_french.sql.in +7 -0
  24. data/data/fulltext/redist/dict_french/dict_snowball.c +56 -0
  25. data/data/fulltext/redist/dict_french/french_stem.c +1222 -0
  26. data/data/fulltext/redist/dict_french/french_stem.h +16 -0
  27. data/data/fulltext/redist/dict_french/subinclude.h +2 -0
  28. data/data/fulltext/redist/dict_german/Makefile +12 -0
  29. data/data/fulltext/redist/dict_german/README.german +1 -0
  30. data/data/fulltext/redist/dict_german/dict_german.sql.in +7 -0
  31. data/data/fulltext/redist/dict_german/dict_snowball.c +56 -0
  32. data/data/fulltext/redist/dict_german/german_stem.c +527 -0
  33. data/data/fulltext/redist/dict_german/german_stem.h +16 -0
  34. data/data/fulltext/redist/dict_german/subinclude.h +1 -0
  35. data/data/fulltext/redist/french_stem.c +1222 -0
  36. data/data/fulltext/redist/french_stem.h +16 -0
  37. data/data/fulltext/redist/german_stem.c +527 -0
  38. data/data/fulltext/redist/german_stem.h +16 -0
  39. data/jobs/export_chde_xls +20 -0
  40. data/jobs/export_csv +20 -0
  41. data/jobs/export_fachinfo_yaml +20 -0
  42. data/jobs/export_patinfo_yaml +20 -0
  43. data/jobs/export_yaml +20 -0
  44. data/jobs/import_dimdi +15 -0
  45. data/jobs/import_gkv +19 -0
  46. data/jobs/import_pharma24 +15 -0
  47. data/jobs/import_pharmnet +30 -0
  48. data/jobs/import_whocc +18 -0
  49. data/lib/fixes/singular.rb +9 -0
  50. data/lib/fixes/yaml.rb +13 -0
  51. data/lib/oddb.rb +13 -0
  52. data/lib/oddb/business/company.rb +18 -0
  53. data/lib/oddb/business/grant_download.rb +27 -0
  54. data/lib/oddb/business/invoice.rb +75 -0
  55. data/lib/oddb/config.rb +112 -0
  56. data/lib/oddb/currency.rb +6 -0
  57. data/lib/oddb/drugs.rb +16 -0
  58. data/lib/oddb/drugs/active_agent.rb +37 -0
  59. data/lib/oddb/drugs/atc.rb +53 -0
  60. data/lib/oddb/drugs/composition.rb +41 -0
  61. data/lib/oddb/drugs/ddd.rb +24 -0
  62. data/lib/oddb/drugs/dose.rb +107 -0
  63. data/lib/oddb/drugs/galenic_form.rb +21 -0
  64. data/lib/oddb/drugs/galenic_group.rb +17 -0
  65. data/lib/oddb/drugs/package.rb +111 -0
  66. data/lib/oddb/drugs/part.rb +55 -0
  67. data/lib/oddb/drugs/product.rb +25 -0
  68. data/lib/oddb/drugs/sequence.rb +68 -0
  69. data/lib/oddb/drugs/substance.rb +31 -0
  70. data/lib/oddb/drugs/substance_group.rb +13 -0
  71. data/lib/oddb/drugs/unit.rb +12 -0
  72. data/lib/oddb/export.rb +4 -0
  73. data/lib/oddb/export/csv.rb +94 -0
  74. data/lib/oddb/export/l10n_sessions.rb +30 -0
  75. data/lib/oddb/export/rss.rb +44 -0
  76. data/lib/oddb/export/server.rb +137 -0
  77. data/lib/oddb/export/xls.rb +127 -0
  78. data/lib/oddb/export/yaml.rb +212 -0
  79. data/lib/oddb/html/state/download.rb +13 -0
  80. data/lib/oddb/html/state/drugs/admin/package.rb +190 -0
  81. data/lib/oddb/html/state/drugs/admin/product.rb +56 -0
  82. data/lib/oddb/html/state/drugs/admin/sequence.rb +253 -0
  83. data/lib/oddb/html/state/drugs/ajax/explain_ddd_price.rb +19 -0
  84. data/lib/oddb/html/state/drugs/ajax/explain_price.rb +19 -0
  85. data/lib/oddb/html/state/drugs/ajax/global.rb +18 -0
  86. data/lib/oddb/html/state/drugs/ajax/package_infos.rb +19 -0
  87. data/lib/oddb/html/state/drugs/ajax/remote_infos.rb +19 -0
  88. data/lib/oddb/html/state/drugs/atc_browser.rb +39 -0
  89. data/lib/oddb/html/state/drugs/atc_guidelines.rb +21 -0
  90. data/lib/oddb/html/state/drugs/compare.rb +52 -0
  91. data/lib/oddb/html/state/drugs/download_export.rb +18 -0
  92. data/lib/oddb/html/state/drugs/downloads.rb +42 -0
  93. data/lib/oddb/html/state/drugs/fachinfo.rb +21 -0
  94. data/lib/oddb/html/state/drugs/feedback.rb +91 -0
  95. data/lib/oddb/html/state/drugs/global.rb +270 -0
  96. data/lib/oddb/html/state/drugs/init.rb +18 -0
  97. data/lib/oddb/html/state/drugs/login.rb +17 -0
  98. data/lib/oddb/html/state/drugs/package.rb +32 -0
  99. data/lib/oddb/html/state/drugs/patinfo.rb +21 -0
  100. data/lib/oddb/html/state/drugs/products.rb +51 -0
  101. data/lib/oddb/html/state/drugs/result.rb +125 -0
  102. data/lib/oddb/html/state/global.rb +206 -0
  103. data/lib/oddb/html/state/global_predefine.rb +17 -0
  104. data/lib/oddb/html/state/limit.rb +17 -0
  105. data/lib/oddb/html/state/login.rb +56 -0
  106. data/lib/oddb/html/state/paypal/checkout.rb +97 -0
  107. data/lib/oddb/html/state/paypal/collect.rb +19 -0
  108. data/lib/oddb/html/state/paypal/download.rb +61 -0
  109. data/lib/oddb/html/state/paypal/redirect.rb +18 -0
  110. data/lib/oddb/html/state/register_download.rb +24 -0
  111. data/lib/oddb/html/state/register_export.rb +38 -0
  112. data/lib/oddb/html/state/register_poweruser.rb +17 -0
  113. data/lib/oddb/html/state/viral/admin.rb +79 -0
  114. data/lib/oddb/html/state/viral/poweruser.rb +16 -0
  115. data/lib/oddb/html/util/annotated_list.rb +39 -0
  116. data/lib/oddb/html/util/know_it_all.rb +28 -0
  117. data/lib/oddb/html/util/known_user.rb +55 -0
  118. data/lib/oddb/html/util/lookandfeel.rb +698 -0
  119. data/lib/oddb/html/util/need_all_input.rb +29 -0
  120. data/lib/oddb/html/util/session.rb +84 -0
  121. data/lib/oddb/html/util/sort.rb +72 -0
  122. data/lib/oddb/html/util/unsaved_helper.rb +20 -0
  123. data/lib/oddb/html/util/validator.rb +59 -0
  124. data/lib/oddb/html/view/ajax/json.rb +22 -0
  125. data/lib/oddb/html/view/alpha_header.rb +28 -0
  126. data/lib/oddb/html/view/document.rb +117 -0
  127. data/lib/oddb/html/view/download.rb +33 -0
  128. data/lib/oddb/html/view/drugs/admin/package.rb +245 -0
  129. data/lib/oddb/html/view/drugs/admin/product.rb +104 -0
  130. data/lib/oddb/html/view/drugs/admin/sequence.rb +305 -0
  131. data/lib/oddb/html/view/drugs/ajax/explain_ddd_price.rb +87 -0
  132. data/lib/oddb/html/view/drugs/ajax/explain_price.rb +61 -0
  133. data/lib/oddb/html/view/drugs/ajax/package_infos.rb +105 -0
  134. data/lib/oddb/html/view/drugs/ajax/remote_infos.rb +44 -0
  135. data/lib/oddb/html/view/drugs/atc_browser.rb +68 -0
  136. data/lib/oddb/html/view/drugs/atc_guidelines.rb +94 -0
  137. data/lib/oddb/html/view/drugs/compare.rb +95 -0
  138. data/lib/oddb/html/view/drugs/download_export.rb +28 -0
  139. data/lib/oddb/html/view/drugs/downloads.rb +128 -0
  140. data/lib/oddb/html/view/drugs/fachinfo.rb +46 -0
  141. data/lib/oddb/html/view/drugs/feedback.rb +235 -0
  142. data/lib/oddb/html/view/drugs/init.rb +51 -0
  143. data/lib/oddb/html/view/drugs/legend.rb +24 -0
  144. data/lib/oddb/html/view/drugs/package.rb +403 -0
  145. data/lib/oddb/html/view/drugs/patinfo.rb +46 -0
  146. data/lib/oddb/html/view/drugs/products.rb +97 -0
  147. data/lib/oddb/html/view/drugs/result.rb +296 -0
  148. data/lib/oddb/html/view/drugs/search.rb +33 -0
  149. data/lib/oddb/html/view/drugs/template.rb +15 -0
  150. data/lib/oddb/html/view/foot.rb +52 -0
  151. data/lib/oddb/html/view/google.rb +23 -0
  152. data/lib/oddb/html/view/google_ads.rb +40 -0
  153. data/lib/oddb/html/view/head.rb +78 -0
  154. data/lib/oddb/html/view/limit.rb +109 -0
  155. data/lib/oddb/html/view/list.rb +59 -0
  156. data/lib/oddb/html/view/login.rb +38 -0
  157. data/lib/oddb/html/view/navigation.rb +67 -0
  158. data/lib/oddb/html/view/offset_header.rb +35 -0
  159. data/lib/oddb/html/view/paypal/collect.rb +95 -0
  160. data/lib/oddb/html/view/paypal/redirect.rb +51 -0
  161. data/lib/oddb/html/view/paypal/register_form.rb +149 -0
  162. data/lib/oddb/html/view/register_download.rb +29 -0
  163. data/lib/oddb/html/view/register_export.rb +29 -0
  164. data/lib/oddb/html/view/register_poweruser.rb +29 -0
  165. data/lib/oddb/html/view/rss/feedback.rb +64 -0
  166. data/lib/oddb/html/view/rss_preview.rb +61 -0
  167. data/lib/oddb/html/view/search.rb +104 -0
  168. data/lib/oddb/html/view/snapback.rb +24 -0
  169. data/lib/oddb/html/view/template.rb +56 -0
  170. data/lib/oddb/import/dimdi.rb +583 -0
  171. data/lib/oddb/import/excel.rb +45 -0
  172. data/lib/oddb/import/gkv.rb +463 -0
  173. data/lib/oddb/import/importer.rb +36 -0
  174. data/lib/oddb/import/pharma24.rb +211 -0
  175. data/lib/oddb/import/pharmnet.rb +1186 -0
  176. data/lib/oddb/import/rtf.rb +409 -0
  177. data/lib/oddb/import/whocc.rb +148 -0
  178. data/lib/oddb/import/xml.rb +15 -0
  179. data/lib/oddb/model.rb +179 -0
  180. data/lib/oddb/persistence.rb +22 -0
  181. data/lib/oddb/persistence/odba.rb +32 -0
  182. data/lib/oddb/persistence/odba/business/company.rb +13 -0
  183. data/lib/oddb/persistence/odba/business/grant_download.rb +14 -0
  184. data/lib/oddb/persistence/odba/business/invoice.rb +15 -0
  185. data/lib/oddb/persistence/odba/drugs/atc.rb +15 -0
  186. data/lib/oddb/persistence/odba/drugs/galenic_form.rb +18 -0
  187. data/lib/oddb/persistence/odba/drugs/galenic_group.rb +13 -0
  188. data/lib/oddb/persistence/odba/drugs/package.rb +25 -0
  189. data/lib/oddb/persistence/odba/drugs/product.rb +13 -0
  190. data/lib/oddb/persistence/odba/drugs/sequence.rb +21 -0
  191. data/lib/oddb/persistence/odba/drugs/substance.rb +21 -0
  192. data/lib/oddb/persistence/odba/drugs/substance_group.rb +13 -0
  193. data/lib/oddb/persistence/odba/drugs/unit.rb +13 -0
  194. data/lib/oddb/persistence/odba/export.rb +26 -0
  195. data/lib/oddb/persistence/odba/model.rb +68 -0
  196. data/lib/oddb/persistence/odba/text/document.rb +11 -0
  197. data/lib/oddb/persistence/odba/util/code.rb +11 -0
  198. data/lib/oddb/persistence/odba/util/m10l_document.rb +13 -0
  199. data/lib/oddb/persistence/og.rb +16 -0
  200. data/lib/oddb/persistence/og/drugs/composition.rb +14 -0
  201. data/lib/oddb/persistence/og/drugs/product.rb +14 -0
  202. data/lib/oddb/persistence/og/drugs/sequence.rb +15 -0
  203. data/lib/oddb/persistence/og/model.rb +25 -0
  204. data/lib/oddb/persistence/og/util/multilingual.rb +13 -0
  205. data/lib/oddb/redist/rtf_tools/reader.rb +139 -0
  206. data/lib/oddb/remote/business/company.rb +17 -0
  207. data/lib/oddb/remote/drugs/active_agent.rb +27 -0
  208. data/lib/oddb/remote/drugs/atc.rb +31 -0
  209. data/lib/oddb/remote/drugs/dose.rb +8 -0
  210. data/lib/oddb/remote/drugs/galenic_form.rb +24 -0
  211. data/lib/oddb/remote/drugs/package.rb +128 -0
  212. data/lib/oddb/remote/drugs/part.rb +30 -0
  213. data/lib/oddb/remote/drugs/substance.rb +20 -0
  214. data/lib/oddb/remote/drugs/unit.rb +20 -0
  215. data/lib/oddb/remote/object.rb +36 -0
  216. data/lib/oddb/text/chapter.rb +23 -0
  217. data/lib/oddb/text/document.rb +42 -0
  218. data/lib/oddb/text/format.rb +37 -0
  219. data/lib/oddb/text/paragraph.rb +53 -0
  220. data/lib/oddb/text/picture.rb +89 -0
  221. data/lib/oddb/text/table.rb +68 -0
  222. data/lib/oddb/util.rb +9 -0
  223. data/lib/oddb/util/annotated_list.rb +37 -0
  224. data/lib/oddb/util/code.rb +69 -0
  225. data/lib/oddb/util/comparison.rb +36 -0
  226. data/lib/oddb/util/download.rb +17 -0
  227. data/lib/oddb/util/exporter.rb +8 -0
  228. data/lib/oddb/util/feedback.rb +23 -0
  229. data/lib/oddb/util/ipn.rb +53 -0
  230. data/lib/oddb/util/job.rb +23 -0
  231. data/lib/oddb/util/logger.rb +20 -0
  232. data/lib/oddb/util/m10l_document.rb +41 -0
  233. data/lib/oddb/util/mail.rb +87 -0
  234. data/lib/oddb/util/money.rb +64 -0
  235. data/lib/oddb/util/multilingual.rb +70 -0
  236. data/lib/oddb/util/quanty.rb +3 -0
  237. data/lib/oddb/util/quanty/fact.rb +242 -0
  238. data/lib/oddb/util/quanty/main.rb +164 -0
  239. data/lib/oddb/util/quanty/parse.rb +872 -0
  240. data/lib/oddb/util/quanty/units.dump +0 -0
  241. data/lib/oddb/util/server.rb +150 -0
  242. data/lib/oddb/util/smtp_tls.rb +58 -0
  243. data/lib/oddb/util/updater.rb +161 -0
  244. data/lib/oddb/util/ydim.rb +110 -0
  245. data/lib/oddb/util/yus.rb +46 -0
  246. data/test/business/test_company.rb +29 -0
  247. data/test/business/test_grant_download.rb +29 -0
  248. data/test/drugs/test_active_agent.rb +53 -0
  249. data/test/drugs/test_atc.rb +54 -0
  250. data/test/drugs/test_composition.rb +88 -0
  251. data/test/drugs/test_ddd.rb +22 -0
  252. data/test/drugs/test_dose.rb +189 -0
  253. data/test/drugs/test_galenic_form.rb +41 -0
  254. data/test/drugs/test_package.rb +172 -0
  255. data/test/drugs/test_part.rb +32 -0
  256. data/test/drugs/test_product.rb +31 -0
  257. data/test/drugs/test_sequence.rb +140 -0
  258. data/test/drugs/test_substance.rb +51 -0
  259. data/test/drugs/test_substance_group.rb +27 -0
  260. data/test/export/test_rss.rb +86 -0
  261. data/test/export/test_server.rb +163 -0
  262. data/test/export/test_xls.rb +146 -0
  263. data/test/export/test_yaml.rb +120 -0
  264. data/test/import/data/csv/products.csv +11 -0
  265. data/test/import/data/html/dimdi_index.html +400 -0
  266. data/test/import/data/html/gkv/Befreiungsliste_Arzneimittel_Versicherte.gkvnet +508 -0
  267. data/test/import/data/html/pharma24/1337397.html +754 -0
  268. data/test/import/data/html/pharma24/842756.html +570 -0
  269. data/test/import/data/html/pharma24/ac-page-10.html +2999 -0
  270. data/test/import/data/html/pharma24/ac-page-11.html +2999 -0
  271. data/test/import/data/html/pharma24/ac-page-12.html +2999 -0
  272. data/test/import/data/html/pharma24/ac-page-13.html +2999 -0
  273. data/test/import/data/html/pharma24/ac-page-14.html +2999 -0
  274. data/test/import/data/html/pharma24/ac-page-15.html +3011 -0
  275. data/test/import/data/html/pharma24/ac-page-16.html +3050 -0
  276. data/test/import/data/html/pharma24/ac-page-17.html +3285 -0
  277. data/test/import/data/html/pharma24/ac-page-18.html +3109 -0
  278. data/test/import/data/html/pharma24/ac-page-19.html +3126 -0
  279. data/test/import/data/html/pharma24/ac-page-2.html +3005 -0
  280. data/test/import/data/html/pharma24/ac-page-20.html +3007 -0
  281. data/test/import/data/html/pharma24/ac-page-21.html +2999 -0
  282. data/test/import/data/html/pharma24/ac-page-22.html +2999 -0
  283. data/test/import/data/html/pharma24/ac-page-23.html +3055 -0
  284. data/test/import/data/html/pharma24/ac-page-24.html +2999 -0
  285. data/test/import/data/html/pharma24/ac-page-25.html +3004 -0
  286. data/test/import/data/html/pharma24/ac-page-26.html +2999 -0
  287. data/test/import/data/html/pharma24/ac-page-27.html +3167 -0
  288. data/test/import/data/html/pharma24/ac-page-28.html +3236 -0
  289. data/test/import/data/html/pharma24/ac-page-29.html +3110 -0
  290. data/test/import/data/html/pharma24/ac-page-3.html +2999 -0
  291. data/test/import/data/html/pharma24/ac-page-30.html +2999 -0
  292. data/test/import/data/html/pharma24/ac-page-31.html +2999 -0
  293. data/test/import/data/html/pharma24/ac-page-32.html +2999 -0
  294. data/test/import/data/html/pharma24/ac-page-33.html +3001 -0
  295. data/test/import/data/html/pharma24/ac-page-34.html +2999 -0
  296. data/test/import/data/html/pharma24/ac-page-35.html +2999 -0
  297. data/test/import/data/html/pharma24/ac-page-36.html +2999 -0
  298. data/test/import/data/html/pharma24/ac-page-37.html +2999 -0
  299. data/test/import/data/html/pharma24/ac-page-38.html +3003 -0
  300. data/test/import/data/html/pharma24/ac-page-39.html +2999 -0
  301. data/test/import/data/html/pharma24/ac-page-4.html +2999 -0
  302. data/test/import/data/html/pharma24/ac-page-40.html +2999 -0
  303. data/test/import/data/html/pharma24/ac-page-41.html +2999 -0
  304. data/test/import/data/html/pharma24/ac-page-42.html +2999 -0
  305. data/test/import/data/html/pharma24/ac-page-43.html +2999 -0
  306. data/test/import/data/html/pharma24/ac-page-44.html +2999 -0
  307. data/test/import/data/html/pharma24/ac-page-45.html +2999 -0
  308. data/test/import/data/html/pharma24/ac-page-46.html +2999 -0
  309. data/test/import/data/html/pharma24/ac-page-47.html +2999 -0
  310. data/test/import/data/html/pharma24/ac-page-48.html +2999 -0
  311. data/test/import/data/html/pharma24/ac-page-49.html +2999 -0
  312. data/test/import/data/html/pharma24/ac-page-5.html +3168 -0
  313. data/test/import/data/html/pharma24/ac-page-50.html +2999 -0
  314. data/test/import/data/html/pharma24/ac-page-51.html +2999 -0
  315. data/test/import/data/html/pharma24/ac-page-52.html +3003 -0
  316. data/test/import/data/html/pharma24/ac-page-53.html +2999 -0
  317. data/test/import/data/html/pharma24/ac-page-54.html +3095 -0
  318. data/test/import/data/html/pharma24/ac-page-55.html +3041 -0
  319. data/test/import/data/html/pharma24/ac-page-56.html +2999 -0
  320. data/test/import/data/html/pharma24/ac-page-57.html +3001 -0
  321. data/test/import/data/html/pharma24/ac-page-58.html +3001 -0
  322. data/test/import/data/html/pharma24/ac-page-59.html +2999 -0
  323. data/test/import/data/html/pharma24/ac-page-6.html +3072 -0
  324. data/test/import/data/html/pharma24/ac-page-60.html +3001 -0
  325. data/test/import/data/html/pharma24/ac-page-61.html +3005 -0
  326. data/test/import/data/html/pharma24/ac-page-62.html +2999 -0
  327. data/test/import/data/html/pharma24/ac-page-63.html +3007 -0
  328. data/test/import/data/html/pharma24/ac-page-64.html +3007 -0
  329. data/test/import/data/html/pharma24/ac-page-65.html +2999 -0
  330. data/test/import/data/html/pharma24/ac-page-66.html +3011 -0
  331. data/test/import/data/html/pharma24/ac-page-67.html +3026 -0
  332. data/test/import/data/html/pharma24/ac-page-68.html +2999 -0
  333. data/test/import/data/html/pharma24/ac-page-69.html +3010 -0
  334. data/test/import/data/html/pharma24/ac-page-7.html +2999 -0
  335. data/test/import/data/html/pharma24/ac-page-70.html +3192 -0
  336. data/test/import/data/html/pharma24/ac-page-71.html +3133 -0
  337. data/test/import/data/html/pharma24/ac-page-72.html +2999 -0
  338. data/test/import/data/html/pharma24/ac-page-73.html +3227 -0
  339. data/test/import/data/html/pharma24/ac-page-74.html +3241 -0
  340. data/test/import/data/html/pharma24/ac-page-75.html +3227 -0
  341. data/test/import/data/html/pharma24/ac-page-76.html +3244 -0
  342. data/test/import/data/html/pharma24/ac-page-77.html +1164 -0
  343. data/test/import/data/html/pharma24/ac-page-8.html +2999 -0
  344. data/test/import/data/html/pharma24/ac-page-9.html +2999 -0
  345. data/test/import/data/html/pharma24/ac.html +2999 -0
  346. data/test/import/data/html/pharmnet/display.html +662 -0
  347. data/test/import/data/html/pharmnet/display1.html +625 -0
  348. data/test/import/data/html/pharmnet/display2.html +625 -0
  349. data/test/import/data/html/pharmnet/display3.html +625 -0
  350. data/test/import/data/html/pharmnet/display_tramal.html +634 -0
  351. data/test/import/data/html/pharmnet/empty_result.html +395 -0
  352. data/test/import/data/html/pharmnet/gate.html +246 -0
  353. data/test/import/data/html/pharmnet/index.html +258 -0
  354. data/test/import/data/html/pharmnet/paged_result_1.html +401 -0
  355. data/test/import/data/html/pharmnet/paged_result_2.html +401 -0
  356. data/test/import/data/html/pharmnet/result.html +401 -0
  357. data/test/import/data/html/pharmnet/search.html +865 -0
  358. data/test/import/data/html/pharmnet/search_filtered.html +182 -0
  359. data/test/import/data/html/whocc/A.html +56 -0
  360. data/test/import/data/html/whocc/A03.html +48 -0
  361. data/test/import/data/html/whocc/A03AB.html +48 -0
  362. data/test/import/data/html/whocc/A06AA.html +47 -0
  363. data/test/import/data/html/whocc/C03.html +47 -0
  364. data/test/import/data/html/whocc/login.html +77 -0
  365. data/test/import/data/mail/csv.mail +81 -0
  366. data/test/import/data/rtf/pharmnet/aarane.pi.rtf +648 -0
  367. data/test/import/data/rtf/pharmnet/ace_hemmer_ratio.pi.rtf +324 -0
  368. data/test/import/data/rtf/pharmnet/ace_hemmer_ratio.rtf +4816 -0
  369. data/test/import/data/rtf/pharmnet/acemetacin.pi.rtf +388 -0
  370. data/test/import/data/rtf/pharmnet/acemit.pi.rtf +240 -0
  371. data/test/import/data/rtf/pharmnet/acerbon.pi.rtf +1257 -0
  372. data/test/import/data/rtf/pharmnet/acetylcystein.pi.rtf +323 -0
  373. data/test/import/data/rtf/pharmnet/aciclo.pi.rtf +287 -0
  374. data/test/import/data/rtf/pharmnet/aciclovir.pi.rtf +236 -0
  375. data/test/import/data/rtf/pharmnet/actrapid.pi.rtf +322 -0
  376. data/test/import/data/rtf/pharmnet/amlodipin.pi.rtf +452 -0
  377. data/test/import/data/rtf/pharmnet/amlodipin.rtf +473 -0
  378. data/test/import/data/rtf/pharmnet/aspirin.pi.rtf +313 -0
  379. data/test/import/data/rtf/pharmnet/aspirin.rtf +781 -0
  380. data/test/import/data/rtf/pharmnet/baymycard.pi.rtf +447 -0
  381. data/test/import/data/rtf/pharmnet/omeprazol.pi.rtf +510 -0
  382. data/test/import/data/rtf/pharmnet/omeprazol.rtf +9216 -0
  383. data/test/import/data/rtf/pharmnet/paroxetin.pi.rtf +678 -0
  384. data/test/import/data/rtf/pharmnet/selegilin.pi.rtf +312 -0
  385. data/test/import/data/rtf/pharmnet/selegilin.rtf +683 -0
  386. data/test/import/data/rtf/pharmnet/valium.pi.rtf +387 -0
  387. data/test/import/data/txt/gkv/gkv_p1.txt +17 -0
  388. data/test/import/data/xls/darform_010706.xls +0 -0
  389. data/test/import/data/xls/fb010706.xls +0 -0
  390. data/test/import/data/xls/liste_zuzahlungsbefreite_arzneimittel_suchfunktion.xls +0 -0
  391. data/test/import/data/xls/wirkkurz_010406.xls +0 -0
  392. data/test/import/data/xml/ATC_2006.xml +47 -0
  393. data/test/import/data/xml/ATC_2006_ddd.xml +35 -0
  394. data/test/import/test_dimdi.rb +323 -0
  395. data/test/import/test_excel.rb +31 -0
  396. data/test/import/test_gkv.rb +260 -0
  397. data/test/import/test_pharma24.rb +112 -0
  398. data/test/import/test_pharmnet.rb +980 -0
  399. data/test/import/test_rtf.rb +37 -0
  400. data/test/import/test_whocc.rb +314 -0
  401. data/test/remote/drugs/test_active_agent.rb +36 -0
  402. data/test/selenium/selenium-server.jar +0 -0
  403. data/test/selenium/test_atc_browser.rb +121 -0
  404. data/test/selenium/test_atc_guidelines.rb +95 -0
  405. data/test/selenium/test_collect.rb +137 -0
  406. data/test/selenium/test_compare.rb +294 -0
  407. data/test/selenium/test_fachinfo.rb +128 -0
  408. data/test/selenium/test_feedback.rb +192 -0
  409. data/test/selenium/test_init.rb +64 -0
  410. data/test/selenium/test_limit.rb +304 -0
  411. data/test/selenium/test_login.rb +67 -0
  412. data/test/selenium/test_package.rb +516 -0
  413. data/test/selenium/test_patinfo.rb +128 -0
  414. data/test/selenium/test_product.rb +80 -0
  415. data/test/selenium/test_products.rb +141 -0
  416. data/test/selenium/test_search.rb +933 -0
  417. data/test/selenium/test_sequence.rb +513 -0
  418. data/test/selenium/unit.rb +190 -0
  419. data/test/stub/http_server.rb +144 -0
  420. data/test/stub/model.rb +173 -0
  421. data/test/suite.rb +15 -0
  422. data/test/test_model.rb +83 -0
  423. data/test/util/test_code.rb +74 -0
  424. data/test/util/test_ipn.rb +117 -0
  425. data/test/util/test_mail.rb +85 -0
  426. data/test/util/test_multilingual.rb +97 -0
  427. data/test/util/test_server.rb +94 -0
  428. data/test/util/test_updater.rb +130 -0
  429. data/test/util/test_ydim.rb +115 -0
  430. data/test/util/test_yus.rb +79 -0
  431. metadata +568 -0
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::RssPreview -- de.oddb.org -- 12.12.2007 -- hwyss@ywesee.com
3
+
4
+ require 'htmlgrid/divcomposite'
5
+ require 'htmlgrid/divlist'
6
+ require 'oddb/html/view/drugs/package'
7
+
8
+ module ODDB
9
+ module Html
10
+ module View
11
+ class RssPreview < HtmlGrid::DivComposite
12
+ CSS_MAP = ['heading']
13
+ def rss_image(model)
14
+ if(link = title(model))
15
+ img = HtmlGrid::Image.new(:rss_img, model, @session, self)
16
+ img.attributes['src'] = @lookandfeel.resource_global(:rss_img)
17
+ link.value = img
18
+ link
19
+ end
20
+ end
21
+ end
22
+ class RssFeedbackList < HtmlGrid::DivList
23
+ include Drugs::PackageMethods
24
+ COMPONENTS = {
25
+ [0,0] => :heading,
26
+ }
27
+ def heading(model)
28
+ if(parent = model.item)
29
+ link = HtmlGrid::Link.new(:feedback, model, @session, self)
30
+ if code = parent.code(:cid)
31
+ link.href = @lookandfeel._event_url(:feedback, :pzn => parent.code(:cid))
32
+ link.value = @lookandfeel.lookup :feedback_preview,
33
+ parent.name.send(@session.language),
34
+ size(parent)
35
+ else
36
+ link.href = @lookandfeel._event_url(:feedback, :uid => parent.uid)
37
+ link.value = parent.name.send(@session.language)
38
+ end
39
+ link
40
+ end
41
+ end
42
+ end
43
+ class RssFeedbacks < RssPreview
44
+ COMPONENTS = {
45
+ [0,0] => :rss_image,
46
+ [1,0] => :title,
47
+ [0,1] => RssFeedbackList,
48
+ }
49
+ def title(model)
50
+ if(feedback = model.first)
51
+ link = HtmlGrid::Link.new(:feedback_feed_title, model, @session, self)
52
+ link.href = url = [ 'http:/', @session.server_name, 'rss',
53
+ @session.language, "feedback.rss" ].join('/')
54
+ link.css_class = 'rss-title'
55
+ link
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Search -- de.oddb.org -- 07.11.2006 -- hwyss@ywesee.com
3
+
4
+ require 'htmlgrid/divform'
5
+ require 'htmlgrid/reset'
6
+ require 'htmlgrid/select'
7
+
8
+ module ODDB
9
+ module Html
10
+ module View
11
+ module SearchMethods
12
+ def dstype(model)
13
+ select = HtmlGrid::Select.new(:dstype, model, @session, self)
14
+ select.set_attribute('onChange', 'this.form.onsubmit();')
15
+ select.selected = @session.persistent_user_input(:dstype)
16
+ select
17
+ end
18
+ end
19
+ class SearchBar < HtmlGrid::InputText
20
+ def init
21
+ super
22
+ self.onload = "document.getElementById('searchbar').focus();"
23
+ val = @lookandfeel.lookup(:query_info)
24
+ txt_val = @session.persistent_user_input(@name) || val
25
+ @attributes.store('value', txt_val)
26
+ @attributes.update({
27
+ 'onFocus' => "if (value=='#{val}') { value='' };",
28
+ 'onBlur' => "if (value=='') { value='#{val}' };",
29
+ 'id' => "searchbar",
30
+ })
31
+ args = [@name, '']
32
+ submit = @lookandfeel._event_url(@container.event, args)
33
+ script = "if(#{@name}.value!='#{val}'){"
34
+ script << "var href = '#{submit}'"
35
+ script << "+encodeURIComponent(#{@name}.value.replace(/\\//, '%2F'));"
36
+ script << "if(this.dstype)"
37
+ script << "href += '/dstype/' + this.dstype.value;"
38
+ #script << "href += '#best_result';"
39
+ script << "document.location.href=href; } return false"
40
+ self.onsubmit = script
41
+ end
42
+ end
43
+ class Search < HtmlGrid::DivForm
44
+ include SearchMethods
45
+ EVENT = :search
46
+ FORM_NAME = 'search'
47
+ COMPONENTS = {
48
+ [0,0] => 'dstype',
49
+ [0,1] => :dstype,
50
+ [0,2] => :query,
51
+ [0,3] => :submit,
52
+ [1,3] => :reset,
53
+ [0,4] => "explain_search",
54
+ [0,5] => :social_bookmarks,
55
+ [0,6] => :screencast,
56
+ }
57
+ SYMBOL_MAP = {
58
+ :query => SearchBar,
59
+ :reset => HtmlGrid::Reset,
60
+ }
61
+ CSS_MAP = {4 => "explain", 6 => "explain"}
62
+ SOCIAL_BOOKMARKS = [
63
+ [ :sb_delicious, "http://del.icio.us/post?url=%s&title=%s" ],
64
+ [ :sb_stumble, "http://www.stumbleupon.com/submit?url=%s&title=%s" ],
65
+ [ :sb_digg, "http://digg.com/submit?phase=2&url=%stitle=%s" ],
66
+ [ :sb_simpy,
67
+ "http://www.simpy.com/simpy/LinkAdd.do?href=%s&note=%s"],
68
+ ]
69
+ def screencast(model)
70
+ if @lookandfeel.enabled?(:screencast)
71
+ link = HtmlGrid::Link.new(:screencast, model, @session, self)
72
+ link.href = @lookandfeel.lookup(:screencast_url)
73
+ link
74
+ end
75
+ end
76
+ def social_bookmarks(model)
77
+ return unless @lookandfeel.enabled?(:social_bookmarks)
78
+ url = @lookandfeel.base_url
79
+ title = escape(@lookandfeel.lookup(:explain_search))
80
+ SOCIAL_BOOKMARKS.collect { |key, fmt|
81
+ span = HtmlGrid::Span.new(model, @session, self)
82
+ link = HtmlGrid::Link.new(key, model, @session, self)
83
+ link.href = sprintf(fmt, url, title)
84
+ span.css_class = 'social'
85
+ span.css_id = key.to_s[3..-1]
86
+ span.value = link
87
+ span
88
+ }
89
+ end
90
+ end
91
+ class InlineSearch < HtmlGrid::DivForm
92
+ include SearchMethods
93
+ EVENT = :search
94
+ COMPONENTS = {
95
+ [0,0] => :query,
96
+ [1,0] => :dstype,
97
+ }
98
+ SYMBOL_MAP = {
99
+ :query => SearchBar,
100
+ }
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Composite -- de.oddb.org -- 14.02.2007 -- hwyss@ywesee.com
3
+
4
+ require 'htmlgrid/divcomposite'
5
+
6
+ module ODDB
7
+ module Html
8
+ module View
9
+ module Snapback
10
+ def snapback(model)
11
+ if(query = @session.persistent_user_input(:query))
12
+ link = HtmlGrid::Link.new(:result, model, @session, self)
13
+ link.href = @lookandfeel._event_url(:search, [ :query, query ])
14
+ link
15
+ else
16
+ link = HtmlGrid::Link.new(:home, model, @session, self)
17
+ link.href = @lookandfeel._event_url(:home)
18
+ link
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Template -- de.oddb.org -- 27.10.2006 -- hwyss@ywesee.com
3
+
4
+ require 'htmlgrid/divtemplate'
5
+ require 'htmlgrid/dojotoolkit'
6
+ require 'sbsm/time'
7
+ require 'oddb/html/view/foot'
8
+ require 'oddb/html/view/head'
9
+
10
+ module ODDB
11
+ module Html
12
+ module View
13
+ class Template < HtmlGrid::DivTemplate
14
+ include HtmlGrid::DojoToolkit::DojoTemplate
15
+ FOOT = Foot
16
+ HEAD = Head
17
+ HTTP_HEADERS = {
18
+ "Content-Type" => "text/html; charset=utf-8",
19
+ "Cache-Control" => "private, no-store, no-cache, must-revalidate, post-check=0, pre-check=0",
20
+ "Pragma" => "no-cache",
21
+ "Expires" => Time.now.rfc1123,
22
+ "P3P" => "CP='OTI NID CUR OUR STP ONL UNI PRE'",
23
+ }
24
+ COMPONENTS = {
25
+ [0,0] => :head,
26
+ [0,1] => :content,
27
+ [0,2] => NavigationFoot,
28
+ [0,3] => :foot,
29
+ }
30
+ CSS_ID_MAP = ['head', 'content', 'navigation', 'foot']
31
+ DOJO_DEBUG = ODDB.config.dojo_debug
32
+ DOJO_REQUIRE = [ 'dojo.widget.Tooltip' ]
33
+ DOJO_PARSE_WIDGETS = true
34
+ def title(context)
35
+ context.title {
36
+ _title.push(@lookandfeel.lookup(:html_owner)).join(' | ') }
37
+ end
38
+ def _title
39
+ parts = [:html_title, @session.zone]
40
+ [@session.state.direct_event].flatten.each_with_index { |part, idx|
41
+ parts << part if((idx%2) == 0)
42
+ }
43
+ parts.collect { |key|
44
+ @lookandfeel.lookup(key) { key if(key.is_a?(String)) } }.compact
45
+ end
46
+ def css_links(context)
47
+ if(@lookandfeel.enabled?(:external_css, false))
48
+ css_link(context, @lookandfeel.resource_external(:external_css))
49
+ else
50
+ super
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,583 @@
1
+ #!/usr/bin/env ruby
2
+ # Import::Dimdi -- de.oddb.org -- 04.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'fileutils'
5
+ require 'oddb/business/company'
6
+ require 'oddb/config'
7
+ require 'oddb/import/excel'
8
+ require 'oddb/util/code'
9
+ require 'oddb/util/money'
10
+ require 'oddb/drugs/active_agent'
11
+ require 'oddb/drugs/atc'
12
+ require 'oddb/drugs/composition'
13
+ require 'oddb/drugs/galenic_form'
14
+ require 'oddb/drugs/galenic_group'
15
+ require 'oddb/drugs/package'
16
+ require 'oddb/drugs/part'
17
+ require 'oddb/drugs/product'
18
+ require 'oddb/drugs/sequence'
19
+ require 'oddb/drugs/substance'
20
+ require 'oddb/drugs/substance_group'
21
+ require 'oddb/drugs/unit'
22
+ require 'open-uri'
23
+
24
+ module ODDB
25
+ module Import
26
+ module Dimdi
27
+ DIMDI_PATH = "http://www.dimdi.de/dynamic/de/amg/fbag/downloadcenter/"
28
+ def Dimdi.download_path
29
+ quater = ((Time.now.month-1)/3+1).to_s
30
+ year = Time.now.year.to_s
31
+ return DIMDI_PATH + year + "/" + quater + "-quartal/"
32
+ end
33
+ def Dimdi.current_date(url)
34
+ if(match = /festbetraege-(\d{4})(\d{2})\.xls/.match(open(url).read))
35
+ Date.new(match[1].to_i, match[2].to_i)
36
+ end
37
+ end
38
+ def Dimdi.download(file, &block)
39
+ url = File.join(download_path, file)
40
+ xls_dir = File.join(ODDB.config.var, 'xls')
41
+ FileUtils.mkdir_p(xls_dir)
42
+ dest = File.join(xls_dir, file)
43
+ unless(File.exist?(dest))
44
+ open(url) { |remote|
45
+ block.call(remote)
46
+ remote.rewind
47
+ open(dest, 'w') { |local|
48
+ local << remote.read
49
+ }
50
+ }
51
+ end
52
+ rescue StandardError => e
53
+ ODDB.logger.error('Dimdi') { e.message }
54
+ end
55
+ def Dimdi.download_latest(url, today, &block)
56
+ file = File.basename(url)
57
+ xls_dir = File.join(ODDB.config.var, 'xls')
58
+ FileUtils.mkdir_p(xls_dir)
59
+ dest = File.join(xls_dir, file)
60
+ archive = File.join(ODDB.config.var, 'xls',
61
+ sprintf("%s-%s", today.strftime("%Y.%m.%d"), file))
62
+ content = open(url).read
63
+ if(!File.exist?(dest) || content.size != File.size(dest))
64
+ open(archive, 'w') { |local|
65
+ local << content
66
+ }
67
+ open(archive, 'r', &block)
68
+ open(dest, 'w') { |local|
69
+ local << content
70
+ }
71
+ end
72
+ rescue StandardError => error
73
+ ODDB.logger.error('Dimdi') { error.message }
74
+ end
75
+ class GalenicForm < DatedExcel
76
+ def initialize(date = Date.today)
77
+ super
78
+ @count = 0
79
+ @created = 0
80
+ @existing = 0
81
+ end
82
+ def import_row(row)
83
+ abbr = cell(row, 0)
84
+ value = cell(row, 1)
85
+ if(abbr != nil && value != nil)
86
+ @count += 1
87
+ description = capitalize_all(value)
88
+ galenic_form = Drugs::GalenicForm.find_by_code(:value => abbr,
89
+ :type => "galenic_form",
90
+ :country => 'DE')
91
+ galenic_form ||= Drugs::GalenicForm.find_by_description(description)
92
+ if(galenic_form)
93
+ @existing += 1
94
+ else
95
+ @created += 1
96
+ galenic_form = Drugs::GalenicForm.new
97
+ galenic_form.description.de = description
98
+ end
99
+ galenic_form.add_code(Util::Code.new("galenic_form",
100
+ abbr, 'DE', @date))
101
+ galenic_form.save
102
+ galenic_form
103
+ end
104
+ end
105
+ def postprocess
106
+ {
107
+ 'Injektion/Infusion' \
108
+ => [ 'P', 'Fertigspritzen' ],
109
+ 'Tabletten' => [ 'O', 'Tabletten', 'Filmtabletten',
110
+ 'Kapseln', 'Dragees', 'Lacktabletten' ],
111
+ 'Transdermale Systeme' \
112
+ => [ 'TD', 'Pflaster, transdermal' ],
113
+ 'Tropfen' => [ 'P', 'Tropfen' ],
114
+ 'Retard-Tabletten'=> [ 'O', 'Retardtabletten',
115
+ 'Retardfilmtabletten', 'Retardkapseln',
116
+ 'Retarddragees' ],
117
+ 'Salben' => [ 'T', 'Creme', 'Gel', 'Lotion', 'Salbe' ],
118
+ 'Suppositorien' => [ 'R', 'Suppositorien' ],
119
+ 'Vaginal-Produkte'=> [ 'V', 'Vaginalcreme', 'Vaginalovula',
120
+ 'Vaginaltabletten',
121
+ 'Vaginalsuppositorien']
122
+ }.each { |groupname, formnames|
123
+ group = Drugs::GalenicGroup.find_by_name(groupname) \
124
+ || Drugs::GalenicGroup.new(groupname)
125
+ group.administration = formnames.shift
126
+ group.save
127
+ formnames.each { |name|
128
+ if((form = Drugs::GalenicForm.find_by_description(name)) \
129
+ && !form.group)
130
+ form.group = group
131
+ form.save
132
+ end
133
+ }
134
+ }
135
+ end
136
+ def report
137
+ [
138
+ sprintf("Imported %3i Galenic Forms per %s:",
139
+ @count, @date.strftime("%d.%m.%Y")),
140
+ sprintf("Visited %3i existing", @existing),
141
+ sprintf("Created %3i new", @created),
142
+ ]
143
+ end
144
+ end
145
+ class Product < DatedExcel
146
+ def initialize(date = Date.today)
147
+ super
148
+ @count = 0
149
+ @created = 0
150
+ @created_sequences = 0
151
+ @created_substances = 0
152
+ @deleted_sequences = 0
153
+ @deleted_products = 0
154
+ @existing = 0
155
+ @existing_sequences = 0
156
+ @reassigned_pzns = 0
157
+ @renamed_products = 0
158
+ end
159
+ def assign_substance_group(sub, groupname)
160
+ if(sub.group.nil? \
161
+ && (group = import_substance_group(groupname)))
162
+ sub.group = group
163
+ sub.save
164
+ end
165
+ end
166
+ def create_product name
167
+ product = Drugs::Product.new
168
+ product.name.de = name
169
+ product.save
170
+ end
171
+ def delete_sequence(sequence)
172
+ product = sequence.product
173
+ if(product.sequences.size == 1)
174
+ @deleted_products += 1
175
+ product.delete
176
+ else
177
+ @deleted_sequences += 1
178
+ sequence.delete
179
+ end
180
+ sequence
181
+ end
182
+ def import_atc(row, sequence)
183
+ atc_name = cell(row, 10)
184
+ substances = sequence.substances.uniq
185
+ candidates = []
186
+ if(substances.size == 1)
187
+ substance = substances.first
188
+ candidates = Drugs::Atc.search_by_exact_name(substance.to_s)
189
+ if(candidates.empty?)
190
+ candidates = Drugs::Atc.search_by_name(substance.to_s)
191
+ end
192
+ end
193
+ if(candidates.size != 1)
194
+ candidates = Drugs::Atc.search_by_exact_name(atc_name)
195
+ end
196
+ if(candidates.empty?)
197
+ candidates = Drugs::Atc.search_by_name(atc_name)
198
+ end
199
+ if(candidates.size == 1)
200
+ atc = candidates.first
201
+ if(sequence.atc.nil? \
202
+ || (sequence.atc != atc && atc.level >= sequence.atc.level))
203
+ sequence.atc = atc
204
+ sequence.save
205
+ end
206
+ end
207
+ end
208
+ def import_row(row)
209
+ if(value = cell(row, 0))
210
+ @package_date = cell(row, 13) || @date
211
+ @count += 1
212
+ pzn = u(value.to_i.to_s)
213
+ package = Drugs::Package.find_by_code(:type => 'cid',
214
+ :value => pzn,
215
+ :country => 'DE')
216
+ name = product_name(row)
217
+ product = Drugs::Product.find_by_name(name)
218
+ if !package
219
+ ## new package and possibly new product
220
+ import_product row, product, name
221
+ elsif !package.product
222
+ product ||= create_product name
223
+ if package.sequence.nil?
224
+ import_sequence row, product, package
225
+ else
226
+ seq = package.sequence
227
+ seq.product = product
228
+ seq.save
229
+ update_package row, package
230
+ end
231
+ else
232
+ ## update package-data
233
+ update_package row, package
234
+ end
235
+ end
236
+ end
237
+ def import_package(row, sequence, unitname)
238
+ ## we don't expect any multipart packages here
239
+ psize = cell(row, 2)
240
+ package = Drugs::Package.new
241
+ pzn = u(cell(row, 0).to_i.to_s)
242
+ package.add_code(Util::Code.new(:cid, pzn, 'DE', @package_date))
243
+ part = Drugs::Part.new
244
+ part.size = psize
245
+ if(unitname)
246
+ unit = Drugs::Unit.find_by_name(unitname)
247
+ if(unit.nil?)
248
+ unit = Drugs::Unit.new
249
+ unit.name.de = unitname
250
+ unit.save
251
+ end
252
+ part.unit = unit
253
+ end
254
+ part.composition = sequence.compositions.first
255
+ part.package = package
256
+ part.save
257
+ package.sequence = sequence
258
+ package.save
259
+ update_package(row, package)
260
+ end
261
+ def import_product(row, product, name)
262
+ if(product)
263
+ @existing += 1
264
+ else
265
+ @created += 1
266
+ product = create_product name
267
+ end
268
+ import_sequence(row, product)
269
+ end
270
+ def import_price(package, type, amount)
271
+ dotype = :"price_#{type}"
272
+ # if this price has been edited manually we won't overwrite
273
+ unless((data_origin = package.data_origin(dotype)) \
274
+ && data_origin.to_s.include?('@'))
275
+ if(price = package.price(type, 'DE'))
276
+ if(price != amount)
277
+ price.amount = amount
278
+ end
279
+ else
280
+ price = Util::Money.new(amount, type, 'DE')
281
+ package.add_price(price)
282
+ end
283
+ package.data_origins.store dotype, :dimdi
284
+ end
285
+ end
286
+ def import_sequence(row, product, package=nil)
287
+ ## be simplistic here - the input file can not describe
288
+ # multiple compositions or active agents. Simply identify
289
+ # existing active agents by their substance and dose.
290
+ sequence, composition, substance, dose = nil
291
+ substances = import_substances(row)
292
+ galform = import_galenic_form(row)
293
+ if(dose = cell(row, 8))
294
+ dose = Drugs::Dose.new(dose, 'mg')
295
+ end
296
+ if product
297
+ sequence = product.sequences.find { |seq|
298
+ doses = seq.doses
299
+ seq.galenic_forms == [galform] \
300
+ && seq.substances == substances \
301
+ && (doses.empty? || doses.inject { |a, b| a + b } == dose)
302
+ }
303
+ end
304
+ if(sequence)
305
+ @existing_sequences += 1
306
+ else
307
+ @created_sequences += 1
308
+ sequence = Drugs::Sequence.new
309
+ composition = Drugs::Composition.new
310
+ if(substances.size > 1)
311
+ dose = nil
312
+ end
313
+ substances.each { |substance|
314
+ active_agent = Drugs::ActiveAgent.new(substance, dose)
315
+ active_agent.composition = composition
316
+ }
317
+ composition.galenic_form = galform
318
+ if(factor = cell(row, 9))
319
+ composition.equivalence_factor = factor
320
+ end
321
+ composition.sequence = sequence
322
+ composition.save
323
+ sequence.product = product
324
+ sequence.save
325
+ end
326
+ import_atc(row, sequence)
327
+ if(package)
328
+ package.sequence = sequence
329
+ package.save
330
+ update_package(row, package)
331
+ else
332
+ unitname = nil
333
+ if(galform)
334
+ unitname = galform.description.de
335
+ end
336
+ import_package(row, sequence, unitname)
337
+ end
338
+ end
339
+ def import_galenic_form(row)
340
+ Drugs::GalenicForm.find_by_code(:value => cell(row, 6),
341
+ :type => "galenic_form",
342
+ :country => 'DE')
343
+ end
344
+ def import_substances(row)
345
+ subs = []
346
+ groupname = cell(row, 10)
347
+ if(abbr = cell(row, 7))
348
+ if(sub = Drugs::Substance.find_by_code(:value => abbr,
349
+ :type => "substance", :country => "DE"))
350
+ assign_substance_group(sub, groupname)
351
+ subs.push(sub)
352
+ else
353
+ subs = Drugs::Substance.search_by_code(:value => abbr,
354
+ :type => "substance-combination", :country => 'DE')
355
+ end
356
+ end
357
+ if(subs.empty?)
358
+ names = groupname.split('+')
359
+ subs = names.collect { |name|
360
+ assumed_name = name.strip[/^\S+/]
361
+ unless(assumed_name.empty?)
362
+ sub = Drugs::Substance.find_by_name(assumed_name)
363
+ if(sub.nil?)
364
+ @created_substances += 1
365
+ sub = Drugs::Substance.new
366
+ sub.name.de = assumed_name
367
+ sub.save
368
+ end
369
+ if(names.size == 1)
370
+ assign_substance_group(sub, groupname)
371
+ end
372
+ sub
373
+ end
374
+ }
375
+ end
376
+ subs.compact
377
+ end
378
+ def import_substance_group(groupname)
379
+ groupname = groupname.to_s.strip
380
+ if(groupname.length > 3)
381
+ group = Drugs::SubstanceGroup.find_by_name(groupname)
382
+ if(group.nil?)
383
+ group = Drugs::SubstanceGroup.new
384
+ group.name.de = groupname
385
+ group.save
386
+ end
387
+ group
388
+ end
389
+ end
390
+ def move_package(row, product, package, name)
391
+ @existing += 1
392
+ move_from = package.sequence
393
+ move_to = product.sequences.find { |sequence|
394
+ sequence.comparable?(move_from)
395
+ }
396
+ if(move_to)
397
+ @existing_sequences += 1
398
+ package.sequence = move_to
399
+ package.save
400
+ update_package(row, package)
401
+ if(move_from.packages.empty?)
402
+ delete_sequence(move_from)
403
+ end
404
+ elsif(move_from.packages.size == 1)
405
+ @existing_sequences += 1
406
+ move_sequence(product, move_from)
407
+ update_package(row, package)
408
+ else
409
+ import_sequence(row, product, package)
410
+ end
411
+ end
412
+ def move_sequence(product, sequence)
413
+ move_from = sequence.product
414
+ sequence.product = product
415
+ sequence.save
416
+ if(move_from.sequences.empty?)
417
+ @deleted_products += 1
418
+ move_from.delete
419
+ end
420
+ end
421
+ def postprocess
422
+ Drugs::Product.all { |product|
423
+ sequences = product.sequences.dup
424
+ sequences.each { |sequence|
425
+ sequences.dup.each { |other|
426
+ if(sequence != other && other.identical?(sequence))
427
+ other.packages.each { |package|
428
+ package.sequence = sequence
429
+ package.save
430
+ }
431
+ sequences.delete other # should be safe because Array is ordered
432
+ other.delete
433
+ end
434
+ }
435
+ }
436
+ }
437
+ end
438
+ def product_name(row)
439
+ if data = cell(row, 1)
440
+ capitalize_all(data.gsub(/[^A-Z\s]/, '').gsub(/\s+/, ' ')).strip
441
+ end
442
+ end
443
+ def rename_product(row, package, name)
444
+ @renamed_products += 1
445
+ product = package.product
446
+ product.name.de = name
447
+ product.save
448
+ update_package(row, package)
449
+ end
450
+ def report
451
+ [
452
+ sprintf("Imported %5i Products per %s:",
453
+ @count, @date.strftime("%d.%m.%Y")),
454
+ sprintf("Visited %5i existing Products", @existing),
455
+ sprintf("Visited %5i existing Sequences",
456
+ @existing_sequences),
457
+ sprintf("Ignored %5i unknown Products", @created),
458
+ sprintf("Created %5i new Sequences", @created_sequences),
459
+ sprintf("Created %5i new Substances from Combinations",
460
+ @created_substances),
461
+ sprintf("Renamed %5i Products", @renamed_products),
462
+ sprintf("Reassigned %5i PZNs", @reassigned_pzns),
463
+ sprintf("Deleted %5i Products", @deleted_products),
464
+ sprintf("Deleted %5i Sequences", @deleted_sequences),
465
+ ]
466
+ end
467
+ def update_package(row, package)
468
+ modified = false
469
+ fpgroup = cell(row, 11)
470
+ unless(fpgroup.is_a?(String))
471
+ fpgroup = u(fpgroup.to_i.to_s)
472
+ end
473
+ if(code = package.code(:festbetragsgruppe))
474
+ if(code.value != fpgroup)
475
+ modified = true
476
+ code.value = fpgroup, @package_date
477
+ end
478
+ else
479
+ modified = true
480
+ package.add_code(Util::Code.new(:festbetragsgruppe,
481
+ fpgroup, 'DE', @package_date))
482
+ end
483
+ import_price(package, :public, cell(row, 3)) && modified = true
484
+ if(efp = package._price_exfactory)
485
+ import_price(package, :exfactory, efp.to_f) && modified = true
486
+ end
487
+ import_price(package, :festbetrag, cell(row, 4)) && modified = true
488
+ if(level = cell(row, 12))
489
+ if(code = package.code(:festbetragsstufe))
490
+ if(code.value != level.to_i)
491
+ modified = true
492
+ code.value = level.to_i, @package_date
493
+ end
494
+ else
495
+ modified = true
496
+ package.add_code(Util::Code.new(:festbetragsstufe, level.to_i,
497
+ 'DE', @package_date))
498
+ end
499
+ end
500
+ package.save if(modified)
501
+ end
502
+ end
503
+ class Substance < DatedExcel
504
+ def initialize(date = Date.today)
505
+ super
506
+ @combi_created = 0
507
+ @combi_existing = 0
508
+ @count = 0
509
+ @created = 0
510
+ @existing = 0
511
+ end
512
+ def import_row(row)
513
+ @count += 1
514
+ abbr = cell(row, 0)
515
+ names = capitalize_all(cell(row, 1)).split('+')
516
+ if(names.size == 1)
517
+ import_substance(abbr, names.pop)
518
+ else
519
+ import_substances(abbr, names)
520
+ end
521
+ end
522
+ def import_substance(abbr, name)
523
+ substance = Drugs::Substance.find_by_code(:value => abbr,
524
+ :type => "substance", :country => "DE")
525
+ substance ||= Drugs::Substance.find_by_name(name)
526
+ unsaved = false
527
+ if(substance)
528
+ @existing += 1
529
+ else
530
+ @created += 1
531
+ substance = Drugs::Substance.new
532
+ substance.name.de = name
533
+ unsaved = true
534
+ end
535
+ unless(substance.code('substance', 'DE'))
536
+ substance.add_code(Util::Code.new("substance", abbr,
537
+ 'DE', @date))
538
+ unsaved = true
539
+ end
540
+ substance.save if(unsaved)
541
+ substance
542
+ end
543
+ def import_substances(abbr, names)
544
+ code = Util::Code.new('substance-combination', abbr,
545
+ 'DE', @date)
546
+ names.collect { |name|
547
+ substance = Drugs::Substance.find_by_name(name)
548
+ if(substance)
549
+ @combi_existing += 1
550
+ else
551
+ @combi_created += 1
552
+ substance = Drugs::Substance.new
553
+ substance.name.de = name
554
+ end
555
+ substance.add_code(code)
556
+ substance.save
557
+ substance
558
+ }
559
+ end
560
+ def postprocess
561
+ ## a special case that probably fits best here:
562
+ if((ass = Drugs::Substance.find_by_name('ASS')) \
563
+ && ass.name.de == 'ASS')
564
+ ass.name.add_synonym('ASS')
565
+ ass.name.de = 'Acetylsalicylsäure'
566
+ ass.save
567
+ end
568
+ end
569
+ def report
570
+ [
571
+ sprintf("Imported %3i Substances per %s:",
572
+ @count, @date.strftime("%d.%m.%Y")),
573
+ sprintf("Visited %3i existing", @existing),
574
+ sprintf("Visited %3i existing in Combinations",
575
+ @combi_existing),
576
+ sprintf("Created %3i new", @created),
577
+ sprintf("Created %3i new from Combinations", @combi_created),
578
+ ]
579
+ end
580
+ end
581
+ end
582
+ end
583
+ end