oddb2xml 1.3.5 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ === 1.3.6 / 08.02.2013
2
+
3
+ * Update article SMCAT as only value from Packungen
4
+ * Change product data definition
5
+ * Base is swissINDEX
6
+
1
7
  === 1.3.5 / 07.02.2013
2
8
 
3
9
  * Update ID of limitation.xml
@@ -58,26 +58,26 @@ module Oddb2xml
58
58
  @articles = nil if reset
59
59
  unless @articles
60
60
  @articles = [] # base is 'DE'
61
- @index['DE'].each_pair do |pharmacode, index|
62
- object = {
63
- :de => index,
64
- :fr => @index['FR'][pharmacode],
61
+ @index['DE'].each_pair do |phar, indices|
62
+ obj = {
63
+ :de => indices,
64
+ :fr => @index['FR'][phar],
65
65
  }
66
- if migel = @migel[pharmacode]
66
+ if migel = @migel[phar]
67
67
  # delete duplicates
68
- @migel[pharmacode] = nil
68
+ @migel[phar] = nil
69
69
  end
70
- if seq = @items[pharmacode]
71
- object[:seq] = seq
70
+ if seq = @items[phar]
71
+ obj[:seq] = seq
72
72
  end
73
- @articles << object
73
+ @articles << obj
74
74
  end
75
75
  # add
76
76
  @migel.values.compact.each do |migel|
77
77
  next if migel[:pharmacode].empty?
78
- object = {}
78
+ obj = {}
79
79
  %w[de fr].each do |lang|
80
- pac = {
80
+ entry = {
81
81
  :ean => migel[:ean],
82
82
  :pharmacode => migel[:pharmacode],
83
83
  :status => 'I',
@@ -89,9 +89,9 @@ module Oddb2xml
89
89
  :company_ean => migel[:company_ean],
90
90
  :company_name => migel[:company_name],
91
91
  }
92
- object[lang.intern] = pac
92
+ obj[lang.intern] = [entry]
93
93
  end
94
- @articles << object
94
+ @articles << obj
95
95
  end
96
96
  end
97
97
  end
@@ -144,38 +144,41 @@ module Oddb2xml
144
144
  def prepare_products
145
145
  unless @products
146
146
  @products = []
147
- @products = @items.values.uniq.map do |seq|
148
- %w[de fr].each do |lang|
149
- # Values come from swissINDEX and Packungen.xls
150
- # * company_name
151
- # * atc_code
152
- # * it_code
153
- it_code = ''
154
- if ppac = @packs[seq[:swissmedic_number5]]
155
- ht_code = ppac[:ith_swissmedic]
156
- end
157
- name_key = "company_name_#{lang}".intern
158
- seq[name_key] = ''
159
- indices = @index[lang.upcase]
160
- seq[:packages].each_pair do |phar, pac|
161
- if index = indices[phar]
162
- if seq[name_key].empty?
163
- seq[name_key] = index[:company_name]
164
- end
165
- if it_code.empty? and
166
- num = pac[:swissmedic_number8] and
167
- ppac = @packs[num]
168
- it_code = ppac[:ith_swissmedic]
147
+ @index['DE'].each_pair do |phar, indices|
148
+ indices.each_with_index do |index, i|
149
+ obj = {}
150
+ obj = {
151
+ :ean => index[:ean],
152
+ :atc => index[:atc_code],
153
+ # additional tags
154
+ :ith => '',
155
+ :seq => @items[phar],
156
+ :pac => nil,
157
+ :no8 => nil,
158
+ :de => index,
159
+ :fr => @index['FR'][phar][i],
160
+ :st => index[:status],
161
+ }
162
+ if obj[:seq] and obj[:pac] = obj[:seq][:packages][phar]
163
+ obj[:no8] = obj[:pac][:swissmedic_number8].to_s
164
+ obj[:atc] = obj[:pac][:atc_code].to_s
165
+ obj[:ith] = obj[:pac][:it_code].to_s # first one
166
+ unless obj[:ean]
167
+ if obj[:no8] and ppac = @packs[obj[:no8].intern] # Packungen.xls
168
+ obj[:ean] = ppac[:ean].to_s
169
+ obj[:atc] = ppac[:atc_code].to_s
170
+ obj[:ith] = ppac[:ith_swissmedic].to_s
171
+ obj[:st] = 'I'
169
172
  end
170
- seq[:atc_code] = index[:atc_code]
171
- seq[:it_code] = it_code
172
- seq[:packages][phar][:ean] = index[:ean]
173
173
  end
174
174
  end
175
+ if obj[:ean][0..3] == '7680'
176
+ @products << obj
177
+ end
175
178
  end
176
- seq
177
179
  end
178
180
  end
181
+ @products
179
182
  end
180
183
  def build_substance
181
184
  prepare_substances
@@ -369,13 +372,15 @@ module Oddb2xml
369
372
  'PROD_DATE' => datetime,
370
373
  'VALID_DATE' => datetime,
371
374
  ) {
375
+ list = []
372
376
  length = 0
373
- @products.each do |seq|
374
- seq[:packages].each_value do |pac|
375
- next if !pac[:ean] or pac[:ean].empty?
376
- length += 1
377
- xml.PRD('DT' => '') {
378
- xml.GTIN pac[:ean]
377
+ @products.each do |obj|
378
+ seq = obj[:seq]
379
+ next unless seq # option
380
+ length += 1
381
+ xml.PRD('DT' => '') {
382
+ xml.GTIN obj[:ean].to_s
383
+ if seq
379
384
  %w[de fr].each do |l|
380
385
  name = "name_#{l}".intern
381
386
  desc = "desc_#{l}".intern
@@ -383,73 +388,77 @@ module Oddb2xml
383
388
  if !seq[name].empty? and !seq[desc].empty?
384
389
  xml.send(elem, seq[name] + ' ' + seq[desc])
385
390
  elsif !seq[desc].empty?
386
- xml.send(elem, seq[desc])
391
+ xml.send(elem, [desc])
387
392
  end
388
393
  end
389
- #xml.BNAMD
390
- #xml.BNAMF
391
- #xml.ADNAMD
392
- #xml.ADNAMF
393
- #xml.SIZE
394
+ end
395
+ #xml.BNAMD
396
+ #xml.BNAMF
397
+ #xml.ADNAMD
398
+ #xml.ADNAMF
399
+ #xml.SIZE
400
+ if seq
394
401
  xml.ADINFD seq[:comment_de] unless seq[:comment_de].empty?
395
402
  xml.ADINFF seq[:comment_fr] unless seq[:comment_fr].empty?
396
403
  xml.GENCD seq[:org_gen_code] unless seq[:org_gen_code].empty?
397
- #xml.GENGRP
398
- xml.ATC seq[:atc_code] unless seq[:atc_code].empty?
399
- xml.IT seq[:it_code] unless seq[:it_code].empty?
400
- #xml.ITBAG
401
- #xml.KONO
402
- #xml.TRADE
403
- #xml.PRTNO
404
- #xml.MONO
405
- #xml.CDGALD
406
- #xml.CDGALF
407
- #xml.FORMD
408
- #xml.FORMF
409
- #xml.DOSE
410
- #xml.DOSEU
411
- #xml.DRGFD
412
- #xml.DRGFF
413
- pac[:swissmedic_number8] =~ /(\d{5})(\d{3})/
414
- if @orphans.include?($1.to_s)
415
- xml.ORPH true
416
- end
417
- #xml.BIOPHA
418
- #xml.BIOSIM
419
- #xml.BFS
420
- #xml.BLOOD
421
- #xml.MSCD # always empty
422
- #xml.DEL
423
- xml.CPT {
424
- #xml.CPTLNO
425
- #xml.CNAMED
426
- #xml.CNAMEF
427
- #xml.IDXIND
428
- #xml.DDDD
429
- #xml.DDDU
430
- #xml.DDDA
431
- #xml.IDXIA
432
- #xml.IXREL
433
- #xml.GALF
434
- #xml.DRGGRPCD
435
- #xml.PRBSUIT
436
- #xml.CSOLV
437
- #xml.CSOLVQ
438
- #xml.CSOLVQU
439
- #xml.PHVAL
440
- #xml.LSPNSOL
441
- #xml.APDURSOL
442
- #xml.EXCIP
443
- #xml.EXCIPQ
444
- #xml.EXCIPCD
445
- #xml.EXCIPCF
446
- #xml.PQTY
447
- #xml.PQTYU
448
- #xml.SIZEMM
449
- #xml.WEIGHT
450
- #xml.LOOKD
451
- #xml.LOOKF
452
- #xml.IMG2
404
+ end
405
+ #xml.GENGRP
406
+ xml.ATC obj[:atc] unless obj[:atc].empty?
407
+ xml.IT obj[:ith] unless obj[:ith].empty?
408
+ #xml.ITBAG
409
+ #xml.KONO
410
+ #xml.TRADE
411
+ #xml.PRTNO
412
+ #xml.MONO
413
+ #xml.CDGALD
414
+ #xml.CDGALF
415
+ #xml.FORMD
416
+ #xml.FORMF
417
+ #xml.DOSE
418
+ #xml.DOSEU
419
+ #xml.DRGFD
420
+ #xml.DRGFF
421
+ obj[:no8] =~ /(\d{5})(\d{3})/
422
+ if @orphans.include?($1.to_s)
423
+ xml.ORPH true
424
+ end
425
+ #xml.BIOPHA
426
+ #xml.BIOSIM
427
+ #xml.BFS
428
+ #xml.BLOOD
429
+ #xml.MSCD # always empty
430
+ #xml.DEL
431
+ xml.CPT {
432
+ #xml.CPTLNO
433
+ #xml.CNAMED
434
+ #xml.CNAMEF
435
+ #xml.IDXIND
436
+ #xml.DDDD
437
+ #xml.DDDU
438
+ #xml.DDDA
439
+ #xml.IDXIA
440
+ #xml.IXREL
441
+ #xml.GALF
442
+ #xml.DRGGRPCD
443
+ #xml.PRBSUIT
444
+ #xml.CSOLV
445
+ #xml.CSOLVQ
446
+ #xml.CSOLVQU
447
+ #xml.PHVAL
448
+ #xml.LSPNSOL
449
+ #xml.APDURSOL
450
+ #xml.EXCIP
451
+ #xml.EXCIPQ
452
+ #xml.EXCIPCD
453
+ #xml.EXCIPCF
454
+ #xml.PQTY
455
+ #xml.PQTYU
456
+ #xml.SIZEMM
457
+ #xml.WEIGHT
458
+ #xml.LOOKD
459
+ #xml.LOOKF
460
+ #xml.IMG2
461
+ if seq
453
462
  seq[:substances].each do |sub|
454
463
  xml.CPTCMP {
455
464
  xml.LINE sub[:index] unless sub[:index].empty?
@@ -468,20 +477,20 @@ module Oddb2xml
468
477
  }
469
478
  end
470
479
  end
471
- #xml.CPTROA {
472
- #xml.SYSLOC
473
- #xml.ROA
474
- #}
475
- }
476
- #xml.PRDICD { # currently empty
477
- #xml.ICD
478
- #xml.RTYP
479
- #xml.RSIG
480
- #xml.REMD
481
- #xml.REMF
480
+ end
481
+ #xml.CPTROA {
482
+ #xml.SYSLOC
483
+ #xml.ROA
482
484
  #}
483
485
  }
484
- end
486
+ #xml.PRDICD { # currently empty
487
+ #xml.ICD
488
+ #xml.RTYP
489
+ #xml.RSIG
490
+ #xml.REMD
491
+ #xml.REMF
492
+ #}
493
+ }
485
494
  end
486
495
  xml.RESULT {
487
496
  xml.OK_ERROR 'OK'
@@ -508,153 +517,152 @@ module Oddb2xml
508
517
  'VALID_DATE' => datetime,
509
518
  ) {
510
519
  @articles.each do |obj|
511
- de_pac = obj[:de] # swiss index DE (base)
512
- fr_pac = obj[:fr] # swiss index FR
513
- bg_pac = nil # BAG XML (additional data)
514
- if obj[:seq]
515
- bg_pac = obj[:seq][:packages][de_pac[:pharmacode]]
516
- end
517
- if de_pac[:ean].length == 13
518
- num = de_pac[:ean][4,8].intern # :swissmedic_number5
519
- elsif bg_pac
520
- num = bg_pac[:swissmedic_number8].intern
521
- end
522
- xml.ART('DT' => '') {
523
- xml.PHAR de_pac[:pharmacode] unless de_pac[:pharmacode].empty?
524
- #xml.GRPCD
525
- #xml.CDS01
526
- #xml.CDS02
527
- #xml.PRDNO
528
- if bg_pac # bag xml
529
- xml.SMCAT bg_pac[:swissmedic_category] unless bg_pac[:swissmedic_category].empty?
530
- elsif @packs[num] and @packs[num][:swissmedic_category] # Packungen.xls
531
- xml.SMCAT @packs[num][:swissmedic_category]
532
- end
533
- if bg_pac
534
- xml.SMNO bg_pac[:swissmedic_number8] unless bg_pac[:swissmedic_number8].empty?
535
- end
536
- #xml.HOSPCD
537
- #xml.CLINCD
538
- #xml.ARTTYP
539
- #xml.VAT
540
- if de_pac
541
- xml.SALECD de_pac[:status].empty? ? 'N' : de_pac[:status]
542
- end
543
- if bg_pac
544
- #xml.INSLIM
545
- xml.LIMPTS bg_pac[:limitation_points] unless bg_pac[:limitation_points].empty?
546
- end
547
- #xml.GRDFR
548
- if bg_pac
549
- if !bg_pac[:swissmedic_number8].empty? and
550
- bg_pac[:swissmedic_number8].to_s =~ /(\d{5})(\d{3})/
551
- xml.COOL 1 if @fridges.include?($1.to_s)
552
- end
553
- end
554
- #xml.TEMP
555
- unless de_pac[:ean].empty?
556
- flag = @flags[de_pac[:ean]]
557
- # as same flag
558
- xml.CDBG (flag ? 'Y' : 'N')
559
- xml.BG (flag ? 'Y' : 'N')
560
- end
561
- #xml.EXP
562
- xml.QTY de_pac[:additional_desc] unless de_pac[:additional_desc].empty?
563
- xml.DSCRD de_pac[:desc] unless de_pac[:desc].empty?
564
- xml.DSCRF fr_pac[:desc] unless fr_pac[:desc].empty?
565
- xml.SORTD de_pac[:desc].upcase unless de_pac[:desc].empty?
566
- xml.SORTF fr_pac[:desc].upcase unless fr_pac[:desc].empty?
567
- #xml.QTYUD
568
- #xml.QTYUF
569
- #xml.IMG
570
- #xml.IMG2
571
- #xml.PCKTYPD
572
- #xml.PCKTYPF
573
- #xml.MULT
574
- if obj[:seq]
575
- xml.SYN1D obj[:seq][:name_de] unless obj[:seq][:name_de].empty?
576
- xml.SYN1F obj[:seq][:name_fr] unless obj[:seq][:name_fr].empty?
577
- end
520
+ obj[:de].each_with_index do |de_idx, i|
521
+ fr_idx = obj[:fr][i] # swiss index FR
522
+ pac,no8 = nil,nil # BAG XML (additional data)
523
+ ppac = nil # Packungen
578
524
  if obj[:seq]
579
- case obj[:seq][:deductible]
580
- when 'Y'; xml.SLOPLUS 1; # 20%
581
- when 'N'; xml.SLOPLUS 2; # 10%
582
- else xml.SLOPLUS '' # k.A.
525
+ pac = obj[:seq][:packages][de_idx[:pharmacode]]
526
+ if pac
527
+ no8 = pac[:swissmedic_number8].intern
528
+ ppac = @packs[no8]
583
529
  end
584
530
  end
585
- #xml.NOPCS
586
- #xml.HSCD
587
- #xml.MINI
588
- #xml.DEPCD
589
- #xml.DEPOT
590
- #xml.BAGSL
591
- #xml.BAGSLC
592
- #xml.LOACD
593
- if de_pac[:status] == "I"
594
- xml.OUTSAL de_pac[:stat_date] unless de_pac[:stat_date].empty?
595
- end
596
- #xml.STTOX
597
- #xml.NOTI
598
- #xml.GGL
599
- #xml.CE
600
- #xml.SMDAT
601
- #xml.SMCDAT
602
- #xml.SIST
603
- #xml.ESIST
604
- #xml.BIOCID
605
- #xml.BAGNO
606
- #xml.LIGHT
607
- #xml.DEL
608
- xml.ARTCOMP {
609
- # use ean13(gln) as COMPNO
610
- xml.COMPNO de_pac[:company_ean] unless de_pac[:company_ean].empty?
611
- #xml.ROLE
612
- #xml.ARTNO1
613
- #xml.ARTNO2
614
- #xml.ARTNO3
615
- }
616
- xml.ARTBAR {
617
- xml.CDTYP 'E13'
618
- xml.BC de_pac[:ean] unless de_pac[:ean].empty?
619
- xml.BCSTAT 'A' # P is alternative
620
- #xml.PHAR2
621
- }
622
- #xml.ARTCH {
623
- #xml.PHAR2
624
- #xml.CHTYPE
625
- #xml.LINENO
626
- #xml.NOUNITS
627
- #}
628
- if bg_pac
629
- bg_pac[:prices].each_pair do |key, price|
630
- xml.ARTPRI {
631
- xml.VDAT price[:valid_date] unless price[:valid_date].empty?
632
- xml.PTYP price[:price_code] unless price[:price_code].empty?
633
- xml.PRICE price[:price] unless price[:price].empty?
634
- }
531
+ xml.ART('DT' => '') {
532
+ xml.PHAR de_idx[:pharmacode] unless de_idx[:pharmacode].empty?
533
+ #xml.GRPCD
534
+ #xml.CDS01
535
+ #xml.CDS02
536
+ #xml.PRDNO
537
+ if pac && ppac && ppac[:swissmedic_category]
538
+ xml.SMCAT ppac[:swissmedic_category]
635
539
  end
636
- end
637
- #xml.ARTMIG {
638
- #xml.VDAT
639
- #xml.MIGCD
640
- #xml.LINENO
641
- #}
642
- #xml.ARTDAN {
643
- #xml.CDTYP
644
- #xml.LINENO
645
- #xml.CDVAL
646
- #}
647
- #xml.ARTLIM {
648
- # xml.LIMCD
649
- #}
650
- if @lppvs[de_pac[:ean]]
651
- xml.ARTINS {
652
- #xml.VDAT
653
- #xml.INCD
654
- xml.NINCD 20
540
+ if pac
541
+ xml.SMNO no8.to_s unless no8.to_s.empty?
542
+ end
543
+ #xml.HOSPCD
544
+ #xml.CLINCD
545
+ #xml.ARTTYP
546
+ #xml.VAT
547
+ if de_idx
548
+ xml.SALECD de_idx[:status].empty? ? 'N' : de_idx[:status]
549
+ end
550
+ if pac
551
+ #xml.INSLIM
552
+ xml.LIMPTS pac[:limitation_points] unless pac[:limitation_points].empty?
553
+ end
554
+ #xml.GRDFR
555
+ if pac
556
+ if no8.empty? and
557
+ no8.to_s =~ /(\d{5})(\d{3})/
558
+ xml.COOL 1 if @fridges.include?($1.to_s)
559
+ end
560
+ end
561
+ #xml.TEMP
562
+ unless de_idx[:ean].empty?
563
+ flag = @flags[de_idx[:ean]]
564
+ # as same flag
565
+ xml.CDBG (flag ? 'Y' : 'N')
566
+ xml.BG (flag ? 'Y' : 'N')
567
+ end
568
+ #xml.EXP
569
+ xml.QTY de_idx[:additional_desc] unless de_idx[:additional_desc].empty?
570
+ xml.DSCRD de_idx[:desc] unless de_idx[:desc].empty?
571
+ xml.DSCRF fr_idx[:desc] unless fr_idx[:desc].empty?
572
+ xml.SORTD de_idx[:desc].upcase unless de_idx[:desc].empty?
573
+ xml.SORTF fr_idx[:desc].upcase unless fr_idx[:desc].empty?
574
+ #xml.QTYUD
575
+ #xml.QTYUF
576
+ #xml.IMG
577
+ #xml.IMG2
578
+ #xml.PCKTYPD
579
+ #xml.PCKTYPF
580
+ #xml.MULT
581
+ if obj[:seq]
582
+ xml.SYN1D obj[:seq][:name_de] unless obj[:seq][:name_de].empty?
583
+ xml.SYN1F obj[:seq][:name_fr] unless obj[:seq][:name_fr].empty?
584
+ end
585
+ if obj[:seq]
586
+ case obj[:seq][:deductible]
587
+ when 'Y'; xml.SLOPLUS 1; # 20%
588
+ when 'N'; xml.SLOPLUS 2; # 10%
589
+ else xml.SLOPLUS '' # k.A.
590
+ end
591
+ end
592
+ #xml.NOPCS
593
+ #xml.HSCD
594
+ #xml.MINI
595
+ #xml.DEPCD
596
+ #xml.DEPOT
597
+ #xml.BAGSL
598
+ #xml.BAGSLC
599
+ #xml.LOACD
600
+ if de_idx[:status] == "I"
601
+ xml.OUTSAL de_idx[:stat_date] unless de_idx[:stat_date].empty?
602
+ end
603
+ #xml.STTOX
604
+ #xml.NOTI
605
+ #xml.GGL
606
+ #xml.CE
607
+ #xml.SMDAT
608
+ #xml.SMCDAT
609
+ #xml.SIST
610
+ #xml.ESIST
611
+ #xml.BIOCID
612
+ #xml.BAGNO
613
+ #xml.LIGHT
614
+ #xml.DEL
615
+ xml.ARTCOMP {
616
+ # use ean13(gln) as COMPNO
617
+ xml.COMPNO de_idx[:company_ean] unless de_idx[:company_ean].empty?
618
+ #xml.ROLE
619
+ #xml.ARTNO1
620
+ #xml.ARTNO2
621
+ #xml.ARTNO3
655
622
  }
656
- end
657
- }
623
+ xml.ARTBAR {
624
+ xml.CDTYP 'E13'
625
+ xml.BC de_idx[:ean] unless de_idx[:ean].empty?
626
+ xml.BCSTAT 'A' # P is alternative
627
+ #xml.PHAR2
628
+ }
629
+ #xml.ARTCH {
630
+ #xml.PHAR2
631
+ #xml.CHTYPE
632
+ #xml.LINENO
633
+ #xml.NOUNITS
634
+ #}
635
+ if pac
636
+ pac[:prices].each_pair do |key, price|
637
+ xml.ARTPRI {
638
+ xml.VDAT price[:valid_date] unless price[:valid_date].empty?
639
+ xml.PTYP price[:price_code] unless price[:price_code].empty?
640
+ xml.PRICE price[:price] unless price[:price].empty?
641
+ }
642
+ end
643
+ end
644
+ #xml.ARTMIG {
645
+ #xml.VDAT
646
+ #xml.MIGCD
647
+ #xml.LINENO
648
+ #}
649
+ #xml.ARTDAN {
650
+ #xml.CDTYP
651
+ #xml.LINENO
652
+ #xml.CDVAL
653
+ #}
654
+ #xml.ARTLIM {
655
+ # xml.LIMCD
656
+ #}
657
+ if @lppvs[de_idx[:ean]]
658
+ xml.ARTINS {
659
+ #xml.VDAT
660
+ #xml.INCD
661
+ xml.NINCD 20
662
+ }
663
+ end
664
+ }
665
+ end
658
666
  end
659
667
  xml.RESULT {
660
668
  xml.OK_ERROR 'OK'
@@ -728,18 +736,14 @@ module Oddb2xml
728
736
  info_index[info[:monid]] = i
729
737
  end
730
738
  end
731
- @products.group_by{|seq| seq[:swissmedic_number5] }.
732
- each_pair do |monid, products|
739
+ @products.select{|obj| obj[:seq] }.
740
+ group_by{|obj| obj[:seq][:swissmedic_number5] }.each_pair do |monid, products|
733
741
  if info_index[monid]
734
742
  xml.KP('DT' => '') {
735
743
  xml.MONID monid
736
- products.each do |seq|
737
- seq[:packages].values.each do |pac|
738
- if (pac[:ean] and pac[:ean][0..3] == '7680')
739
- length += 1
740
- xml.GTIN pac[:ean]
741
- end
742
- end
744
+ products.each do |obj|
745
+ xml.GTIN obj[:ean]
746
+ length += 1
743
747
  end
744
748
  # as orphans ?
745
749
  xml.DEL @orphans.include?(monid) ? true : false
@@ -800,68 +804,65 @@ module Oddb2xml
800
804
  prepare_articles
801
805
  rows = []
802
806
  @articles.each do |obj|
803
- row = ''
804
- de_pac = obj[:de]
805
- # Oddb2tdat.parse
806
- if obj[:de][:status] =~ /A|I/
807
- pac,num = nil, nil
808
- if obj[:seq]
809
- pac = obj[:seq][:packages][de_pac[:pharmacode]]
810
- end
811
- # :swissmedic_numbers
812
- if de_pac[:ean].length == 13
813
- num = de_pac[:ean][4,8].intern # :swissmedic_number5
814
- elsif pac
815
- num = pac[:swissmedic_number8].intern
807
+ obj[:de].each_with_index do |idx, i|
808
+ row = ''
809
+ # Oddb2tdat.parse
810
+ if idx[:status] =~ /A|I/
811
+ pac,no8 = nil,nil
812
+ if obj[:seq]
813
+ pac = obj[:seq][:packages][idx[:pharmacode]]
814
+ end
815
+ # :swissmedic_numbers
816
+ if pac
817
+ no8 = pac[:swissmedic_number8].intern
818
+ end
819
+ row << "%#{DAT_LEN[:RECA]}s" % '11'
820
+ row << "%#{DAT_LEN[:CMUT]}s" % if (phar = idx[:pharmacode] and phar.size > 3) # does not check expiration_date
821
+ idx[:status] == "I" ? '3' : '1'
822
+ else
823
+ '3'
824
+ end
825
+ row << "%0#{DAT_LEN[:PHAR]}d" % idx[:pharmacode].to_i
826
+ row << "%-#{DAT_LEN[:ABEZ]}s" % (
827
+ idx[:desc].to_s.gsub(/"/, '') + " " +
828
+ (pac ? pac[:name_de].to_s : '') +
829
+ idx[:additional_desc]
830
+ ).to_s[0, DAT_LEN[:ABEZ]].gsub(/"/, '')
831
+ row << "%#{DAT_LEN[:PRMO]}s" % (pac ? format_price(pac[:prices][:exf_price][:price].to_s) : ('0' * DAT_LEN[:PRMO]))
832
+ row << "%#{DAT_LEN[:PRPU]}s" % (pac ? format_price(pac[:prices][:pub_price][:price].to_s) : ('0' * DAT_LEN[:PRPU]))
833
+ row << "%#{DAT_LEN[:CKZL]}s" % if (@lppvs[idx[:ean]])
834
+ '2'
835
+ elsif pac # sl_entry
836
+ '1'
837
+ else
838
+ '3'
839
+ end
840
+ row << "%#{DAT_LEN[:CLAG]}s" % if ((no8 && no8.to_s =~ /(\d{5})(\d{3})/) and
841
+ @fridges.include?($1.to_s))
842
+ '1'
843
+ else
844
+ '0'
845
+ end
846
+ row << "%#{DAT_LEN[:CBGG]}s" % if ((pac && pac[:narcosis_flag] == 'Y') or # BAGXml
847
+ (@flags[idx[:ean]])) # ywesee BM_update
848
+ '3'
849
+ else
850
+ '0'
851
+ end
852
+ row << "%#{DAT_LEN[:CIKS]}s" % if (no8 && @packs[no8]) # Packungen.xls
853
+ @packs[no8][:swissmedic_category]
854
+ else
855
+ '0'
856
+ end.gsub(/(\+|\s)/, '')
857
+ row << "%0#{DAT_LEN[:ITHE]}d" % if (no8 && @packs[no8])
858
+ format_date(@packs[no8][:ith_swissmedic])
859
+ else
860
+ ('0' * DAT_LEN[:ITHE])
861
+ end.to_i
862
+ row << "%0#{DAT_LEN[:CEAN]}d" % idx[:ean].to_i
863
+ row << "%#{DAT_LEN[:CMWS]}s" % '2' # pharma
864
+ rows << row
816
865
  end
817
- row << "%#{DAT_LEN[:RECA]}s" % '11'
818
- row << "%#{DAT_LEN[:CMUT]}s" % if (phar = de_pac[:pharmacode] and phar.size > 3) # does not check expiration_date
819
- obj[:de][:status] == "I" ? '3' : '1'
820
- else
821
- '3'
822
- end
823
- row << "%0#{DAT_LEN[:PHAR]}d" % de_pac[:pharmacode].to_i
824
- row << "%-#{DAT_LEN[:ABEZ]}s" % (
825
- de_pac[:desc].to_s.gsub(/"/, '') + " " +
826
- (pac ? pac[:name_de].to_s : '') +
827
- de_pac[:additional_desc]
828
- ).to_s[0, DAT_LEN[:ABEZ]].gsub(/"/, '')
829
- row << "%#{DAT_LEN[:PRMO]}s" % (pac ? format_price(pac[:prices][:exf_price][:price].to_s) : ('0' * DAT_LEN[:PRMO]))
830
- row << "%#{DAT_LEN[:PRPU]}s" % (pac ? format_price(pac[:prices][:pub_price][:price].to_s) : ('0' * DAT_LEN[:PRPU]))
831
- row << "%#{DAT_LEN[:CKZL]}s" % if (@lppvs[de_pac[:ean]])
832
- '2'
833
- elsif pac # sl_entry
834
- '1'
835
- else
836
- '3'
837
- end
838
- row << "%#{DAT_LEN[:CLAG]}s" % if ((num && num.to_s =~ /(\d{5})(\d{3})/) and
839
- @fridges.include?($1.to_s))
840
- '1'
841
- else
842
- '0'
843
- end
844
- row << "%#{DAT_LEN[:CBGG]}s" % if ((pac && pac[:narcosis_flag] == 'Y') or # BAGXml
845
- (@flags[de_pac[:ean]])) # ywesee BM_update
846
- '3'
847
- else
848
- '0'
849
- end
850
- row << "%#{DAT_LEN[:CIKS]}s" % if (pac && pac[:swissmedic_category] =~ /^[ABCDE]$/) # BAGXml
851
- pac[:swissmedic_category]
852
- elsif (@packs[num]) # Packungen.xls
853
- @packs[num][:swissmedic_category]
854
- else
855
- '0'
856
- end.gsub(/(\+|\s)/, '')
857
- row << "%0#{DAT_LEN[:ITHE]}d" % if (@packs[num])
858
- format_date(@packs[num][:ith_swissmedic])
859
- else
860
- ('0' * DAT_LEN[:ITHE])
861
- end.to_i
862
- row << "%0#{DAT_LEN[:CEAN]}d" % de_pac[:ean].to_i
863
- row << "%#{DAT_LEN[:CMWS]}s" % '2' # pharma
864
- rows << row
865
866
  end
866
867
  end
867
868
  rows.join("\n")
@@ -871,31 +872,32 @@ module Oddb2xml
871
872
  prepare_articles(reset)
872
873
  rows = []
873
874
  @articles.each do |obj|
874
- row = ''
875
- de_pac = obj[:de]
876
- next if (!ean14 && de_pac[:ean].to_s.length != 13)
877
- # Oddb2tdat.parse_migel
878
- row << "%#{DAT_LEN[:RECA]}s" % '11'
879
- row << "%#{DAT_LEN[:CMUT]}s" % if (phar = de_pac[:pharmacode] and phar.size > 3)
880
- '1'
881
- else
882
- '3'
883
- end
884
- row << "%0#{DAT_LEN[:PHAR]}d" % de_pac[:pharmacode].to_i
885
- row << "%-#{DAT_LEN[:ABEZ]}s" % (
886
- de_pac[:desc].to_s.gsub(/"/, '') + " " +
887
- de_pac[:additional_desc]
888
- ).to_s[0, DAT_LEN[:ABEZ]].gsub(/"/, '')
889
- row << "%#{DAT_LEN[:PRMO]}s" % ('0' * DAT_LEN[:PRMO])
890
- row << "%#{DAT_LEN[:PRPU]}s" % ('0' * DAT_LEN[:PRPU])
891
- row << "%#{DAT_LEN[:CKZL]}s" % '3' # sl_entry and lppv
892
- row << "%#{DAT_LEN[:CLAG]}s" % '0'
893
- row << "%#{DAT_LEN[:CBGG]}s" % '0'
894
- row << "%#{DAT_LEN[:CIKS]}s" % ' ' # no category
895
- row << "%0#{DAT_LEN[:ITHE]}d" % 0
896
- row << "%0#{DAT_LEN[:CEAN]}d" % (de_pac[:ean] ? de_pac[:ean].to_i : 0)
897
- row << "%#{DAT_LEN[:CMWS]}s" % '1' # nonpharma
898
- rows << row
875
+ obj[:de].each_with_index do |idx, i|
876
+ row = ''
877
+ next if (!ean14 && idx[:ean].to_s.length != 13)
878
+ # Oddb2tdat.parse_migel
879
+ row << "%#{DAT_LEN[:RECA]}s" % '11'
880
+ row << "%#{DAT_LEN[:CMUT]}s" % if (phar = idx[:pharmacode] and phar.size > 3)
881
+ '1'
882
+ else
883
+ '3'
884
+ end
885
+ row << "%0#{DAT_LEN[:PHAR]}d" % idx[:pharmacode].to_i
886
+ row << "%-#{DAT_LEN[:ABEZ]}s" % (
887
+ idx[:desc].to_s.gsub(/"/, '') + " " +
888
+ idx[:additional_desc]
889
+ ).to_s[0, DAT_LEN[:ABEZ]].gsub(/"/, '')
890
+ row << "%#{DAT_LEN[:PRMO]}s" % ('0' * DAT_LEN[:PRMO])
891
+ row << "%#{DAT_LEN[:PRPU]}s" % ('0' * DAT_LEN[:PRPU])
892
+ row << "%#{DAT_LEN[:CKZL]}s" % '3' # sl_entry and lppv
893
+ row << "%#{DAT_LEN[:CLAG]}s" % '0'
894
+ row << "%#{DAT_LEN[:CBGG]}s" % '0'
895
+ row << "%#{DAT_LEN[:CIKS]}s" % ' ' # no category
896
+ row << "%0#{DAT_LEN[:ITHE]}d" % 0
897
+ row << "%0#{DAT_LEN[:CEAN]}d" % (idx[:ean] ? idx[:ean].to_i : 0)
898
+ row << "%#{DAT_LEN[:CMWS]}s" % '1' # nonpharma
899
+ rows << row
900
+ end
899
901
  end
900
902
  rows.join("\n")
901
903
  end
@@ -22,7 +22,7 @@ module Oddb2xml
22
22
  item[:desc_fr] = (desc = seq.at_xpath('.//DescriptionFr')) ? desc.text : ''
23
23
  item[:name_de] = (name = seq.at_xpath('.//NameDe')) ? name.text : ''
24
24
  item[:name_fr] = (name = seq.at_xpath('.//NameFr')) ? name.text : ''
25
- item[:swissmedic_number5] = (num5 = seq.at_xpath('.//SwissmedicNo5')) ? num5.text : ''
25
+ item[:swissmedic_number5] = (num5 = seq.at_xpath('.//SwissmedicNo5')) ? (num5.text.rjust(5,'0')) : ''
26
26
  item[:org_gen_code] = (orgc = seq.at_xpath('.//OrgGenCode')) ? orgc.text : ''
27
27
  item[:deductible] = (ddbl = seq.at_xpath('.//FlagSB20')) ? ddbl.text : ''
28
28
  item[:atc_code] = (atcc = seq.at_xpath('.//AtcCode')) ? atcc.text : ''
@@ -55,7 +55,7 @@ module Oddb2xml
55
55
  item[:packages][phar] = {
56
56
  :pharmacode => phar,
57
57
  :swissmedic_category => (cat = pac.at_xpath('.//SwissmedicCategory')) ? cat.text : '',
58
- :swissmedic_number8 => (num = pac.at_xpath('.//SwissmedicNo8')) ? num.text : '',
58
+ :swissmedic_number8 => (num = pac.at_xpath('.//SwissmedicNo8')) ? num.text.rjust(8, '0') : '',
59
59
  :narcosis_flag => (flg = pac.at_xpath('.//FlagNarcosis')) ? flg.text : '',
60
60
  :prices => {
61
61
  :exf_price => {
@@ -147,7 +147,7 @@ module Oddb2xml
147
147
  item[:stat_date] = (date = pac.at_xpath('.//SDATE')) ? date.text : ''
148
148
  item[:lang] = (lang = pac.at_xpath('.//LANG')) ? lang.text : ''
149
149
  item[:desc] = (dscr = pac.at_xpath('.//DSCR')) ? dscr.text : ''
150
- item[:atc_code] = (code = pac.at_xpath('.//ATC')) ? code.text : ''
150
+ item[:atc_code] = (code = pac.at_xpath('.//ATC')) ? code.text.to_s : ''
151
151
  # as quantity text
152
152
  item[:additional_desc] = (dscr = pac.at_xpath('.//ADDSCR')) ? dscr.text : ''
153
153
  if comp = pac.xpath('.//COMP')
@@ -155,7 +155,10 @@ module Oddb2xml
155
155
  item[:company_ean] = (gln = comp.at_xpath('.//GLN')) ? gln.text : ''
156
156
  end
157
157
  unless item[:pharmacode].empty?
158
- data[item[:pharmacode]] = item
158
+ unless data[item[:pharmacode]] # pharmacode => GTINs
159
+ data[item[:pharmacode]] = []
160
+ end
161
+ data[item[:pharmacode]] << item
159
162
  end
160
163
  end
161
164
  data
@@ -188,19 +191,25 @@ module Oddb2xml
188
191
  end
189
192
  data.uniq
190
193
  end
191
- def to_hash
194
+ def to_hash # Packungen.xls
192
195
  data = {}
193
196
  case @type
194
197
  when :packages
195
198
  i_5,i_3 = 0,10 # :swissmedic_numbers
196
199
  cat = 13 # :swissmedic_category
197
200
  ith = 4 # :ith_swissmedic IT-Code (swissmedic-diff)
198
- @sheet.each do |row|
201
+ atc = 5 # :atc_code
202
+ typ = 6 # Heilmittelcode
203
+ @sheet.each_with_index do |row, i|
204
+ next if (i== 0 or row[typ] == 'Tierarzneimittel')
199
205
  no8 = extract_number(row, i_5).to_s + extract_number(row, i_3, /^\d{3}$/).to_s
200
206
  unless no8.empty?
207
+ ean_base12 = "7680#{no8}"
201
208
  data[no8.intern] = {
209
+ :ean => (ean_base12.ljust(12, '0') + calc_checksum(ean_base12)),
202
210
  :ith_swissmedic => row[ith].to_s,
203
211
  :swissmedic_category => row[cat].to_s,
212
+ :atc_code => row[atc].to_s,
204
213
  }
205
214
  end
206
215
  end
@@ -211,7 +220,8 @@ module Oddb2xml
211
220
  def extract_number(row, i, ptrn=/^\d{5}$/)
212
221
  begin
213
222
  return nil unless row[i]
214
- number = row[i].to_i.to_s.gsub(/[^0-9]/, '')
223
+ row[i] = row[i].to_i if row[i].is_a? Float
224
+ number = row[i].to_s.gsub(/[^0-9]/, '')
215
225
  number = number.rjust(5, '0') if ptrn == /^\d{5}$/
216
226
  if number =~ ptrn
217
227
  return number
@@ -222,6 +232,16 @@ module Oddb2xml
222
232
  nil
223
233
  end
224
234
  end
235
+ def calc_checksum(str)
236
+ str = str.strip
237
+ sum = 0
238
+ val = str.split(//u)
239
+ 12.times do |idx|
240
+ fct = ((idx%2)*2)+1
241
+ sum += fct*val[idx].to_i
242
+ end
243
+ ((10-(sum%10))%10).to_s
244
+ end
225
245
  end
226
246
  class MigelExtractor < Extractor
227
247
  def initialize(bin)
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "1.3.5"
2
+ VERSION = "1.3.6"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oddb2xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.3.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-07 00:00:00.000000000 Z
12
+ date: 2013-02-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubyzip
16
- requirement: &11444160 !ruby/object:Gem::Requirement
16
+ requirement: &7438920 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *11444160
24
+ version_requirements: *7438920
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: archive-tar-minitar
27
- requirement: &11443700 !ruby/object:Gem::Requirement
27
+ requirement: &7438340 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *11443700
35
+ version_requirements: *7438340
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: mechanize
38
- requirement: &11443080 !ruby/object:Gem::Requirement
38
+ requirement: &7437620 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *11443080
46
+ version_requirements: *7437620
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: nokogiri
49
- requirement: &11442640 !ruby/object:Gem::Requirement
49
+ requirement: &7436920 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *11442640
57
+ version_requirements: *7436920
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: savon
60
- requirement: &11442020 !ruby/object:Gem::Requirement
60
+ requirement: &7435960 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '2.0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *11442020
68
+ version_requirements: *7435960
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: spreadsheet
71
- requirement: &11441540 !ruby/object:Gem::Requirement
71
+ requirement: &7435040 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *11441540
79
+ version_requirements: *7435040
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &11441020 !ruby/object:Gem::Requirement
82
+ requirement: &7432740 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *11441020
90
+ version_requirements: *7432740
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: webmock
93
- requirement: &11440480 !ruby/object:Gem::Requirement
93
+ requirement: &7430920 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *11440480
101
+ version_requirements: *7430920
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: ZenTest
104
- requirement: &11439620 !ruby/object:Gem::Requirement
104
+ requirement: &7429180 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *11439620
112
+ version_requirements: *7429180
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: hoe
115
- requirement: &11438920 !ruby/object:Gem::Requirement
115
+ requirement: &7425900 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: '3.4'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *11438920
123
+ version_requirements: *7425900
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: rdoc
126
- requirement: &11438260 !ruby/object:Gem::Requirement
126
+ requirement: &7421480 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *11438260
134
+ version_requirements: *7421480
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: rdoc
137
- requirement: &11435260 !ruby/object:Gem::Requirement
137
+ requirement: &7420100 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ~>
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: '3.10'
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *11435260
145
+ version_requirements: *7420100
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: hoe
148
- requirement: &11434400 !ruby/object:Gem::Requirement
148
+ requirement: &7418960 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ~>
@@ -153,7 +153,7 @@ dependencies:
153
153
  version: '2.13'
154
154
  type: :development
155
155
  prerelease: false
156
- version_requirements: *11434400
156
+ version_requirements: *7418960
157
157
  description: oddb2xml creates xml files using swissINDEX, BAG-XML and Swissmedic.
158
158
  email: yasaka@ywesee.com, zdavatz@ywesee.com
159
159
  executables: