era_835_parser 0.2.1 → 0.2.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab71e41a87a2f73200361b1bedeb9740c6edc2451cee146057682484a3d3caf7
4
- data.tar.gz: 9ed593d781b601484ac0c99019de108f6b4d15374059c1ef46d5a707d5dbec72
3
+ metadata.gz: 27c9972b427c29ab16fc6977570044045f0064db4e42cdd06e5ee02c2aaf8d05
4
+ data.tar.gz: 308eadea4e7c01d786898f52576b378e0caf62edf56fecc146bd569068badb4d
5
5
  SHA512:
6
- metadata.gz: 260a869a1d17269a37c9e06177357b4e8a3c3ac3be88bc9605b9d58459c7bb2bb19be8752109d0640c81b7c7ece04307c9a652f4450d3c94bf198b91213d593c
7
- data.tar.gz: fd110d86ad73c4a50f2578f0b65fb5f90c174408bde64f97b03b4682eb8615f44dee6e9790f0a6ff26886c39d603f5d6891a7c6aa3f54dc395a9943e4012989e
6
+ metadata.gz: d322bb6e647d262130e37069a05944f71f8befae9452516e54f0895fc9c43897844beab38f06ef76687de8054c1f9eec4d0b159760bd5ca168d8441c18ca3cea
7
+ data.tar.gz: 2abee925027773e179f967614b4cadb47ef9186708e208a3c3126b0fabc1f30b79996b2f89b54758843931a158a87efc7178392da0b0561939b740a3fca5a9bf
data/README.md CHANGED
@@ -43,6 +43,17 @@ if !era[:checks].nil?
43
43
  puts check[:payer_tax_id] # Payer tax id
44
44
  puts check[:payer_edi_id] # Payer EDI id
45
45
  puts check[:date] # Check date (string mm/dd/yyyy)
46
+ # Provider level adjustments (PLB) attributed to this check
47
+ if !check[:provider_adjustments].nil?
48
+ check[:provider_adjustments].each do |adjustment|
49
+ puts adjustment[:adjustment_date] # Adjustment date (string mm/dd/yyyy)
50
+ puts adjustment[:provider_id] # Provider ID
51
+ puts adjustment[:reference_id] # Reference ID
52
+ puts adjustment[:adjustment_amount] # Adjustment amount (integer)
53
+ puts adjustment[:reason] # Reason
54
+ puts adjustment[:reason_code] # Reason code
55
+ end
56
+ end
46
57
  if !check[:eras].nil?
47
58
  check[:eras].each do |era_counter, individual_era|
48
59
  puts individual_era[:era_text] # ERA text
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "bundler", ">= 1.7"
22
22
  spec.add_development_dependency "rake", ">= 12.3.3"
23
23
  spec.add_development_dependency "rspec"
24
24
  end
@@ -35,6 +35,11 @@ module Era835Parser
35
35
  adjustment_counter_a = -1
36
36
  svc_counter = 0
37
37
 
38
+ # PLB (provider level adjustment) segment state
39
+ plb_provider_id = ''
40
+ plb_adjustment_date = ''
41
+ plb_pair_open = false
42
+
38
43
  # trigger variables
39
44
  adjustments_start = false
40
45
  checks_start = false
@@ -677,121 +682,49 @@ module Era835Parser
677
682
  case index
678
683
  when 1
679
684
  # Provider Identifier
680
- adjustment_counter_a += 1
681
- adjustment = Hash.new
682
- adjustment[:provider_id] = element.strip
685
+ plb_provider_id = element.strip
686
+ plb_pair_open = false
683
687
  when 2
684
688
  # Fiscal Period Date
685
- adjustment[:adjustment_date] = element.strip[4..5] + "/" + element.strip[6..7] + "/" + element.strip[0..3]
686
- when 3
687
- element.split(":").each_with_index do |subelement, i|
688
- case i
689
- when 0
690
- # PROVIDER ADJUSTMENT REASON CODE
691
- # puts "PROVIDER ADJUSTMENT REASON CODE: #{subelement}"
692
- adjustment[:reason_code] = subelement.strip
693
- adjustment[:reason] = PROVIDER_LEVEL_ADJUSTMENTS[subelement.strip]
694
- when 1
695
- # Provider Adjustment Identifier
696
- # puts "Provider Adjustment Identifier: #{subelement}"
697
- adjustment[:reference_id] = subelement.strip
698
- end
699
- end
700
- when 4
701
- # Provider Adjustment Amount
702
- adjustment[:adjustment_amount] = (element.to_f * 100).round().to_i
703
- when 5
704
- adjustment_counter_a += 1
705
- element.split(":").each_with_index do |subelement, i|
706
- case i
707
- when 0
708
- # PROVIDER ADJUSTMENT REASON CODE
709
- # puts "PROVIDER ADJUSTMENT REASON CODE: #{subelement}"
710
- adjustment[:reason_code] = subelement.strip
711
- adjustment[:reason] = PROVIDER_LEVEL_ADJUSTMENTS[subelement.strip]
712
- when 1
713
- # Provider Adjustment Identifier
714
- # puts "Provider Adjustment Identifier: #{subelement}"
715
- adjustment[:reference_id] = subelement.strip
716
- end
717
- end
718
- when 6
719
- # Provider Adjustment Amount
720
- adjustment[:adjustment_amount] = (element.to_f * 100).round().to_i
721
- when 7
722
- adjustment_counter_a += 1
723
- element.split(":").each_with_index do |subelement, i|
724
- case i
725
- when 0
726
- # PROVIDER ADJUSTMENT REASON CODE
727
- # puts "PROVIDER ADJUSTMENT REASON CODE: #{subelement}"
728
- adjustment[:reason_code] = subelement.strip
729
- adjustment[:reason] = PROVIDER_LEVEL_ADJUSTMENTS[subelement.strip]
730
- when 1
731
- # Provider Adjustment Identifier
732
- # puts "Provider Adjustment Identifier: #{subelement}"
733
- adjustment[:reference_id] = subelement.strip
734
- end
735
- end
736
- when 8
737
- # Provider Adjustment Amount
738
- adjustment[:adjustment_amount] = (element.to_f * 100).round().to_i
739
- when 9
740
- adjustment_counter_a += 1
741
- element.split(":").each_with_index do |subelement, i|
742
- case i
743
- when 0
744
- # PROVIDER ADJUSTMENT REASON CODE
745
- # puts "PROVIDER ADJUSTMENT REASON CODE: #{subelement}"
746
- adjustment[:reason_code] = subelement.strip
747
- adjustment[:reason] = PROVIDER_LEVEL_ADJUSTMENTS[subelement.strip]
748
- when 1
749
- # Provider Adjustment Identifier
750
- # puts "Provider Adjustment Identifier: #{subelement}"
751
- adjustment[:reference_id] = subelement.strip
752
- end
753
- end
754
- when 10
755
- # Provider Adjustment Amount
756
- adjustment[:adjustment_amount] = (element.to_f * 100).round().to_i
757
- when 11
758
- adjustment_counter_a += 1
759
- element.split(":").each_with_index do |subelement, i|
760
- case i
761
- when 0
762
- # PROVIDER ADJUSTMENT REASON CODE
763
- # puts "PROVIDER ADJUSTMENT REASON CODE: #{subelement}"
764
- adjustment[:reason_code] = subelement.strip
765
- adjustment[:reason] = PROVIDER_LEVEL_ADJUSTMENTS[subelement.strip]
766
- when 1
767
- # Provider Adjustment Identifier
768
- # puts "Provider Adjustment Identifier: #{subelement}"
769
- adjustment[:reference_id] = subelement.strip
689
+ plb_adjustment_date = element.strip[4..5] + "/" + element.strip[6..7] + "/" + element.strip[0..3]
690
+ when 3, 5, 7, 9, 11, 13
691
+ # Start of an adjustment reason/amount pair (PLB03-04 through PLB13-14).
692
+ # A single PLB segment carries up to 6 pairs; each pair is its own adjustment.
693
+ if element.strip.empty?
694
+ plb_pair_open = false
695
+ else
696
+ plb_pair_open = true
697
+ adjustment_counter_a += 1
698
+ adjustment = Hash.new
699
+ adjustment[:provider_id] = plb_provider_id
700
+ adjustment[:adjustment_date] = plb_adjustment_date
701
+ element.split(":").each_with_index do |subelement, i|
702
+ case i
703
+ when 0
704
+ # PROVIDER ADJUSTMENT REASON CODE
705
+ # puts "PROVIDER ADJUSTMENT REASON CODE: #{subelement}"
706
+ adjustment[:reason_code] = subelement.strip
707
+ adjustment[:reason] = PROVIDER_LEVEL_ADJUSTMENTS[subelement.strip]
708
+ when 1
709
+ # Provider Adjustment Identifier
710
+ # puts "Provider Adjustment Identifier: #{subelement}"
711
+ adjustment[:reference_id] = subelement.strip
712
+ end
770
713
  end
771
714
  end
772
- when 12
715
+ when 4, 6, 8, 10, 12, 14
773
716
  # Provider Adjustment Amount
774
- adjustment[:adjustment_amount] = (element.to_f * 100).round().to_i
775
- when 13
776
- adjustment_counter_a += 1
777
- element.split(":").each_with_index do |subelement, i|
778
- case i
779
- when 0
780
- # PROVIDER ADJUSTMENT REASON CODE
781
- # puts "PROVIDER ADJUSTMENT REASON CODE: #{subelement}"
782
- adjustment[:reason_code] = subelement.strip
783
- adjustment[:reason] = PROVIDER_LEVEL_ADJUSTMENTS[subelement.strip]
784
- when 1
785
- # Provider Adjustment Identifier
786
- # puts "Provider Adjustment Identifier: #{subelement}"
787
- adjustment[:reference_id] = subelement.strip
788
- end
717
+ adjustment[:adjustment_amount] = (element.to_f * 100).round().to_i if plb_pair_open
718
+ end
719
+ if plb_pair_open && adjustment_counter_a > -1 && (adjustment != {} && !adjustment.nil?)
720
+ adjustments[adjustment_counter_a] = adjustment
721
+ # Attribute the adjustment to the check (TRN) it belongs to, so multi-check
722
+ # files expose provider level adjustments per check.
723
+ if check[:check_number]
724
+ check[:provider_adjustments] = Array.new if check[:provider_adjustments].nil?
725
+ check[:provider_adjustments] << adjustment unless check[:provider_adjustments].include?(adjustment)
789
726
  end
790
- when 14
791
- # Provider Adjustment Amount
792
- adjustment[:adjustment_amount] = (element.to_f * 100).round().to_i
793
727
  end
794
- adjustments[adjustment_counter_a] = adjustment if adjustment_counter_a > -1 && (adjustment != {} && !adjustment.nil?)
795
728
  when "CAS"
796
729
  case index
797
730
  when 1
@@ -1,3 +1,3 @@
1
1
  module Era835Parser
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -29,6 +29,9 @@ RSpec.describe Era835Parser::Parser do
29
29
  it 'returns the correct number of adjustment groups' do
30
30
  expect(@era[:checks]['70408535'][:eras][0][:line_items][0][:adjustment_groups].count).to eq(1)
31
31
  end
32
+ it 'returns no provider adjustments' do
33
+ expect(@era[:checks]['70408535'][:provider_adjustments]).to eq(nil)
34
+ end
32
35
  end
33
36
 
34
37
  context 'Check #70408535' do
@@ -1730,6 +1733,84 @@ RSpec.describe Era835Parser::Parser do
1730
1733
  end
1731
1734
  end
1732
1735
  end
1736
+
1737
+ context 'example_7.835' do
1738
+ # Multi-check 835 where PLB segments carry multiple reason/amount pairs
1739
+ # (PLB03-04 through PLB13-14). Each pair must parse as its own
1740
+ # adjustment and be attributed to the check (TRN) it belongs to.
1741
+ before :all do
1742
+ @era = Era835Parser::Parser.new(file_path: "../era_835_parser/spec/example_7.835").parse
1743
+ end
1744
+
1745
+ context 'Aggregate totals' do
1746
+ it 'returns the correct number of checks' do
1747
+ expect(@era[:checks].count).to eq(2)
1748
+ end
1749
+ it 'returns one adjustment per reason/amount pair across the file' do
1750
+ expect(@era[:adjustments].count).to eq(5)
1751
+ end
1752
+ end
1753
+
1754
+ context 'Check #02790758 (zero payment, multi-pair PLB)' do
1755
+ it 'returns the transaction handling code' do
1756
+ expect(@era[:checks]['02790758'][:transaction_handling_code]).to eq('H')
1757
+ end
1758
+ it 'returns the check amount (integer)' do
1759
+ expect(@era[:checks]['02790758'][:amount]).to eq(0)
1760
+ end
1761
+ it 'returns one provider adjustment per reason/amount pair' do
1762
+ expect(@era[:checks]['02790758'][:provider_adjustments].count).to eq(4)
1763
+ end
1764
+ it 'returns the first pair' do
1765
+ adjustment = @era[:checks]['02790758'][:provider_adjustments][0]
1766
+ expect(adjustment[:reason_code]).to eq('FB')
1767
+ expect(adjustment[:reason]).to eq('Forwarding Balance')
1768
+ expect(adjustment[:reference_id]).to eq('926072000117048')
1769
+ expect(adjustment[:adjustment_amount]).to eq(547904)
1770
+ expect(adjustment[:provider_id]).to eq('0987654321')
1771
+ expect(adjustment[:adjustment_date]).to eq('03/14/2026')
1772
+ end
1773
+ it 'returns the second pair' do
1774
+ adjustment = @era[:checks]['02790758'][:provider_adjustments][1]
1775
+ expect(adjustment[:reason_code]).to eq('FB')
1776
+ expect(adjustment[:reference_id]).to eq('926073000032814')
1777
+ expect(adjustment[:adjustment_amount]).to eq(-375852)
1778
+ end
1779
+ it 'returns the third pair' do
1780
+ adjustment = @era[:checks]['02790758'][:provider_adjustments][2]
1781
+ expect(adjustment[:reason_code]).to eq('WO')
1782
+ expect(adjustment[:reason]).to eq('Overpayment Recovery')
1783
+ expect(adjustment[:reference_id]).to eq('200200964A52')
1784
+ expect(adjustment[:adjustment_amount]).to eq(11576)
1785
+ end
1786
+ it 'returns the fourth pair' do
1787
+ adjustment = @era[:checks]['02790758'][:provider_adjustments][3]
1788
+ expect(adjustment[:reason_code]).to eq('CS')
1789
+ expect(adjustment[:reason]).to eq('Adjustment')
1790
+ expect(adjustment[:reference_id]).to eq('200200964A52')
1791
+ expect(adjustment[:adjustment_amount]).to eq(-11576)
1792
+ end
1793
+ end
1794
+
1795
+ context 'Check #99887766 (single-pair PLB)' do
1796
+ it 'returns the transaction handling code' do
1797
+ expect(@era[:checks]['99887766'][:transaction_handling_code]).to eq('I')
1798
+ end
1799
+ it 'returns the check amount (integer)' do
1800
+ expect(@era[:checks]['99887766'][:amount]).to eq(10000)
1801
+ end
1802
+ it 'returns one provider adjustment' do
1803
+ expect(@era[:checks]['99887766'][:provider_adjustments].count).to eq(1)
1804
+ end
1805
+ it 'returns the pair' do
1806
+ adjustment = @era[:checks]['99887766'][:provider_adjustments][0]
1807
+ expect(adjustment[:reason_code]).to eq('WO')
1808
+ expect(adjustment[:reason]).to eq('Overpayment Recovery')
1809
+ expect(adjustment[:reference_id]).to eq('926074000055521')
1810
+ expect(adjustment[:adjustment_amount]).to eq(2500)
1811
+ end
1812
+ end
1813
+ end
1733
1814
  end
1734
1815
 
1735
1816
  context 'Human readable' do
@@ -0,0 +1,48 @@
1
+ ST*835*1234~
2
+ BPR*H*0*C*NON************20260314~
3
+ TRN*1*02790758*560894904~
4
+ REF*F2*LCLA438D~
5
+ DTM*405*20260310~
6
+ N1*PR*BLUE CROSS AND BLUE SHIELD OF NORTH CAROLINA~
7
+ N3*P O BOX 2291~
8
+ N4*DURHAM*NC*27702~
9
+ PER*CX*TE*8005554844~
10
+ N1*PE*XYZ HEALTHCARE CORPORATION*XX*0987654321~
11
+ N3*P O BOX XYZ~
12
+ N4*CHARLOTTE*NC*28234~
13
+ REF*TJ*123456789~
14
+ LX*1~
15
+ CLP*200200964A52*1*150*67.73*0*15*94151100100~
16
+ NM1*QC*1*Dough*Mary****MI*YPB123456789001~
17
+ DTM*050*20260310~
18
+ SVC*HC:92507*150*67.73**1~
19
+ DTM*472*20260301~
20
+ CAS*CO*45*82.27~
21
+ REF*6R*0001~
22
+ AMT*B6*67.73~
23
+ PLB*0987654321*20260314*FB:926072000117048*5479.04*FB:926073000032814*-3758.52*WO:200200964A52*115.76*CS:200200964A52*-115.76~
24
+ SE*27*1234~
25
+ ST*835*1235~
26
+ BPR*I*100*C*CHK************20260314~
27
+ TRN*1*99887766*560894904~
28
+ REF*F2*LCLA439D~
29
+ DTM*405*20260310~
30
+ N1*PR*BLUE CROSS AND BLUE SHIELD OF NORTH CAROLINA~
31
+ N3*P O BOX 2291~
32
+ N4*DURHAM*NC*27702~
33
+ PER*CX*TE*8005554844~
34
+ N1*PE*XYZ HEALTHCARE CORPORATION*XX*0987654321~
35
+ N3*P O BOX XYZ~
36
+ N4*CHARLOTTE*NC*28234~
37
+ REF*TJ*123456789~
38
+ LX*1~
39
+ CLP*300300964B63*1*125*100*0*15*94151100200~
40
+ NM1*QC*1*Dough*John****MI*YPB123456789002~
41
+ DTM*050*20260310~
42
+ SVC*HC:92507*125*100**1~
43
+ DTM*472*20260301~
44
+ CAS*CO*45*25~
45
+ REF*6R*0001~
46
+ AMT*B6*100~
47
+ PLB*0987654321*20260314*WO:926074000055521*25~
48
+ SE*24*1235~
metadata CHANGED
@@ -1,27 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: era_835_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin S. Dias
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-05-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - "~>"
16
+ - - ">="
18
17
  - !ruby/object:Gem::Version
19
18
  version: '1.7'
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
- - - "~>"
23
+ - - ">="
25
24
  - !ruby/object:Gem::Version
26
25
  version: '1.7'
27
26
  - !ruby/object:Gem::Dependency
@@ -81,13 +80,13 @@ files:
81
80
  - spec/example_4.835
82
81
  - spec/example_5.835
83
82
  - spec/example_6.835
83
+ - spec/example_7.835
84
84
  - spec/spec_helper.rb
85
85
  - spec/test_era.txt
86
86
  homepage: https://github.com/diasks2/era_835_parser
87
87
  licenses:
88
88
  - MIT
89
89
  metadata: {}
90
- post_install_message:
91
90
  rdoc_options: []
92
91
  require_paths:
93
92
  - lib
@@ -102,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
101
  - !ruby/object:Gem::Version
103
102
  version: '0'
104
103
  requirements: []
105
- rubygems_version: 3.3.26
106
- signing_key:
104
+ rubygems_version: 3.7.2
107
105
  specification_version: 4
108
106
  summary: Electronic Remittance Advice (ERA) 835 parser
109
107
  test_files:
@@ -114,5 +112,6 @@ test_files:
114
112
  - spec/example_4.835
115
113
  - spec/example_5.835
116
114
  - spec/example_6.835
115
+ - spec/example_7.835
117
116
  - spec/spec_helper.rb
118
117
  - spec/test_era.txt