Class: Oddb2xml::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/oddb2xml/builder.rb

Constant Summary collapse

Data_dir =
File.expand_path(File.join(File.dirname(__FILE__),'..','..', 'data'))
@@article_overrides =
YAML.load_file(File.join(Data_dir, 'article_overrides.yaml'))
@@product_overrides =
YAML.load_file(File.join(Data_dir, 'product_overrides.yaml'))
@@ignore_file =
File.join(Data_dir, 'gtin2ignore.yaml')
@@gtin2ignore =
YAML.load_file(@@ignore_file)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Builder

Returns a new instance of Builder.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/oddb2xml/builder.rb', line 50

def initialize(args = {})
  @options    = args
  @subject    = nil
  @refdata    = {}
  @items      = {} # Items from Preparations.xml in BAG, using GTINs as key
  @flags      = {}
  @lppvs      = {}
  @infos      = {}
  @packs      = {}
  @migel      = {}
  @infos_zur_rose  ||= {}
  @actions    = []
  @orphan    = []
  @ean14      = false
  @companies  = []
  @people     = []
  @tag_suffix = nil
  @pharmacode = {} # index pharmacode => item
  if block_given?
    yield self
  end
end

Instance Attribute Details

#actionsObject

Returns the value of attribute actions.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def actions
  @actions
end

#companiesObject

Returns the value of attribute companies.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def companies
  @companies
end

#ean14Object

Returns the value of attribute ean14.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def ean14
  @ean14
end

#flagsObject

Returns the value of attribute flags.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def flags
  @flags
end

#infosObject

Returns the value of attribute infos.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def infos
  @infos
end

#infos_zur_roseObject

Returns the value of attribute infos_zur_rose.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def infos_zur_rose
  @infos_zur_rose
end

#itemsObject

Returns the value of attribute items.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def items
  @items
end

#lppvsObject

Returns the value of attribute lppvs.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def lppvs
  @lppvs
end

#migelObject

Returns the value of attribute migel.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def migel
  @migel
end

#orphanObject

Returns the value of attribute orphan.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def orphan
  @orphan
end

#packsObject

Returns the value of attribute packs.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def packs
  @packs
end

#peopleObject

Returns the value of attribute people.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def people
  @people
end

#refdataObject

Returns the value of attribute refdata.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def refdata
  @refdata
end

#subjectObject

Returns the value of attribute subject.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def subject
  @subject
end

#tag_suffixObject

Returns the value of attribute tag_suffix.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def tag_suffix
  @tag_suffix
end

#xsdObject

Returns the value of attribute xsd.



44
45
46
# File 'lib/oddb2xml/builder.rb', line 44

def xsd
  @xsd
end

Instance Method Details

#check_name(obj, lang = :de) ⇒ Object

No. Marco did not filter it, eg. 8804121 in rtikelstamm_oddb2xml_051217_v5.xm



1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
# File 'lib/oddb2xml/builder.rb', line 1371

def check_name(obj, lang = :de)
  ean = obj[:ean13]
  refdata = @refdata[ean]
  if lang == :de
    name = (refdata && refdata[:desc_de]) ? refdata[:desc_de] : obj[:sequence_name]
  elsif lang == :fr
    name = (refdata && refdata[:desc_fr]) ? refdata[:desc_fr] : obj[:sequence_name]
  else
    return false
  end
  return false if !name || name.empty? || name.length < 3
  name
end

#emit_items(xml) ⇒ Object



1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
# File 'lib/oddb2xml/builder.rb', line 1400

def emit_items(xml)
  nr_items = 0
  gtins_to_article = {}
  @articles.each {|article| gtins_to_article[article[:ean13]] = article }
  gtins = gtins_to_article.keys + @infos_zur_rose.keys + @packs.values.collect{|x| x[:ean13]}
  gtins = (gtins-@@gtin2ignore)
  gtins.sort!.uniq!
  @nr_items = gtins.size
  gtins.each do |ean13|
    pac,no8 = nil,ean13.to_s[4..11] # BAG-XML(SL/LS)
    next if ean13 == 0
    obj = gtins_to_article[ean13] || @infos_zur_rose[ean13]
    if obj
      obj = @packs[no8].merge(obj) if @packs[no8]
    else
      obj = @packs[no8] # obj not yet in refdata. Use data from swissmedic_package.xlsx
    end
    nr_items += 1
    Oddb2xml.log "build_article #{nr_items} of #{gtins.size} articles" if nr_items % 5000 == 0
    item = @items[ean13]
    pack_info = nil
    pack_info = @packs[no8] if no8 && /#{ean13}/.match(@packs[no8].to_s) # info from Packungen.xlsx from swissmedic_info
    next if pack_info && /Tierarzneimittel/.match(pack_info[:list_code])
    next if obj[:desc_de] && /ad us vet/i.match(obj[:desc_de])
    sequence    = obj[:seq]
    unless sequence
      if  @packs[no8] && /#{ean13}/.match(@packs[no8].to_s)
        sequence = {:packages =>{ean13 => @packs[no8]}}
        obj[:seq] = sequence.clone
      end
    end
    if no8
      ppac = ((_ppac = pack_info and !_ppac[:is_tier]) ? _ppac : nil)
    end
    if sequence
      unless obj[:seq][:packages].keys.index(ean13)
        # puts "unable to find  #{ean13} in #{obj[:seq][:packages].keys}"
        next
      end
      sequence[:packages].each do |gtin, package|
        pkg_gtin = package[:ean13].clone
        pharma_code = @refdata[pkg_gtin]
        if @refdata[pkg_gtin] && @refdata[pkg_gtin][:pharmacode]
          pharma_code = @refdata[pkg_gtin][:pharmacode]
        else
          pharma_code = obj[:pharmacode]
        end
# 
        info = @calc_items[pkg_gtin]
        if @@emitted_v5_gtins.index(pkg_gtin)
          next
        else
          @@emitted_v5_gtins << pkg_gtin.clone
        end
        options = {'PHARMATYPE' => 'P'}
        xml.ITEM(options) do
          name = (@refdata[pkg_gtin] ? @refdata[pkg_gtin][:desc_de] : nil) || obj[:desc_de] || obj[:sequence_name]
          xml.GTIN pkg_gtin.to_s.rjust(13, '0')
          override(xml, pkg_gtin, :PHAR, pharma_code)
          xml.SALECD('A')
          # maxLength for DSCR is 50 for Artikelstamm v3
          xml.DSCR(name) # for description for zur_rose
          xml.DSCRF(obj[:desc_fr] || '--missing--')
          xml.COMP  do # Manufacturer
            xml.NAME  obj[:company_name]
            xml.GLN   obj[:company_ean]
          end
          pexf = ppub = nil
          if package[:prices]
            pexf ||= package[:prices][:exf_price][:price]
            ppub ||= package[:prices][:pub_price][:price]
          elsif @items[ean13] &&  @items[ean13][:packages] && @items[ean13][:packages][ean13] && (bag_prices = @items[ean13][:packages][ean13][:prices])
            pexf ||= bag_prices[:exf_price][:price]
            ppub ||= bag_prices[:pub_price][:price]
          else
            pexf ||= obj[:price]
            ppub ||= obj[:pub_price]
          end
          ppub = nil if ppub && ppub.size == 0
          pexf = nil if pexf && pexf.size == 0
          xml.PEXF pexf if pexf
          xml.PPUB ppub if ppub
          measure = ''
          if info
            # MEASSURE Measurement Unit,e.g. Pills or milliliters
            #             <DSCR>HIRUDOID Creme 3 mg/g 40 g</DSCR>
            xml.PKG_SIZE info.pkg_size.to_i if info.pkg_size
            if info.measure
              measure = info.measure
            elsif info.pkg_size && info.unit
              measure = info.pkg_size + ' ' + info.unit
            elsif info.pkg_size
              measure = info.pkg_size
            end
            xml.MEASURE   measure
            xml.MEASUREF  measure
            # Die Darreichungsform dieses Items. zB Tablette(n) oder Spritze(n)
            xml.DOSAGE_FORM  info.galenic_form.descriptions['de'] if info.galenic_form.descriptions['de']
            xml.DOSAGE_FORMF info.galenic_form.descriptions['fr'] if info.galenic_form.descriptions['fr']
          end
          xml.SL_ENTRY          'true' if  @items[pkg_gtin]
          xml.IKSCAT            package[:swissmedic_category] if package[:swissmedic_category] && package[:swissmedic_category].length > 0
          xml.GENERIC_TYPE sequence[:org_gen_code] if sequence[:org_gen_code] && !sequence[:org_gen_code].empty?
          xml.LPPV              'true' if @lppvs[pkg_gtin.to_s] # detect_nincd
          case item[:deductible]
          when 'Y'; xml.DEDUCTIBLE 20; # 20%
          when 'N'; xml.DEDUCTIBLE 10; # 10%
          else #     xml.DEDUCTIBLE '' # k.A.
          end if item && item[:deductible]
          xml.PRODNO            ppac[:prodno] if ppac && ppac[:prodno] # pkg_gtin.to_s[4..11]
          csv = []
          @csv_file << [pkg_gtin, name, package[:unit], measure,
                        pexf ? pexf : '',
                        ppub ? ppub : '',
                        package[:prodno],  package[:atc_code], package[:substance_swissmedic],
                        sequence[:org_gen_code],  package[:ith_swissmedic],
                        @items[pkg_gtin] ? 'SL' : '',
                        ]
        end
      end
    else # non pharma
       @csv_file << [ ean13, (obj[:desc_de] || obj[:description]), '', '',
                    obj[:price], obj[:pub_price], '', '', '', '', '', '' ]
      if @@emitted_v5_gtins.index(ean13)
        next
      else
        @@emitted_v5_gtins << ean13.clone
      end
      # Set the pharmatype to 'Y' for outdated products, which are no longer found
      # in refdata/packungen
      patched_pharma_type = (/^7680/.match(ean13.to_s.rjust(13, '0')) ? 'P': 'N' )
      xml.ITEM({'PHARMATYPE' => patched_pharma_type }) do
        xml.GTIN ean13.to_s.rjust(13, '0')
        xml.PHAR obj[:pharmacode]
        emit_salecd(xml, ean13, obj)
        xml.DSCR(obj[:desc_de] || obj[:description]) # for description for zur_rose
        xml.DSCRF(obj[:desc_fr] || '--missing--')
        xml.COMP  do
          xml.GLN obj[:company_ean]
        end if obj[:company_ean] && !obj[:company_ean].empty?
        xml.PEXF obj[:price]      if obj[:price] && !obj[:price].empty?
        xml.PPUB obj[:pub_price]  if obj[:pub_price] && !obj[:pub_price].empty?
      end
    end
  end
  @csv_file.close if @csv_file && !@csv_file.closed?
  nr_items
end

#emit_substance(xml, substance, emit_active = false) ⇒ Object



724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
# File 'lib/oddb2xml/builder.rb', line 724

def emit_substance(xml, substance, emit_active=false)
    xml.MORE_INFO substance.more_info if substance.more_info
    xml.SUBSTANCE_NAME substance.name
    xml.IS_ACTIVE_AGENT substance.is_active_agent if emit_active
    if substance.dose
      if substance.qty.is_a?(Float) or substance.qty.is_a?(Integer)
        xml.QTY  substance.qty
        xml.UNIT substance.unit
      else
        xml.DOSE_TEXT substance.dose.to_s
      end
    end
    if substance.chemical_substance
      xml.CHEMICAL_SUBSTANCE {
        emit_substance(xml, substance.chemical_substance)
      }
    end
    if substance.salts and substance.salts.size > 0
      xml.SALTS do
        substance.salts.each do |salt|
          xml.SALT do
            emit_substance(xml, salt)
          end
        end
      end
    end
end

#override(xml, id, field, default_value) ⇒ Object



1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
# File 'lib/oddb2xml/builder.rb', line 1384

def override(xml, id, field, default_value)
  has_overrides =  /\d{13}/.match(id.to_s) ? @@article_overrides[id.to_i] : @@product_overrides[id.to_i]
  unless (has_overrides && has_overrides[field.to_s])
    cmd = "xml.#{field} \"#{default_value.to_s.gsub('"','')}\""
  else
    new_value = has_overrides[field.to_s]
    if new_value.to_s.eql?(default_value.to_s)
      xml.comment('obsolete override')
      cmd = "xml.#{field} \"#{new_value}\""
    else
      xml.comment("override #{default_value.to_s} with")
      cmd ="xml.#{field} \"#{new_value}\""
    end
  end
  eval cmd if default_value
end

#to_dat(subject = nil) ⇒ Object



80
81
82
83
84
85
86
87
# File 'lib/oddb2xml/builder.rb', line 80

def to_dat(subject=nil)
  Oddb2xml.log  "to_dat subject #{subject ? subject.to_s :  @subject.to_s} for #{self.class}"
  if subject
    self.send('build_' + subject.to_s)
  elsif @subject
    self.send('build_' + @subject.to_s)
  end
end

#to_xml(subject = nil) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/oddb2xml/builder.rb', line 72

def to_xml(subject=nil)
  Oddb2xml.log "to_xml subject #{subject || @subject}"
  if subject
    self.send('build_' + subject.to_s)
  elsif @subject
    self.send('build_' + @subject.to_s)
  end
end