oddb2xml 2.7.8 → 2.8.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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +1 -0
  3. data/.github/workflows/codeql.yml +41 -0
  4. data/.github/workflows/ruby.yml +1 -1
  5. data/.gitignore +0 -0
  6. data/.rspec +0 -0
  7. data/.ruby-version +1 -0
  8. data/.standard.yml +0 -0
  9. data/Elexis_Artikelstamm_v003.xsd +0 -0
  10. data/Elexis_Artikelstamm_v5.xsd +4 -4
  11. data/Gemfile +2 -0
  12. data/Gemfile.lock +198 -0
  13. data/History.txt +4 -0
  14. data/LICENSE +0 -0
  15. data/Manifest.txt +0 -0
  16. data/QA.md +0 -0
  17. data/README.md +0 -0
  18. data/Rakefile +0 -0
  19. data/artikelstamm.md +0 -0
  20. data/data/article_overrides.yaml +0 -0
  21. data/data/gal_forms.yaml +0 -0
  22. data/data/gal_groups.yaml +0 -0
  23. data/data/gtin2ignore.yaml +0 -0
  24. data/data/product_overrides.yaml +0 -0
  25. data/dokumentation_calc.textile +0 -0
  26. data/flake.lock +80 -0
  27. data/flake.nix +36 -0
  28. data/gemset.nix +814 -0
  29. data/lib/oddb2xml/builder.rb +34 -17
  30. data/lib/oddb2xml/calc.rb +2 -2
  31. data/lib/oddb2xml/chapter_70_hack.rb +0 -0
  32. data/lib/oddb2xml/cli.rb +15 -1
  33. data/lib/oddb2xml/compare.rb +0 -0
  34. data/lib/oddb2xml/compositions_syntax.rb +0 -0
  35. data/lib/oddb2xml/compressor.rb +0 -0
  36. data/lib/oddb2xml/downloader.rb +22 -0
  37. data/lib/oddb2xml/extractor.rb +30 -0
  38. data/lib/oddb2xml/options.rb +4 -0
  39. data/lib/oddb2xml/parslet_compositions.rb +2 -0
  40. data/lib/oddb2xml/util.rb +0 -0
  41. data/lib/oddb2xml/version.rb +1 -1
  42. data/lib/oddb2xml/xml_definitions.rb +0 -0
  43. data/lib/oddb2xml.rb +0 -0
  44. data/oddb2xml.xsd +3 -27
  45. data/oddb_calc.xsd +0 -0
  46. data/spec/artikelstamm_spec.rb +8 -2
  47. data/spec/builder_spec.rb +7 -8
  48. data/spec/calc_spec.rb +0 -0
  49. data/spec/check_artikelstamm_spec.rb +0 -0
  50. data/spec/cli_spec.rb +0 -0
  51. data/spec/compare_spec.rb +0 -0
  52. data/spec/composition_syntax_spec.rb +0 -0
  53. data/spec/compressor_spec.rb +0 -0
  54. data/spec/data/AipsDownload.zip +0 -0
  55. data/spec/data/Elexis_Artikelstamm_v5.xsd +0 -0
  56. data/spec/data/GL_Diff_SB.xml +0 -0
  57. data/spec/data/ItCodes.xml +0 -0
  58. data/spec/data/PR121001.txt +0 -0
  59. data/spec/data/PR121002.txt +0 -0
  60. data/spec/data/Preparations.xml +0 -0
  61. data/spec/data/Publications.xls +0 -0
  62. data/spec/data/artikelstamm_N_010917.xml +0 -0
  63. data/spec/data/artikelstamm_N_011217.xml +0 -0
  64. data/spec/data/artikelstamm_P_010917.xml +0 -0
  65. data/spec/data/artikelstamm_P_011217.xml +0 -0
  66. data/spec/data/atc.csv +0 -0
  67. data/spec/data/check_artikelstamm/artikelstamm_v5_gtin_non_numeric.xml +0 -0
  68. data/spec/data/check_artikelstamm/artikelstamm_v5_gtin_not_uniq.xml +0 -0
  69. data/spec/data/check_artikelstamm/artikelstamm_v5_limitation_exists.xml +0 -0
  70. data/spec/data/check_artikelstamm/artikelstamm_v5_okay.xml +0 -0
  71. data/spec/data/check_artikelstamm/artikelstamm_v5_pharma_has_product.xml +0 -0
  72. data/spec/data/check_artikelstamm/artikelstamm_v5_prodno_not_uniq.xml +0 -0
  73. data/spec/data/check_artikelstamm/artikelstamm_v5_product_needs_article.xml +0 -0
  74. data/spec/data/column_c.txt +0 -0
  75. data/spec/data/compositions.txt +0 -0
  76. data/spec/data/compressor/oddb2xml_files_bm_update.txt +0 -0
  77. data/spec/data/compressor/oddb2xml_files_lppv.txt +0 -0
  78. data/spec/data/compressor/oddb2xml_files_nonpharma.xls +0 -0
  79. data/spec/data/epha_interactions.csv +0 -0
  80. data/spec/data/listen_neu.html +0 -0
  81. data/spec/data/medregbm_betrieb.txt +0 -0
  82. data/spec/data/medregbm_person.txt +0 -0
  83. data/spec/data/oddb2xml_files_bm_update.txt +0 -0
  84. data/spec/data/oddb2xml_files_lppv.txt +0 -0
  85. data/spec/data/oddb2xml_files_nonpharma.xls +0 -0
  86. data/spec/data/problems.txt +0 -0
  87. data/spec/data/refdata_NonPharma.xml +0 -0
  88. data/spec/data/refdata_Pharma.xml +0 -0
  89. data/spec/data/swissmedic_fridges.html +0 -0
  90. data/spec/data/swissmedic_info.html +0 -0
  91. data/spec/data/swissmedic_info_2.html +0 -0
  92. data/spec/data/swissmedic_orphan.xlsx +0 -0
  93. data/spec/data/swissmedic_orphans.html +0 -0
  94. data/spec/data/swissmedic_package.xlsx +0 -0
  95. data/spec/data/swissmedic_packages.html +0 -0
  96. data/spec/data/transfer.dat +0 -0
  97. data/spec/data/v5_first.xml +0 -0
  98. data/spec/data/v5_second.xml +0 -0
  99. data/spec/data/varia_De.htm +0 -0
  100. data/spec/data/vcr/transfer.dat +0 -0
  101. data/spec/data/vcr/transfer.zip +0 -0
  102. data/spec/data/wsdl_nonpharma.xml +0 -0
  103. data/spec/data/wsdl_pharma.xml +0 -0
  104. data/spec/fixtures/vcr_cassettes/artikelstamm.json +0 -0
  105. data/spec/galenic_spec.rb +0 -0
  106. data/spec/parslet_spec.rb +1 -1
  107. data/tools/cacert.pem +0 -0
  108. data/tools/set.bat +0 -0
  109. data/tools/win_fetch_cacerts.rb +0 -0
  110. metadata +13 -7
  111. data/shell.nix +0 -19
@@ -42,7 +42,7 @@ module Oddb2xml
42
42
  @@gtin2ignore ||= []
43
43
  attr_accessor :subject, :refdata, :items, :flags, :lppvs,
44
44
  :actions, :migel, :orphan,
45
- :infos, :packs, :infos_zur_rose,
45
+ :infos, :packs, :infos_zur_rose, :firstbase,
46
46
  :ean14, :tag_suffix,
47
47
  :companies, :people,
48
48
  :xsd
@@ -57,6 +57,7 @@ module Oddb2xml
57
57
  @packs = {}
58
58
  @migel = {}
59
59
  @infos_zur_rose ||= {}
60
+ @firstbase ||= {}
60
61
  @actions = []
61
62
  @orphan = []
62
63
  @ean14 = false
@@ -170,6 +171,19 @@ module Oddb2xml
170
171
  end
171
172
  end
172
173
  end
174
+ @firstbase.each do |ean13, obj|
175
+ entry = {
176
+ ean13: obj[:gtin],
177
+ desc_de: obj[:trade_item_description_de],
178
+ desc_fr: obj[:trade_item_description_fr],
179
+ atc_code: "",
180
+ company_ean: obj[:gln],
181
+ firstbase: true
182
+ }
183
+ if @refdata[obj[:gtin]].nil?
184
+ @articles << entry
185
+ end
186
+ end
173
187
  end
174
188
  Oddb2xml.log("prepare_articles done. Added #{nr_added} prices. Total #{@articles.size}")
175
189
  end
@@ -378,7 +392,6 @@ module Oddb2xml
378
392
  xml.LIMNIV lim[:niv]
379
393
  xml.DSCRD lim[:desc_de]
380
394
  xml.DSCRF lim[:desc_fr]
381
- xml.DSCRI lim[:desc_it]
382
395
  xml.VDAT lim[:vdate]
383
396
  nbr_records += 1
384
397
  end
@@ -536,7 +549,7 @@ module Oddb2xml
536
549
  if lang == :de
537
550
  name = refdata && refdata[:desc_de] ? refdata[:desc_de] : obj[:sequence_name]
538
551
  elsif lang == :fr
539
- name = refdata[:desc_fr] if refdata && refdata[:desc_fr]
552
+ name = refdata && refdata[:desc_fr] ? refdata[:desc_fr] : obj[:sequence_name]
540
553
  elsif lang == :it
541
554
  name = refdata[:desc_it] if refdata && refdata[:desc_it]
542
555
  else
@@ -560,7 +573,7 @@ module Oddb2xml
560
573
  @missing.each do |obj|
561
574
  ean = obj[:ean13]
562
575
  next unless check_name(obj, :de)
563
- # next unless check_name(obj, :fr)
576
+ next unless check_name(obj, :fr)
564
577
  next if /^Q/i.match?(obj[:atc])
565
578
  if obj[:prodno]
566
579
  next if emitted.index(obj[:prodno])
@@ -572,9 +585,6 @@ module Oddb2xml
572
585
  xml.PRODNO obj[:prodno] if obj[:prodno]
573
586
  xml.DSCRD check_name(obj, :de)
574
587
  xml.DSCRF check_name(obj, :fr) if check_name(obj, :fr)
575
- binding.pry if check_name(obj, :de) && check_name(obj, :de).eql?('Varilrix Trockensub c solv')
576
-
577
- xml.DSCRI check_name(obj, :it) if check_name(obj, :it)
578
588
  xml.ATC obj[:atc_code] unless obj[:atc_code].empty?
579
589
  xml.IT obj[:ith_swissmedic] if obj[:ith_swissmedic]
580
590
  xml.CPT
@@ -584,6 +594,14 @@ module Oddb2xml
584
594
  xml.CompositionSwissmedic obj[:composition_swissmedic] if obj[:composition_swissmedic]
585
595
  }
586
596
  end
597
+ @firstbase.each do |ean13, obj|
598
+ xml.PRD("DT" => "") {
599
+ xml.GTIN obj[:gtin]
600
+ xml.CPT
601
+ xml.DSCRD obj[:trade_item_description_de]
602
+ xml.DSCRF obj[:trade_item_description_fr]
603
+ }
604
+ end
587
605
  @products.sort.to_h.each do |ean13, obj|
588
606
  next if /^Q/i.match?(obj[:atc])
589
607
  seq = obj[:seq]
@@ -598,7 +616,6 @@ module Oddb2xml
598
616
  xml.PRODNO ppac[:prodno] if ppac[:prodno] && !ppac[:prodno].empty?
599
617
  xml.DSCRD check_name(obj, :de)
600
618
  xml.DSCRF check_name(obj, :fr)
601
- xml.DSCRI check_name(obj, :it)
602
619
  # xml.BNAMD
603
620
  # xml.BNAMF
604
621
  # xml.ADNAMD
@@ -952,10 +969,10 @@ module Oddb2xml
952
969
  end
953
970
  xml.DSCRD obj[:desc_de] if obj[:desc_de] && !obj[:desc_de].empty?
954
971
  xml.DSCRF obj[:desc_fr] if obj[:desc_fr] && !obj[:desc_fr].empty?
955
- xml.DSCRI obj[:desc_it] if obj[:desc_it] && !obj[:desc_it].empty?
972
+ xml.DSCRF obj[:desc_de] if !obj[:desc_fr] || obj[:desc_fr].empty?
956
973
  xml.SORTD obj[:desc_de].upcase if obj[:desc_de] && !obj[:desc_de].empty?
957
974
  xml.SORTF obj[:desc_fr].upcase if obj[:desc_fr] && !obj[:desc_fr].empty?
958
- xml.SORTI obj[:desc_it].upcase if obj[:desc_it] && !obj[:desc_it].empty?
975
+ xml.SORTF obj[:desc_de].upcase if !obj[:desc_fr] || obj[:desc_fr].empty?
959
976
  # xml.QTYUD
960
977
  # xml.QTYUF
961
978
  # xml.IMG
@@ -966,7 +983,6 @@ module Oddb2xml
966
983
  if obj[:seq]
967
984
  xml.SYN1D obj[:seq][:name_de] unless obj[:seq][:name_de].empty?
968
985
  xml.SYN1F obj[:seq][:name_fr] unless obj[:seq][:name_fr].empty?
969
- xml.SYN1I obj[:seq][:name_it] unless obj[:seq][:name_it].empty?
970
986
  end
971
987
  if obj[:seq]
972
988
  case obj[:seq][:deductible]
@@ -1520,21 +1536,21 @@ module Oddb2xml
1520
1536
  xml.GTIN pkg_gtin.to_s.rjust(13, "0")
1521
1537
  xml.SALECD("A")
1522
1538
  # maxLength for DSCR is 50 for Artikelstamm v3
1523
- xml.DSCR(name) # for g for zur_rose
1539
+ xml.DSCR(name) # for description for zur_rose
1524
1540
  name_fr = item[:name_fr] + " " + item[:desc_fr].strip + " " + package[:desc_fr] if package && package[:desc_fr]
1525
1541
  name_fr ||= @refdata[pkg_gtin] ? @refdata[pkg_gtin][:desc_fr] : nil
1526
1542
  # Zugelassenen Packungen has only german names
1527
1543
  name_fr ||= (obj[:name_fr] + ", " + obj[:desc_fr]).strip if obj[:name_fr]
1528
1544
  # ZuRorse has only german names
1529
1545
  name_fr ||= (item[:name_fr] + ", " + item[:desc_fr]) if item
1530
- xml.DSCRF(name_fr) if name_fr
1546
+ xml.DSCRF(name_fr)
1531
1547
  name_it = item[:name_it] + " " + item[:desc_it].strip + " " + package[:desc_it] if package && package[:desc_it]
1532
1548
  name_it ||= @refdata[pkg_gtin] ? @refdata[pkg_gtin][:desc_it] : nil
1533
1549
  # Zugelassenen Packungen has only german names
1534
1550
  name_it ||= (obj[:name_it] + ", " + obj[:desc_it]).strip if obj[:name_it]
1535
1551
  # ZuRorse has only german names
1536
1552
  name_it ||= (item[:name_it] + ", " + item[:desc_it]) if item
1537
- xml.DSCRI(name_it) if name_it
1553
+ xml.DSCRI(name_it)
1538
1554
  if obj[:company_name] || obj[:company_ean]
1539
1555
  xml.COMP do # Manufacturer
1540
1556
  xml.NAME obj[:company_name][0..99] # limit to 100 chars as in XSD
@@ -1647,7 +1663,7 @@ module Oddb2xml
1647
1663
  emit_salecd(xml, ean13, obj)
1648
1664
  description = obj[:desc_de] || obj[:description] # for description for zur_rose
1649
1665
  xml.DSCR(description)
1650
- xml.DSCRF(obj[:desc_fr]) if obj[:desc_fr] && !obj[:desc_fr].empty?
1666
+ xml.DSCRF(obj[:desc_fr])
1651
1667
  xml.DSCRI(obj[:desc_it]) if obj[:desc_it] && !obj[:desc_it].empty?
1652
1668
  if obj[:company_ean] && !obj[:company_ean].empty?
1653
1669
  xml.COMP do
@@ -1752,7 +1768,6 @@ module Oddb2xml
1752
1768
  nr_products += 1
1753
1769
  xml.PRODUCT do
1754
1770
  xml.PRODNO prodno
1755
-
1756
1771
  if sequence
1757
1772
  xml.SALECD("A") # these products are always active!
1758
1773
  name_de = "#{sequence[:name_de]} #{sequence[:desc_de]}".strip if sequence[:name_de]
@@ -1761,10 +1776,11 @@ module Oddb2xml
1761
1776
  else
1762
1777
  sequence[:desc_de]
1763
1778
  end
1779
+ name_fr ||= (ppac && ppac[:sequence_name])
1764
1780
  name_fr = "#{sequence[:name_fr]} #{sequence[:desc_fr]}".strip if sequence[:name_fr]
1765
1781
  name_it = "#{sequence[:name_it]} #{sequence[:desc_it]}".strip if sequence[:name_it]
1766
1782
  override(xml, prodno, :DSCR, name_de.strip)
1767
- override(xml, prodno, :DSCRF, name_fr.strip) if name_fr && !name_fr.empty?
1783
+ override(xml, prodno, :DSCRF, name_fr.strip)
1768
1784
  override(xml, prodno, :DSCRI, name_it.strip) if name_it && !name_it.empty?
1769
1785
  # use overriden ATC if possibel
1770
1786
  atc = sequence[:atc] || sequence[:atc_code]
@@ -1779,6 +1795,7 @@ module Oddb2xml
1779
1795
  xml.comment "Chapter70 hack prodno #{prodno} #{obj[:description].encode(xml: :text).gsub("--", "-")}"
1780
1796
  xml.SALECD("A") # these products are always active!
1781
1797
  xml.DSCR obj[:description]
1798
+ xml.DSCRF ""
1782
1799
  if @limitations.index(obj[:code])
1783
1800
  xml.LIMNAMEBAG obj[:code]
1784
1801
  used_limitations << obj[:code]
data/lib/oddb2xml/calc.rb CHANGED
@@ -95,8 +95,8 @@ module Oddb2xml
95
95
  UNKNOWN_GALENIC_FORM = 140
96
96
  UNKNOWN_GALENIC_GROUP = 1
97
97
  DATA_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data"))
98
- @@galenic_groups = YAML.load_file(File.join(DATA_DIR, "gal_groups.yaml"))
99
- @@galenic_forms = YAML.load_file(File.join(DATA_DIR, "gal_forms.yaml"))
98
+ @@galenic_groups = YAML.load_file(File.join(DATA_DIR, "gal_groups.yaml"), permitted_classes: [ Oddb2xml::GalenicForm, Oddb2xml::GalenicGroup, Symbol])
99
+ @@galenic_forms = YAML.load_file(File.join(DATA_DIR, "gal_forms.yaml"), permitted_classes: [ Oddb2xml::GalenicForm, Oddb2xml::GalenicGroup, Symbol])
100
100
  @@new_galenic_forms = []
101
101
  @@names_without_galenic_forms = []
102
102
  @@rules_counter = {}
File without changes
data/lib/oddb2xml/cli.rb CHANGED
@@ -26,6 +26,7 @@ module Oddb2xml
26
26
  @packs = {} # [option] Packungen from Swissmedic for dat
27
27
  @infos_zur_rose = {} # [addition] infos_zur_rose and other infos from zurrose transfer.txt
28
28
  @migel = {} # [addition] additional Non Pharma products from files repo
29
+ @firstbase = {}
29
30
  @actions = [] # [addition] interactions from epha
30
31
  @orphan = [] # [addition] Orphaned drugs from Swissmedic xls
31
32
  # addresses
@@ -60,6 +61,9 @@ module Oddb2xml
60
61
  threads << download(:package) # swissmedic
61
62
  threads << download(:lppv) # oddb2xml_files
62
63
  threads << download(:bag) # bag.e-mediat
64
+ if @options[:firstbase]
65
+ threads << download(:firstbase) # https://github.com/zdavatz/oddb2xml/issues/63
66
+ end
63
67
  types.each do |type|
64
68
  threads << download(:refdata, type) # refdata
65
69
  end
@@ -85,6 +89,7 @@ module Oddb2xml
85
89
  puts "Validatied #{@the_files[:artikelstamm]}"
86
90
  else
87
91
  puts "Validating failed using #{cmd}"
92
+ require'pry'; binding.pry
88
93
  raise "Validating failed using #{cmd}"
89
94
  end
90
95
  end
@@ -124,7 +129,7 @@ module Oddb2xml
124
129
  builder.infos = @infos
125
130
  builder.packs = @packs
126
131
  # additional sources
127
- %w[actions orphan migel infos_zur_rose].each do |addition|
132
+ %w[actions orphan migel infos_zur_rose firstbase].each do |addition|
128
133
  builder.send("#{addition}=".intern, instance_variable_get("@#{addition}"))
129
134
  end
130
135
  end
@@ -312,6 +317,15 @@ module Oddb2xml
312
317
  @refdata_types[type]
313
318
  end
314
319
 
320
+ when :firstbase
321
+ downloader = FirstbaseDownloader.new(@options)
322
+ bin = downloader.download
323
+ Oddb2xml.log("FirstbaseDownloader bin #{File.size(bin)} bytes")
324
+ @mutex.synchronize do
325
+ @firstbase = FirstbaseExtractor.new(bin).to_hash
326
+ Oddb2xml.log("FirstbaseExtractor added #{@firstbase.size} firstbase items")
327
+ @firstbase
328
+ end
315
329
  end
316
330
  end
317
331
 
File without changes
File without changes
File without changes
@@ -381,4 +381,26 @@ module Oddb2xml
381
381
  read_xml_from_zip(/^AipsDownload_/iu, file)
382
382
  end
383
383
  end
384
+
385
+ class FirstbaseDownloader < Downloader
386
+ BASE_URL = "https://www.firstbase.ch"
387
+ include DownloadMethod
388
+ def initialize(type = :orphan, options = {})
389
+ @url = BASE_URL + "/sites/default/files/2023-09/firstbase_healthcare_public_data-dump%2C%2020230920.xlsx"
390
+ end
391
+
392
+ def download
393
+ @file2save = File.join(DOWNLOADS, "firstbase.xlsx")
394
+ report_download(@url, @file2save)
395
+ begin
396
+ download_as(@file2save, "w+")
397
+ return File.expand_path(@file2save)
398
+ rescue Timeout::Error, Errno::ETIMEDOUT
399
+ retrievable? ? retry : raise
400
+ ensure
401
+ Oddb2xml.download_finished(@file2save, false)
402
+ end
403
+ File.expand_path(@file2save)
404
+ end
405
+ end
384
406
  end
@@ -591,4 +591,34 @@ module Oddb2xml
591
591
  nil
592
592
  end
593
593
  end
594
+
595
+ class FirstbaseExtractor < Extractor
596
+ def initialize(file)
597
+ @sheet = RubyXL::Parser.parse(file).worksheets[0]
598
+ end
599
+
600
+ def to_hash
601
+ data = {}
602
+ return data unless @sheet
603
+ @sheet.each_with_index do |row, i|
604
+ next if i <= 1
605
+ gtin = row[0].value.to_s.gsub(/^0+/, '')
606
+ data[gtin] = {
607
+ gtin: gtin,
608
+ gln: row[1].value.to_s,
609
+ target_market: row[2] ? row[2].value.to_s: "",
610
+ gpc: row[3] ? row[3].value.to_s: "",
611
+ trade_item_description_de: row[4] ? row[4].value.to_s: "",
612
+ trade_item_description_en: row[5] ? row[5].value.to_s: "",
613
+ trade_item_description_fr: row[6] ? row[6].value.to_s: "",
614
+ trade_item_description_it: row[7] ? row[7].value.to_s: "",
615
+ manufacturer_name: row[8] ? row[8].value.to_s: "",
616
+ start_availability_date: row[9] ? row[9].value.to_s: "",
617
+ gross_weight: row[10] ? row[10].value.to_s: "",
618
+ net_weight: row[11] ? row[11].value.to_s: "",
619
+ }
620
+ end
621
+ data
622
+ end
623
+ end
594
624
  end
@@ -43,6 +43,7 @@ module Oddb2xml
43
43
  opt :log, "log important actions", short: :none
44
44
  opt :use_ra11zip, "Use the ra11.zip (a zipped transfer.dat from Galexis)",
45
45
  default: File.exist?("ra11.zip") ? "ra11.zip" : nil, type: :string
46
+ opt :firstbase, "Build all NONPHARMA articles on firstbase", short: "b", default: false
46
47
  end
47
48
 
48
49
  @opts[:percent] = @opts[:increment]
@@ -63,6 +64,9 @@ module Oddb2xml
63
64
  @opts[:extended] = true
64
65
  @opts[:price] = :zurrose
65
66
  end
67
+ if @opts[:firstbase]
68
+ @opts[:nonpharma] = true
69
+ end
66
70
  @opts[:price] = :zurrose if @opts[:price].is_a?(TrueClass)
67
71
  @opts[:price] = @opts[:price].to_sym if @opts[:price]
68
72
  @opts[:ean14] = @opts[:include]
@@ -430,6 +430,7 @@ class ParseComposition
430
430
  ast = transf.apply(parser.parse(cleaned))
431
431
  end
432
432
  rescue Parslet::ParseFailed => error
433
+ @@error_handler.nrParsingErrors ||= 0
433
434
  @@error_handler.nrParsingErrors += 1
434
435
  puts "#{File.basename(__FILE__)}:#{__LINE__}: failed parsing ==> #{cleaned} #{error}"
435
436
  return nil
@@ -495,6 +496,7 @@ class ParseGalenicForm
495
496
  ast = transf.apply(parser.parse(string))
496
497
  end
497
498
  rescue Parslet::ParseFailed => error
499
+ @@error_handler.nrParsingErrors ||= 0
498
500
  @@error_handler.nrParsingErrors += 1
499
501
  puts "#{File.basename(__FILE__)}:#{__LINE__}: failed parsing ==> #{string} #{error}"
500
502
  return nil
data/lib/oddb2xml/util.rb CHANGED
File without changes
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "2.7.8"
2
+ VERSION = "2.8.0"
3
3
  end
File without changes
data/lib/oddb2xml.rb CHANGED
File without changes
data/oddb2xml.xsd CHANGED
@@ -48,7 +48,6 @@
48
48
  FIRST import all data from swissINDEX
49
49
  * DSCRD German name
50
50
  * DSCRF French name (Products/article only from ZurRose do not have a french name)
51
- * DSCRI Italian name (Products/article only from ZurRose do not have a french name)
52
51
  * GTIN
53
52
  GTIN may be 8, 12, 13 or 14 chars long (https://en.wikipedia.org/wiki/Global_Trade_Item_Number)
54
53
  The EAN-8 code is an eight-digit barcode used usually for very small articles, such as a battery for hearing aid, where fitting a larger code onto the item would be difficult
@@ -129,15 +128,6 @@
129
128
  </xs:simpleType>
130
129
  </xs:element>
131
130
 
132
- <xs:element name="DSCRI">
133
- <xs:simpleType>
134
- <xs:restriction base="xs:string">
135
- <xs:minLength value="3" />
136
- <xs:maxLength value="120" />
137
- </xs:restriction>
138
- </xs:simpleType>
139
- </xs:element>
140
-
141
131
  <xs:element name="ART">
142
132
  <xs:complexType>
143
133
  <xs:sequence>
@@ -167,15 +157,12 @@
167
157
  <xs:element ref="ns1:BG"/>
168
158
  </xs:sequence>
169
159
  <xs:element ref="ns1:DSCRD"/>
170
- <xs:element ref="ns1:DSCRF" minOccurs="0" />
171
- <xs:element ref="ns1:DSCRI" minOccurs="0"/>
160
+ <xs:element ref="ns1:DSCRF"/>
172
161
  <xs:element ref="ns1:SORTD"/>
173
- <xs:element ref="ns1:SORTF" minOccurs="0"/>
174
- <xs:element ref="ns1:SORTI" minOccurs="0"/>
162
+ <xs:element ref="ns1:SORTF"/>
175
163
  <xs:sequence minOccurs="0">
176
164
  <xs:element ref="ns1:SYN1D"/>
177
165
  <xs:element ref="ns1:SYN1F"/>
178
- <xs:element ref="ns1:SYN1I"/>
179
166
  <xs:element ref="ns1:SLOPLUS"/>
180
167
  </xs:sequence>
181
168
  <xs:element ref="ns1:ARTCOMP"/>
@@ -258,10 +245,8 @@
258
245
  </xs:element>
259
246
  <xs:element name="SORTD" type="xs:string"/>
260
247
  <xs:element name="SORTF" type="xs:string"/>
261
- <xs:element name="SORTI" type="xs:string"/>
262
248
  <xs:element name="SYN1D" type="xs:string"/>
263
249
  <xs:element name="SYN1F" type="xs:string"/>
264
- <xs:element name="SYN1I" type="xs:string"/>
265
250
  <xs:element name="SLOPLUS">
266
251
  <xs:simpleType>
267
252
  <xs:restriction base="xs:byte">
@@ -361,10 +346,8 @@
361
346
  <xs:element ref="ns1:QTYMD"/>
362
347
  <xs:element ref="ns1:DSCRDMD"/>
363
348
  <xs:element ref="ns1:DSCRFMD"/>
364
- <xs:element ref="ns1:DSCRIMD"/>
365
349
  <xs:element ref="ns1:SORTDMD"/>
366
350
  <xs:element ref="ns1:SORTFMD"/>
367
- <xs:element ref="ns1:SORTIMD"/>
368
351
  <xs:sequence minOccurs="0">
369
352
  <xs:element ref="ns1:SYN1DMD"/>
370
353
  <xs:element ref="ns1:SYN1FMD"/>
@@ -416,10 +399,8 @@
416
399
  </xs:element>
417
400
  <xs:element name="SORTDMD" type="xs:string"/>
418
401
  <xs:element name="SORTFMD" type="xs:string"/>
419
- <xs:element name="SORTIMD" type="xs:string"/>
420
402
  <xs:element name="SYN1DMD" type="xs:string"/>
421
403
  <xs:element name="SYN1FMD" type="xs:string"/>
422
- <xs:element name="SYN1IMD" type="xs:string"/>
423
404
  <xs:element name="SLOPLUSMD">
424
405
  <xs:simpleType>
425
406
  <xs:restriction base="xs:byte">
@@ -741,7 +722,6 @@
741
722
  <xs:element ref="ns1:LIMNIV"/>
742
723
  <xs:element name="DSCRD" type="xs:string"/>
743
724
  <xs:element name="DSCRF" type="xs:string"/>
744
- <xs:element name="DSCRI" type="xs:string"/>
745
725
  <xs:element ref="ns1:VDAT"/>
746
726
  </xs:sequence>
747
727
  <xs:attribute name="DT" use="required"/>
@@ -800,7 +780,6 @@
800
780
  <xs:element ref="ns1:LIMNIVMD"/>
801
781
  <xs:element name="DSCRDMD" type="xs:string"/>
802
782
  <xs:element name="DSCRFMD" type="xs:string"/>
803
- <xs:element name="DSCRIMD" type="xs:string"/>
804
783
  <xs:element ref="ns1:VDATMD"/>
805
784
  </xs:sequence>
806
785
  <xs:attribute name="DT" use="required"/>
@@ -865,8 +844,7 @@
865
844
  <xs:element minOccurs="0" ref="ns1:PRODNO"/>
866
845
  <xs:sequence minOccurs="0">
867
846
  <xs:element ref="ns1:DSCRD"/>
868
- <xs:element ref="ns1:DSCRF" minOccurs="0"/>
869
- <xs:element ref="ns1:DSCRI" minOccurs="0"/>
847
+ <xs:element ref="ns1:DSCRF"/>
870
848
  </xs:sequence>
871
849
  <xs:element minOccurs="0" ref="ns1:ADINFD"/>
872
850
  <xs:element minOccurs="0" ref="ns1:ADINFF"/>
@@ -942,7 +920,6 @@
942
920
  <xs:sequence minOccurs="0">
943
921
  <xs:element ref="ns1:DSCRDMD"/>
944
922
  <xs:element ref="ns1:DSCRFMD"/>
945
- <xs:element ref="ns1:DSCRIMD"/>
946
923
  </xs:sequence>
947
924
  <xs:element minOccurs="0" ref="ns1:ADINFDMD"/>
948
925
  <xs:element minOccurs="0" ref="ns1:ADINFFMD"/>
@@ -1111,7 +1088,6 @@
1111
1088
  <xs:element name="ITMD" type="xs:string"/>
1112
1089
  <xs:element name="DSCRDMD" type="xs:string"/>
1113
1090
  <xs:element name="DSCRFMD" type="xs:string"/>
1114
- <xs:element name="DSCRIMD" type="xs:string"/>
1115
1091
  <xs:element name="VDATMD" type="xs:NMTOKEN"/>
1116
1092
  <xs:element name="RESULTMD">
1117
1093
  <xs:complexType>
data/oddb_calc.xsd CHANGED
File without changes
@@ -11,7 +11,7 @@ describe Oddb2xml::Builder do
11
11
  expect(@inhalt).not_to be nil
12
12
  unless @inhalt.index(expected_value)
13
13
  puts expected_value
14
- binding.pry # TODO: Must not be active in production!!
14
+ # binding.pry # TODO: Must not be active in production!!
15
15
  end
16
16
  expect(@inhalt.index(expected_value)).not_to be nil
17
17
  end
@@ -75,11 +75,12 @@ describe Oddb2xml::Builder do
75
75
  expect(@inhalt.index(expected)).not_to be nil
76
76
  end
77
77
 
78
- it "should have a ATC for product PRIORIX TETRA" do
78
+ it "should have a DSCRF and ATC for product PRIORIX TETRA" do
79
79
  expected = %(<PRODUCT>
80
80
  <PRODNO>5815801</PRODNO>
81
81
  <SALECD>A</SALECD>
82
82
  <DSCR>PRIORIX TETRA Trockensub c Solv Fertspr</DSCR>
83
+ <DSCRF>Priorix-Tetra, Pulver und Lösungsmittel zur Herstellung einer Injektionslösung</DSCRF>
83
84
  <ATC>J07BD54</ATC>
84
85
  </PRODUCT>)
85
86
  expect(@inhalt.index(expected)).not_to be nil
@@ -118,6 +119,7 @@ describe Oddb2xml::Builder do
118
119
  <PRODNO>5559401</PRODNO>
119
120
  <SALECD>A</SALECD>
120
121
  <DSCR>Nutriflex Lipid plus, Infusionsemulsion, 1250ml</DSCR>
122
+ <DSCRF/>
121
123
  <ATC>B05BA10</ATC>
122
124
  </PRODUCT>)
123
125
  expect(@inhalt.index(expected)).not_to be nil
@@ -244,6 +246,7 @@ describe Oddb2xml::Builder do
244
246
  <PHAR>0055805</PHAR>
245
247
  <SALECD>A</SALECD>
246
248
  <DSCR>TENSOPLAST Kompressionsbinde 5cmx4.5m</DSCR>
249
+ <DSCRF/>
247
250
  <PEXF>0.00</PEXF>
248
251
  <PPUB>22.95</PPUB>
249
252
  </ITEM>),
@@ -458,12 +461,14 @@ describe Oddb2xml::Builder do
458
461
  <!--Chapter70 hack prodno 2069639 Ceres Urtinkturen gemäss L2 mit - im Kommentar-->
459
462
  <SALECD>A</SALECD>
460
463
  <DSCR>Ceres Urtinkturen gemäss L2 mit -- im Kommentar</DSCR>
464
+ <DSCRF/>
461
465
  </PRODUCT>),
462
466
  "Chapter 70 item" => %(<ITEM PHARMATYPE="P">
463
467
  <GTIN>2500000588532</GTIN>
464
468
  <PHAR>2069639</PHAR>
465
469
  <SALECD>A</SALECD>
466
470
  <DSCR>EINF ARZNEI Ceres Urtinktur spez 20ml</DSCR>
471
+ <DSCRF/>
467
472
  <PEXF>23.44</PEXF>
468
473
  <PPUB>31.30</PPUB>
469
474
  <!--Chapter70 hack 2500000588532 EINF ARZNEI Ceres Urtinktur spez 20ml-->
@@ -482,6 +487,7 @@ Der behandelnde Arzt ist verpflichtet, die erforderlichen Daten laufend im vorge
482
487
  <PRODNO>1336901</PRODNO>
483
488
  <SALECD>A</SALECD>
484
489
  <DSCR>Pethidin HCl Amino 100 mg/2 ml, Injektionslösung</DSCR>
490
+ <DSCRF/>
485
491
  <ATC>N02AB02</ATC>
486
492
  </PRODUCT>)}
487
493
 
data/spec/builder_spec.rb CHANGED
@@ -35,7 +35,7 @@ ARTICLE_ZURROSE_ELEMENTS = [
35
35
  ["ARTICLE/ART/ARTINS/NINCD", "20"]
36
36
  ]
37
37
 
38
- ARTICLE_NAROPIN = %( <REF_DATA>1</REF_DATA>
38
+ ARTICLE_NAROPIN = %(<REF_DATA>1</REF_DATA>
39
39
  <SMCAT>B</SMCAT>
40
40
  <SMNO>54015011</SMNO>
41
41
  <PRODNO>5401501</PRODNO>
@@ -44,10 +44,8 @@ ARTICLE_NAROPIN = %( <REF_DATA>1</REF_DATA>
44
44
  <BG>N</BG>
45
45
  <DSCRD>NAROPIN Inj Lös 0.2 % 10ml Duofit Amp 5 Stk</DSCRD>
46
46
  <DSCRF>NAROPIN sol inj 0.2 % 10ml amp duofit 5 pce</DSCRF>
47
- <DSCRI>NAROPIN Inj Lös 0.2 % 10ml Duofit Amp 5 Stk</DSCRI>
48
47
  <SORTD>NAROPIN INJ LÖS 0.2 % 10ML DUOFIT AMP 5 STK</SORTD>
49
48
  <SORTF>NAROPIN SOL INJ 0.2 % 10ML AMP DUOFIT 5 PCE</SORTF>
50
- <SORTI>NAROPIN INJ LÖS 0.2 % 10ML DUOFIT AMP 5 STK</SORTI>
51
49
  <ARTCOMP>
52
50
  <COMPNO>7601001402539</COMPNO>
53
51
  </ARTCOMP>
@@ -56,8 +54,7 @@ ARTICLE_NAROPIN = %( <REF_DATA>1</REF_DATA>
56
54
  <BC>7680540150118</BC>
57
55
  <BCSTAT>A</BCSTAT>
58
56
  </ARTBAR>
59
- </ART>
60
- )
57
+ </ART>)
61
58
 
62
59
  ARTICLE_COMMON_ELEMENTS = [
63
60
  ["ARTICLE/ART/REF_DATA", "1"],
@@ -571,10 +568,11 @@ describe Oddb2xml::Builder do
571
568
 
572
569
  it "should generate ATC for 7680002770014" do
573
570
  oddb_product_xml = IO.read(File.join(Oddb2xml::WORK_DIR, "oddb_product.xml"))
574
- text = %(<GTIN>7680002770021</GTIN>
571
+ text = %(<GTIN>7680002770014</GTIN>
575
572
  <PRODNO>0027701</PRODNO>
576
- <DSCRD>Coeur-Vaisseaux Sérocytol, suppositoire</DSCRD>
577
- <ATC>J06AA</ATC>
573
+ <DSCRD>SEROCYTOL Herz-Gefässe Supp 3 Stk</DSCRD>
574
+ <DSCRF>SEROCYTOL Coeur-Vaisseaux supp 3 pce</DSCRF>
575
+ <ATC>J06AA99</ATC>
578
576
  <IT>08.07.</IT>
579
577
  <CPT/>)
580
578
  expect(oddb_product_xml.index(text)).to be >= 1
@@ -585,6 +583,7 @@ describe Oddb2xml::Builder do
585
583
  text2 = %( <GTIN>7680002770021</GTIN>
586
584
  <PRODNO>0027701</PRODNO>
587
585
  <DSCRD>Coeur-Vaisseaux Sérocytol, suppositoire</DSCRD>
586
+ <DSCRF>Coeur-Vaisseaux Sérocytol, suppositoire</DSCRF>
588
587
  <ATC>J06AA</ATC>
589
588
  <IT>08.07.</IT>
590
589
  <CPT/>)
data/spec/calc_spec.rb CHANGED
File without changes
File without changes
data/spec/cli_spec.rb CHANGED
File without changes
data/spec/compare_spec.rb CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/spec/data/atc.csv CHANGED
File without changes