Class: Oddb2xml::FhirExtractor

Inherits:
Extractor show all
Defined in:
lib/oddb2xml/fhir_support.rb

Overview

FHIR Extractor - Compatible with existing BagXmlExtractor

Instance Attribute Summary

Attributes inherited from Extractor

#xml

Instance Method Summary collapse

Constructor Details

#initialize(fhir_file) ⇒ FhirExtractor



568
569
570
# File 'lib/oddb2xml/fhir_support.rb', line 568

def initialize(fhir_file)
  @fhir_file = fhir_file
end

Instance Method Details

#to_hashObject



572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
# File 'lib/oddb2xml/fhir_support.rb', line 572

def to_hash
  data = {}
  Oddb2xml.log "FhirExtractor: Parsing FHIR file #{@fhir_file}"

  # Parse FHIR NDJSON
  result = FhirPreparationsEntry.parse(@fhir_file)

  result.Preparations.Preparation.each do |seq|
    next unless seq
    next if seq.SwissmedicNo5 && seq.SwissmedicNo5.eql?("0")

    # Build item structure matching BagXmlExtractor
    item = {}
    item[:data_origin] = "fhir"
    item[:refdata] = true
    item[:product_key] = nil  # Not available in FHIR
    item[:desc_de] = ""  # Not in FHIR at product level
    item[:desc_fr] = ""
    item[:desc_it] = ""
    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.to_s.rjust(5, "0") : ""
    item[:org_gen_code] = (orgc = seq.OrgGenCode) ? orgc : ""
    item[:deductible] = ""  # Will be set per package based on cost_share
    item[:deductible20] = ""  # Will be set per package based on cost_share  
    item[:atc_code] = (atcc = seq.AtcCode) ? atcc : ""
    item[:comment_de] = ""  # Not available in FHIR
    item[:comment_fr] = ""
    item[:comment_it] = ""
    item[:it_code] = (itc = seq.ItCode) ? itc : ""  # NOW available in FHIR!

    # Build substances array
    item[:substances] = []
    if seq.Substances && seq.Substances.Substance
      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
    end

    item[:pharmacodes] = []
    item[:packages] = {}

    # Process packages
    if seq.Packs && seq.Packs.Pack
      seq.Packs.Pack.each do |pac|
        next unless pac.GTIN

        ean13 = pac.GTIN.to_s

        # Ensure SwissmedicNo8 has leading zeros
        if pac.SwissmedicNo8 && pac.SwissmedicNo8.length < 8
          pac.SwissmedicNo8 = pac.SwissmedicNo8.rjust(8, "0")
        end

        Oddb2xml.setEan13forNo8(pac.SwissmedicNo8, ean13) if pac.SwissmedicNo8

        # Build price structures
        exf = {price: "", valid_date: "", price_code: ""}
        if pac.Prices && pac.Prices.ExFactoryPrice
          exf[:price] = pac.Prices.ExFactoryPrice.Price.to_s if pac.Prices.ExFactoryPrice.Price
          exf[:valid_date] = pac.Prices.ExFactoryPrice.ValidFromDate if pac.Prices.ExFactoryPrice.ValidFromDate
          exf[:price_code] = "PEXF"
        end

        pub = {price: "", valid_date: "", price_code: ""}
        if pac.Prices && pac.Prices.PublicPrice
          pub[:price] = pac.Prices.PublicPrice.Price.to_s if pac.Prices.PublicPrice.Price
          pub[:valid_date] = pac.Prices.PublicPrice.ValidFromDate if pac.Prices.PublicPrice.ValidFromDate
          pub[:price_code] = "PPUB"
        end

        # Build package entry matching BagXmlExtractor structure
        item[:packages][ean13] = {
          ean13: ean13,
          name_de: (name = seq.NameDe) ? name : "",
          name_fr: (name = seq.NameFr) ? name : "",
          name_it: (name = seq.NameIt) ? name : "",
          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}
        }

        # Map limitations from FHIR
        item[:packages][ean13][:limitations] = []
        if pac.Limitations && pac.Limitations.Limitation
          pac.Limitations.Limitation.each do |lim|
            # Calculate is_deleted safely
            is_deleted = false
            if lim.ValidThruDate
              begin
                is_deleted = Date.parse(lim.ValidThruDate) < Date.today
              rescue
                is_deleted = false
              end
            end
            
            item[:packages][ean13][:limitations] << {
              it: item[:it_code],
              key: :swissmedic_number8,
              id: pac.SwissmedicNo8 || "",
              code: lim.LimitationCode || "",
              type: lim.LimitationType || "",
              value: lim.LimitationValue || "",
              niv: lim.LimitationNiveau || "",
              desc_de: lim.DescriptionDe || "",
              desc_fr: lim.DescriptionFr || "",
              desc_it: lim.DescriptionIt || "",
              vdate: lim.ValidFromDate || "",
              del: is_deleted
            }
          end
        end
        item[:packages][ean13][:limitation_points] = ""
        
        # Map cost_share to deductible flags
        if pac.CostShare
          case pac.CostShare
          when 10
            item[:deductible] = "Y"
          when 20
            item[:deductible20] = "Y"
          when 40
            # New value - might need new field or special handling
            item[:deductible] = "Y"  # Fallback to standard deductible
          end
        end

        # Store in data hash with ean13 as key
        data[ean13] = item
      end
    end
  end

  Oddb2xml.log "FhirExtractor: Extracted #{data.size} packages"
  data
end