class Oddb2xml::BagXmlExtractor

Constants

GTIN
SwissmedicNo8

Public Instance Methods

to_hash() click to toggle source
# File lib/oddb2xml/extractor.rb, line 40
def to_hash
  data = {}
  result = PreparationsEntry.parse(@xml.sub(STRIP_FOR_SAX_MACHINE, ""), lazy: true)
  result.Preparations.Preparation.each do |seq|
    if seq.SwissmedicNo5.eql?("0")
      puts "BagXmlExtractor Skipping SwissmedicNo5 0 for #{seq.NameDe} #{seq.DescriptionDe} #{seq.CommentDe}"
      next
    end
    item = {}
    item[:data_origin] = "bag_xml"
    item[:refdata] = true
    item[:product_key] = seq.ProductCommercial
    item[:desc_de] = (desc = seq.DescriptionDe) ? desc : ""
    item[:desc_fr] = (desc = seq.DescriptionFr) ? desc : ""
    item[:desc_it] = (desc = seq.DescriptionIt) ? desc : ""
    item[:name_de] = (name = seq.NameDe) ? name : ""
    item[:name_fr] = (name = seq.NameFr) ? name : ""
    item[:name_it] = (name = seq.NameIt) ? name : ""
    item[:swissmedic_number5] = (num5 = seq.SwissmedicNo5) ? num5.rjust(5, "0") : ""
    item[:org_gen_code] = (orgc = seq.OrgGenCode) ? orgc : ""
    item[:deductible] = (ddbl = seq.FlagSB) ? ddbl : ""
    item[:deductible20] = (ddbl20 = seq.FlagSB20) ? ddbl20 : ""
    item[:atc_code] = (atcc = seq.AtcCode) ? atcc : ""
    item[:comment_de] = (info = seq.CommentDe) ? info : ""
    item[:comment_fr] = (info = seq.CommentFr) ? info : ""
    item[:comment_it] = (info = seq.CommentIt) ? info : ""
    item[:it_code] = ""
    seq.ItCodes.ItCode.each do |itc|
      if item[:it_code].to_s.empty?
        it_code = itc.Code.to_s
        item[:it_code] = /(\d+)\.(\d+)\.(\d+)./.match?(it_code) ? it_code : ""
      end
    end
    item[:substances] = []
    seq.Substances.Substance.each_with_index do |sub, i|
      item[:substances] << {
        index: i.to_s,
        name: (name = sub.DescriptionLa) ? name : "",
        quantity: (qtty = sub.Quantity) ? qtty : "",
        unit: (unit = sub.QuantityUnit) ? unit : ""
      }
    end
    item[:pharmacodes] = []
    item[:packages] = {} # pharmacode => package
    seq.Packs.Pack.each do |pac|
      if pac.SwissmedicNo8 && pac.SwissmedicNo8.length < 8
        puts "BagXmlExtractor: Adding leading zeros for SwissmedicNo8 #{pac.SwissmedicNo8}  BagDossierNo #{pac.BagDossierNo} PackId #{pac.PackId} #{item[:name_de]}" if $VERBOSE
        pac.SwissmedicNo8 = pac.SwissmedicNo8.rjust(8, "0")
      end
      unless pac.GTIN
        if pac.SwissmedicNo8
          ean12 = "7680" + pac.SwissmedicNo8
          pac.GTIN = (ean12 + Oddb2xml.calc_checksum(ean12)) unless @artikelstamm
          # puts "BagXmlExtractor: Missing GTIN in SwissmedicNo8 #{pac.SwissmedicNo8}  BagDossierNo #{pac.BagDossierNo} PackId #{pac.PackId} #{item[:name_de]}."
        else
          puts "BagXmlExtractor: Missing GTIN and SwissmedicNo8 in SwissmedicNo8 #{pac.SwissmedicNo8}  BagDossierNo #{pac.BagDossierNo} PackId #{pac.PackId} #{item[:name_de]}"
          next
        end
      end
      ean13 = pac.GTIN.to_s
      Oddb2xml.setEan13forNo8(pac.SwissmedicNo8, ean13) if pac.SwissmedicNo8
      # packages
      exf = {price: "", valid_date: "", price_code: ""}
      if pac&.Prices&.ExFactoryPrice
        exf[:price] = pac.Prices.ExFactoryPrice.Price if pac.Prices.ExFactoryPrice.Price
        exf[:valid_date] = pac.Prices.ExFactoryPrice.ValidFromDate if pac.Prices.ExFactoryPrice.ValidFromDate
        exf[:price_code] = pac.Prices.ExFactoryPrice.PriceTypeCode if pac.Prices.ExFactoryPrice.PriceTypeCode
      end
      pub = {price: "", valid_date: "", price_code: ""}
      if pac&.Prices&.PublicPrice
        pub[:price] = pac.Prices.PublicPrice.Price if pac.Prices.PublicPrice.Price
        pub[:valid_date] = pac.Prices.PublicPrice.ValidFromDate if pac.Prices.PublicPrice.ValidFromDate
        pub[:price_code] = pac.Prices.PublicPrice.PriceTypeCode if pac.Prices.PublicPrice.PriceTypeCode
      end
      item[:packages][ean13] = {
        ean13: ean13,
        name_de: (desc = seq.NameDe) ? desc : "",
        name_fr: (desc = seq.NameFr) ? desc : "",
        name_it: (desc = seq.NameIt) ? desc : "",
        desc_de: (desc = pac.DescriptionDe) ? desc : "",
        desc_fr: (desc = pac.DescriptionFr) ? desc : "",
        desc_it: (desc = pac.DescriptionIt) ? desc : "",
        sl_entry: true,
        swissmedic_category: (cat = pac.SwissmedicCategory) ? cat : "",
        swissmedic_number8: (num = pac.SwissmedicNo8) ? num : "",
        prices: {exf_price: exf, pub_price: pub}
      }
      # related all limitations
      item[:packages][ean13][:limitations] = []
      limitations = Hash.new { |h, k| h[k] = [] }
      limitations[:seq] = if seq.Limitations
        seq.Limitations.Limitation.collect { |x| x }
      end
      # in it-codes
      if seq&.ItCodes && seq&.ItCodes&.ItCode
        limitations[:itc] = []
        seq.ItCodes.ItCode.each { |x| limitations[:itc] += x.Limitations.Limitation if x.Limitations.Limitation }
      else
        limitations[:itc] = nil
      end
      # in pac
      limitations[:pac] = if pac && pac.Limitations
        (lims = pac.Limitations.Limitation) ? lims.to_a : nil
      end
      limitations.each_pair do |lim_key, lims|
        key = ""
        id = ""
        case lim_key
        when :seq, :itc
          key = :swissmedic_number5
          id = item[key].to_s
        when :pac
          key = :swissmedic_number8
          id = item[:packages][ean13][key].to_s
        end
        if id.empty? && item[:packages][ean13][:swissmedic_number8]
          key = :swissmedic_number8
          id = item[:packages][ean13][key].to_s
        end
        lims&.each do |lim|
          limitation = {
            it: item[:it_code],
            key: key,
            id: id,
            code: (lic = lim.LimitationCode) ? lic : "",
            type: (lit = lim.LimitationType) ? lit : "",
            value: (liv = lim.LimitationValue) ? liv : "",
            niv: (niv = lim.LimitationNiveau) ? niv : "",
            desc_de: (dsc = lim.DescriptionDe) ? dsc : "",
            desc_fr: (dsc = lim.DescriptionFr) ? dsc : "",
            desc_it: (dsc = lim.DescriptionIt) ? dsc : "",
            vdate: (dat = lim.ValidFromDate) ? dat : ""
          }
          deleted = false
          if (upto = ((thr = lim.ValidThruDate) ? thr : nil)) &&
              upto =~ (/\d{2}\.\d{2}\.\d{2}/)
            begin
              deleted = true if Date.strptime(upto, "%d.%m.%y") >= Date.today
            rescue ArgumentError
            end
          end
          limitation[:del] = deleted
          item[:packages][ean13][:limitations] << limitation
        end
      end
      # limitation points
      pts = pac.PointLimitations.PointLimitation.first # only first points
      item[:packages][ean13][:limitation_points] = pts ? pts.Points : ""
      if pac.SwissmedicNo8
        ean12 = "7680" + pac.SwissmedicNo8
        correct_ean13 = ean12 + Oddb2xml.calc_checksum(ean12)
        unless pac.GTIN.eql?(correct_ean13)
          puts "pac.GTIN #{pac.GTIN} should be #{correct_ean13}"
          item[:packages][ean13][:CORRECT_EAN13] = correct_ean13
        end
      end
      data[ean13] = item
    end
  end
  data
end