Coder Social home page Coder Social logo

kputnam / stupidedi Goto Github PK

View Code? Open in Web Editor NEW
261.0 12.0 137.0 40.91 MB

Ruby API for parsing and generating ASC X12 EDI transactions

License: BSD 3-Clause "New" or "Revised" License

Ruby 99.98% HTML 0.02%
ruby edi hp-835 hc-837 grammar parser validation x12 po-810 hn-277

stupidedi's People

Contributors

adriand avatar apreskill avatar austinmbrown avatar casconed avatar dependabot[bot] avatar irobayna avatar jakedmsnap avatar julienroger avatar kelnadim avatar kfalconer avatar kputnam avatar kyle-query avatar lanxx019 avatar michael-t-shrout avatar milieu avatar mrpasquini avatar mtwstudios avatar nickrivadeneira avatar nsmith avatar pepito2k avatar peretzp avatar petergoldstein avatar samueltc avatar serixscorpio avatar skaczor avatar snyk-bot avatar sofiengwin avatar tamagokun avatar vikaskedia avatar wling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stupidedi's Issues

Multiple constraints on find not working as expected

I have the following segment...

L11|68600 TL 182555|CR|SHPREF1/~

I'm trying to pull the 68600 TL 182555 reference using the following:

el(m.find(:L11, nil, nil, 'SHPREF1'), 1){|e| puts "Reference: #{e}" }

But that comes up empty.

If I do m.find(:L11, nil, 'CR'), it works. But that isn't a unique identifier, so I need to use SHPREF1.

Is this a bug or am I doing something wrong?

Non-deterministic state

running edi-pp against the latest message I am defining (PS830), I am getting the following output

Non-deterministic state
0.122 seconds

Any ideas as of why?

Leverage ruby 2.3.0 frozen string literal pragma?

@kputnam Now that ruby 2.3.0 has been released I am wondering if we should try experimenting with the new frozen string literal pragma? In theory sounds like stupidedi could benefit from it, i.e: less memory usage and faster processing. Thoughts?

edi-pp reports unknown transaction set "PS" "830" "004010" when using ruby 2.2.0

Sample EDI files that parsed correctly prior to ruby2.2.0 are failing now

InvalidEnvelopeVal(
        unknown transaction set "PS" "830" "004010",
        InvalidSegmentVal[ST],
        InvalidSegmentVal[BFR],
        InvalidSegmentVal[N1],
        InvalidSegmentVal[N1],
        InvalidSegmentVal[LIN],
        InvalidSegmentVal[UIT],
        InvalidSegmentVal[PID],
        InvalidSegmentVal[N1],
        InvalidSegmentVal[SDP],
        InvalidSegmentVal[FST],
        InvalidSegmentVal[FST],
        InvalidSegmentVal[FST],
        InvalidSegmentVal[FST],
        InvalidSegmentVal[FST],
        InvalidSegmentVal[FST],
        InvalidSegmentVal[CTT],
        InvalidSegmentVal[SE]),

Strict SegmentDef validations

Check that any element marked Relational actually has a corresponding SyntaxRule and that each SyntaxRule uses valid segments indexes.

Generator example returns parse error

I am looking to use this gem to generate 837 professional claim file. ButI can't get the example provided for generating claims to work. The following error is return when trying to generate the ST data segment:

Stupidedi::Exceptions::ParseError: unknown transaction set "HC" "837" "005010X222"

Do I have to set some config settings for the transaction header?

Memory/performance

Hi there,

I've been doing some benchmarking and am puzzled by the memory footprint i'm seeing. Do you expect MRI to use up 2.5+gb of RAM to parse (not pp) a 9mb SC832 doc, with run times well over 4min?

Seems a little... excessive. Is there a trick I'm missing?

HC837i support

Hi,

I need to create HC837p as well as HC837i health claims.
I already have everything for the 837p, but I don't see any code for validating X223HC837P.

Is there any 'easy' way to validate that standard ?
If not, can you guide me a little bit on what should I modify/add to get it to work ? I have the standard documentation and I am willing to make the effort to add the support to the gem but It would help having a little guide on it.

Thanks,
Gonzalo.

How to specify a certain set of segments?

Here's a typical transaction set:

ST|214|000056421~
B10|0|0|UPSN~
L11|QVD|TN|O4~
L11|1Z75A3T3YT10727583|2I~
L11|68600 TL 182555|CR|SHPREF1/~
L11|68600 TL 182555|CR|PKGREF1/~
N1|SH|NA|25|75A3T3~
N1|BT||25|75A3T3|01~
LX|1~
AT7|X2|A2|||20130612|213727|LT~
L11|AH-THE ADDRESS HAS BEEN CORREC|RRS|. THE DELIVERY HAS BEEN RESCHE~
L11|DS-THE ADDRESS LABEL IS MISSIN|REC|R ILLEGIBLE~
MAN|CP|E1|ONTARIO HUB|CP|CA|US~
CD3|||E1~
CD3|||R4~
N1|UP|ABE LINCOLN~
N3|123 ANYWHERE AVE~
N4|SOMEWHERE|NY|33332|US~
SE|19|000056421~

What I'm ultimately trying to pull is that set of N1, N3 and N4 towards then end of the set.

But, there will occasionally be an additional set of those under the first occurrence of N1 (and before AT7).

So how would I differentiate those and select only those segments before AT7 or only those towards the end?

Does that make sense?

Problem parsing - ideas needed

When I first implemented message RA 820 v3010, I was getting lots of non-deterministic problems and with your guidance we collapse some loops and items and both tools: edi-pp and edi-ed parse the data correctly.

My problem is that if I manually traverse the tree, I get to a loop of N1 items which belong to a particular segment and the parser parses all the N1 not just the ones that belong to the parent.

Here is my code:

      edi_data.first.flatmap do |isa|
        isa.iterate(:GS) do |gs|
          gs.iterate(:ST) do |st|
            gs.find(:ST).flatmap{|x| x.find(:BPS) }
            .tap do |bps|
            end
            gs.find(:ST).flatmap{|x| x.find(:REF,'R2') }
            .tap do |ref|
            end
            gs.find(:ST).flatmap{|x| x.find(:DTM) }
            .tap do |dtm|
            end
            gs.find(:ST).flatmap{|x| x.find(:N1,'SU') }
            .tap do |n1|
            end
            gs.find(:ST).flatmap{|x| x.find(:LS,'A') }
            .tap do |ls|
              ls.iterate(:N1, 'HH') do |n1|
                puts "N1 HH #{n1.element(2).map(&:node).fetch(0)}"
                n1.find(:N1, 'HH').flatmap{|x| x.find(:RMT,'IV') }
                .tap do |rmt|
                 @seller_invoice_number  = "#{rmt.element(2).map(&:node).fetch(0)}"
                  @total_gross_amount     = "#{rmt.element(3).map(&:node).fetch(0)}"
                  puts "RMT IV [$#{@total_gross_amount}] #{@seller_invoice_number}"
                  puts "==========================="
             end
                  n1.iterate(:N1, 'LI') do |n11|
                    puts "N1 LI #{n11.element(2).map(&:node).fetch(0)}"
                  end

The problem is on the last item N1 LI which it iterates through all the LI on the file, not the ones just belonging to the parent N1

Segment cannot be reached from the current state

I'm getting this error:

Stupidedi::Exceptions::ParseError: AT7 segment cannot be reached from the current state

When I run this:

a.flatmap{|m| m.sequence(:GS, :ST) }.tap do |m|
  m.find(:AT7)
end

Here's an example transaction set:

ST|214|000056391~
B10|0|0|UPSN~
L11|QVD|TN|O4~
L11|1Z6VX489YN03535798|2I~
N1|SH|NA|25|6VX489~
N1|BT||25|6VX489|01~
LX|1~
AT7|X8|AJ|||20130612|232947|LT~
AT7|||AB|BG|20130612~
L11|2U-UPS WILL ATTEMPT DELIVERY|REC|KAGE WILL NOT BE TRANSFERRED T~
MAN|CP|E1|OKC EDMOND|CP|OK|US~
CD3|||R4~
N1|UP|NA~
SE|14|000056391~

If I run that find on other elements (like L11 or N1) it works fine, but AT7 and MAN throw that error.

"non-deterministic machine state" when generating 837 2310E/2010F

Hi, I'm trying to convert a (horrible) hand-generated EDI "generator" to use stupidedi. Slowly figuring things out, but ran into this issue (and a few others, but separate tickets for those).

When trying to generate the 837 output, I'm getting:

"non-deterministic machine state: NM1 Rendering Provider Name, NM1 Service Facility Location Name, NM1 Ambulance Pick-up Location, NM1 Ambulance Drop-off Location"

This happens if I have both 2310E (Ambulance Pickup Location) and 2310F (Ambulance Dropoff Location) defined, does not happen with only one of them. So the presence of both is confusing the parser, even though they should be unambigious.

The relevant code snippet is:

        config = Stupidedi::Config.hipaa
        b = Stupidedi::Builder::BuilderDsl.build(config)
...
              b.CLM claim.original_id,
                    claim.claim_amount,
                    nil, nil,
                    b.composite(parameters.place_of_service_code, 'B', '1'),
                    'Y', 'A', 'Y', 'Y'

              b.DTP '454', 'D8',
                  claim.claim_date

              b.HI b.composite(*(claim.procedure_code.split ':'))

# 2310E
              b.NM1 'PW', '2'
              b.N3 claim.pickup_address
              b.N4 claim.pickup_city, claim.pickup_state, claim.pickup_postcode

# 2310F, HAVING THIS SEGMENT CAUSES THE ERROR
              b.NM1 '42', '2'
              b.N3 claim.dropoff_address
              b.N4 claim.dropoff_city, claim.dropoff_state, claim.dropoff_postcode

              b.LX '1'

              b.SV1 b.composite('HC', claim.hcpcs_code),
                    claim.claim_amount,
                    'UN', '1', nil, nil, b.composite('1')

              b.DTP '472', 'D8',
                    claim.claim_date
...

Any ideas on how I could get around this? Everything else is now working fine, but the client wants to have both the pickup and the dropoff addresses included per claim.

including gem causes infinite deprecation warnings

I find that including this as a gem causes the following error over and over on tests:

Passing options to #find is deprecated. Please build a scope and then call #find on it.

If I do require: false, then no problems, unless I require the library in a test.

Support for reading UTF-8 strings

It seems that stupidedi does not support UTF-8 chacaters when reading out an EDI. I get:

ArgumentError: universe does not contain element "ใ‚"

Digging a bit I found that Stupidedi::Reader::C_BYTES, defined here, only includes ASCII characters and crashes here when other characters are used.

I believe this should be fixable simply by changing the definition of C_BYTES but wondering if there are other considerations that would prevent this from being possible.

Warn about re-assigning configuration

Configuration documentation should be reviewed (and tangentially, an explanation for the difference between a TransactionSetDef and Guide would be useful). It's likely someone may unknowingly do something like this:

x.register("004010", "SM", "204") { FortyTen::TransactionSetDefs::SM204 }
x.register("004010", "SM", "204") { Guides::FortyTen::SM204 }

... which probably has unintended consequences: the first configuration is overwritten. Printing a warning would be appropriate.

Example file fails parser

The example file from the example fails with a InvalidEnvelopeVal:

./bin/edi-pp spec/fixtures/X222-HC837/1-good.txt


TransmissionVal(
  InterchangeVal[00501](
    SegmentVal[ISA: Interchange Control Header](
      ID.value[  I01: Authorization Information Qualifier](00: No Authorization Information Present (No Meaningful Information in I02)),
      AN.value[  I02: Authorization Information](..........),
      ID.value[  I03: Security Information Qualifier](01: Password),
      AN.value[  I04: Security Information](SECRET....),
      ID.value[  I05: Interchange ID Qualifier](ZZ: Mutually Defined),
      AN.value[  I06: Interchange Sender ID](SUBMITTERS.ID..),
      ID.value[  I05: Interchange ID Qualifier](ZZ: Mutually Defined),
      AN.value[  I07: Interchange Receiver ID](RECEIVERS.ID...),
      DT.value[  I08: Interchange Date](XX03-01-01),
      TM.value[  I09: Interchange Time](12:53:ss),
      SeparatorElementVal.value[I65](^),
      ID.value[  I11: Interchange Control Version Number](00501: Standards Approved for Publication by ASC X12 Procedures Review Board through October 2003),
      Nn.value[  I12: Interchange Control Number](905),
      ID.value[  I13: Acknowledgment Requested](1: Interchange Acknowledgment Requested (TA1)),
      ID.value[  I14: Interchange Usage Indicator](T: Test Data),
      SeparatorElementVal.value[I15](:)), 
    FunctionalGroupVal[005010](
      SegmentVal[GS: Functional Group Header](
        ID.value[ E479: Functional Identifier Code](HC: Health Care Claim),
        AN.value[ E142: Application's Sender Code](SENDER CODE),
        AN.value[ E124: Application Receiver's Code](RECEIVER CODE),
        DT.value[ E373: Date](1999-12-31),
        TM.value[ E337: Time](08:02:ss),
        Nn.value[  E28: Group Control Number](1),
        ID.value[ E455: Responsible Agency Code](X: Accredited Standards Committee X12),
        AN.value[ E480: Version / Release / Identifier Code](005010X222)), 
      InvalidEnvelopeVal(
        unknown transaction set "HC" "837" "005010X222",
        InvalidSegmentVal[ST],
        InvalidSegmentVal[BHT],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[PER],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[HL],
        InvalidSegmentVal[PRV],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[N3],
        InvalidSegmentVal[N4],
        InvalidSegmentVal[REF],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[N3],
        InvalidSegmentVal[N4],
        InvalidSegmentVal[HL],
        InvalidSegmentVal[SBR],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[N3],
        InvalidSegmentVal[N4],
        InvalidSegmentVal[DMG],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[N4],
        InvalidSegmentVal[REF],
        InvalidSegmentVal[HL],
        InvalidSegmentVal[PAT],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[N3],
        InvalidSegmentVal[N4],
        InvalidSegmentVal[DMG],
        InvalidSegmentVal[CLM],
        InvalidSegmentVal[REF],
        InvalidSegmentVal[HI],
        InvalidSegmentVal[LX],
        InvalidSegmentVal[SV1],
        InvalidSegmentVal[DTP],
        InvalidSegmentVal[LX],
        InvalidSegmentVal[SV1],
        InvalidSegmentVal[DTP],
        InvalidSegmentVal[LX],
        InvalidSegmentVal[SV1],
        InvalidSegmentVal[DTP],
        InvalidSegmentVal[LX],
        InvalidSegmentVal[SV1],
        InvalidSegmentVal[DTP],
        InvalidSegmentVal[SE]), 
      SegmentVal[GE: Functional Group Trailer](
        Nn.value[  E97: Number of Transaction Sets Included](1),
        Nn.value[  E28: Group Control Number](1))), 
    SegmentVal[IEA: Interchange Control Trailer](
      Nn.value[  I16: Number of Included Functional Groups](1),
      Nn.value[  I12: Interchange Control Number](905))))
49 segments
0.156 seconds

Json output

Hey,

For the sake of argument is there a way in which I can get json output of the transformed document.

830 PO v2001 - BFR segment cannot be reached from the current state

trying to parse something that loos like this:

SA*00*          *00*          *01*054481205      *01*126564801      *140801*0623*U*00200*000008573*0*P*:!
GS*PO*054481305*126224801*140801*0623*8573*X*002001!
ST*830*8573!
BFR*04**140801*DL*A*140801*140807*140801**CP!

I am able to iterate through all segments but for some reason, can't do it to BFR, instead of using .iterate I have to use something along these lines:

edi_data.first.flatmap do |isa|
      isa.iterate(:GS) do |gs|
        gs.find(:ST).flatmap{|x| x.find(:BFR) }
        .tap do |bfr|
          puts "#{bfr.element(1).map(&:node).fetch(0)}"
        end 
...

which works but I am confused as to why .iterate does not find that segment. I get following message Stupidedi::Exceptions::ParseError - BFR segment cannot be reached from the current state:

I think I might have introduced a bug while adding this particular message. Note: using edi-pp and edi-ed, both behave the data properly as expected.

Any thoughts as to why st.iterate(:BFR) might not behave as expected?

Type conversion to String in ID elements

For ID elements that are essentially numeric, like HL*03, it would be nice to allow numeric arguments like m.find(:HL, nil, nil, 20). Currently this throws an exception:

ArgumentError: 20 is not allowed in HL03

The workaround is to use strings for all ID elements: m.find(:HL, nil, nil, "20")

Extra space on TD5 segment

While generating a SH856, I am getting an extra space on TD5 on the second field (E66)

Example:

`TD5B2 XYZZM``

TD5 is defined as:

          TD5 = s::SegmentDef.build(:TD5, "Carrier Details (Routing Sequence/Transit Time)",
            "To specify the carrier and sequence of routing and provide transit time information",
            e::E133.simple_use(r::Optional,  s::RepeatCount.bounded(1)),
            e::E66 .simple_use(r::Mandatory,  s::RepeatCount.bounded(1)),
            e::E67 .simple_use(r::Mandatory,  s::RepeatCount.bounded(1)),
            e::E91 .simple_use(r::Relational, s::RepeatCount.bounded(1)))

and

E66 is defined as:

E66   = t::ID.new(:E66  , "Identification Code Qualifier"        , 1, 2,
            s::CodeList.build(
              "1"  => "D-U-N-S Number, Dun & Bradstreet",
              "2"  => "Standard Carrier Alpha Code (SCAC)",
...

Any ideas?

Rails4 delegate issue

back trace when I tried to start rails console:
/Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/bundler/gems/stupidedi-67bade054f9e/lib/ruby/module.rb:71:in class_eval': /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/actionpack-4.0.2/lib/abstract_controller/layouts.rb:212: syntax error, unexpected '.' (SyntaxError) class._layout_conditions(*args, &block) ^ from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/bundler/gems/stupidedi-67bade054f9e/lib/ruby/module.rb:71:inblock in delegate'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/bundler/gems/stupidedi-67bade054f9e/lib/ruby/module.rb:63:in each' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/bundler/gems/stupidedi-67bade054f9e/lib/ruby/module.rb:63:indelegate'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/actionpack-4.0.2/lib/abstract_controller/layouts.rb:212:in <module:Layouts>' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/actionpack-4.0.2/lib/abstract_controller/layouts.rb:200:inmodule:AbstractController'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/actionpack-4.0.2/lib/abstract_controller/layouts.rb:3:in <top (required)>' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/actionpack-4.0.2/lib/action_controller/base.rb:203:inclass:Base'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/actionpack-4.0.2/lib/action_controller/base.rb:163:in <module:ActionController>' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/actionpack-4.0.2/lib/action_controller/base.rb:4:in<top (required)>'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/rails-observers-0.1.2/lib/rails/observers/action_controller/caching.rb:10:in <module:Caching>' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/rails-observers-0.1.2/lib/rails/observers/action_controller/caching.rb:2:inmodule:ActionController'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/rails-observers-0.1.2/lib/rails/observers/action_controller/caching.rb:1:in <top (required)>' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:inrequire'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:in block in require' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:214:inload_dependency'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:in require' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/bundler/gems/audited-1db8f77a2aed/lib/audited/sweeper.rb:2:in<top (required)>'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:in require' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:inblock in require'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:214:in load_dependency' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:inrequire'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/bundler/gems/audited-1db8f77a2aed/lib/audited/adapters/active_record.rb:15:in <top (required)>' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:inrequire'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:in block in require' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:214:inload_dependency'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:in require' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/bundler/gems/audited-1db8f77a2aed/lib/audited-activerecord.rb:2:in<top (required)>'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/bundler-1.3.1/lib/bundler/runtime.rb:72:in require' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/bundler-1.3.1/lib/bundler/runtime.rb:72:inblock (2 levels) in require'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/bundler-1.3.1/lib/bundler/runtime.rb:70:in each' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/bundler-1.3.1/lib/bundler/runtime.rb:70:inblock in require'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/bundler-1.3.1/lib/bundler/runtime.rb:59:in each' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/bundler-1.3.1/lib/bundler/runtime.rb:59:inrequire'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/bundler-1.3.1/lib/bundler.rb:132:in require' from /Users/K/dev/code/mom/qt_mcwhiskers/config/application.rb:12:in<top (required)>'
from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/railties-4.0.2/lib/rails/commands.rb:60:in require' from /Users/K/.rvm/gems/ruby-2.0.0-p353@momcorp/gems/railties-4.0.2/lib/rails/commands.rb:60:in<top (required)>'
from bin/rails:4:in require' from bin/rails:4:in

'

writing document fails (no method error "present?")

Trying to generate an EDI document using the sample code from the documentation:

b.machine.zipper.tap do |z|
  # The :component, and :repetition parameters can also be specified as elements
  # of the ISA segment, at `b.ISA(...)` above. When generating a document from
  # scratch, :segment and :element must be specified -- if you've parsed the doc
  # from a file, these params will default to whatever was used in the file, or
  # you can override them here.
  separators =
    Stupidedi::Reader::Separators.build :segment    => "~\n",
                                        :element    => "*",
                                        :component  => ":",
                                        :repetition => "^"

  # You can also serialize any subtree within the document (e.g., everything inside
  # some ST..SE transaction set, or a single loop. Here, z.root is the entire tree.
  w = Stupidedi::Writer::Default.new(z.root, separators)
  w.write($stdout)
end

Getting the following no method error:

/Users/mkruk/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/stupidedi-1.2.6/lib/stupidedi/reader/separators.rb:53:in `select': undefined method `present?' for ":":String (NoMethodError)
Did you mean?  prepend
    from /Users/mkruk/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/stupidedi-1.2.6/lib/stupidedi/reader/separators.rb:53:in `characters'
    from /Users/mkruk/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/stupidedi-1.2.6/lib/stupidedi/writer/default.rb:19:in `write'
    from script/generate_997.rb:59:in `block in <main>'
    from /Users/mkruk/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/stupidedi-1.2.6/lib/stupidedi/either.rb:152:in `deconstruct'
    from /Users/mkruk/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/stupidedi-1.2.6/lib/stupidedi/either.rb:127:in `tap'
    from script/generate_997.rb:44:in `<main>'

Thought that it was my ruby version, upgraded to 2.3.0, but still no luck. It seems like maybe this is an issue with refinements? Any help would be appreciated.

Incorrect variable use in exception block?

In file \stupidedi\lib\stupidedi\guides\004010\guide_builder.rb

line 83

              unless e_requirement.forbidden?
                unless e_arguments.length == u.definition.component_uses.length
                  raise Exceptions::InvalidSchemaError,
                    "composite element #{u.definition.id} at #{segment_def.id}" <<
                    "#{element_index} has #{u.definition.element_uses.length}" <<
                    " component elements but #{e_arguments.length} were given"
                end

variable ....element_uses.length should be ...component_uses.length

right now I get the following exception when hitting the InvalidSchemaError exception:

guide_builder.rb:83:in `block in Segment': undefined method `element_uses' for #<Stupidedi::Schema::CompositeElementDef:0x3fb26d5df2a0 ...> (NoMethodError)

Floating Fields?

@kputnam Did you ever heard of Usage: Floating?

I have come across a more accurate specs for one of the messages I implemented and realized a segment I struggle with happens to be Floating.

It appears floating means that it can appear anywhere. Any thoughts on how to handle this?

834 fails on parsing

https://github.com/kputnam/stupidedi/blob/master/spec/fixtures/X220-BE834/3-good.txt
Fails on parsing 834 data:

TransmissionVal(
  InterchangeVal[00501](
    SegmentVal[ISA: Interchange Control Header](
      ID.value[  I01: Authorization Information Qualifier](00: No Authorization Information Present (No Meaningful Information in I02)),
      AN.value[  I02: Authorization Information](..........),
      ID.value[  I03: Security Information Qualifier](01: Password),
      AN.value[  I04: Security Information](SECRET....),
      ID.value[  I05: Interchange ID Qualifier](ZZ: Mutually Defined),
      AN.value[  I06: Interchange Sender ID](SUBMITTERS.ID..),
      ID.value[  I05: Interchange ID Qualifier](ZZ: Mutually Defined),
      AN.value[  I07: Interchange Receiver ID](RECEIVERS.ID...),
      DT.value[  I08: Interchange Date](XX03-01-01),
      TM.value[  I09: Interchange Time](12:53:ss),
      SeparatorElementVal.value[I65](^),
      ID.value[  I11: Interchange Control Version Number](00501: Standards Approved for Publication by ASC X12 Procedures Review Board through October 2003),
      Nn.value[  I12: Interchange Control Number](905),
      ID.value[  I13: Acknowledgment Requested](1: Interchange Acknowledgment Requested (TA1)),
      ID.value[  I14: Interchange Usage Indicator](T: Test Data),
      SeparatorElementVal.value[I15](:)), 
    FunctionalGroupVal[005010](
      SegmentVal[GS: Functional Group Header](
        ID.value[ E479: Functional Identifier Code](BE: Benefit Enrollment and Maintenance),
        AN.value[ E142: Application's Sender Code](SENDER CODE),
        AN.value[ E124: Application Receiver's Code](RECEIVER CODE),
        DT.value[ E373: Date](1999-12-31),
        TM.value[ E337: Time](08:02:ss),
        Nn.value[  E28: Group Control Number](1),
        ID.value[ E455: Responsible Agency Code](X: Accredited Standards Committee X12),
        AN.value[ E480: Version / Release / Identifier Code](005010X220)), 
      InvalidEnvelopeVal(
        unknown transaction set "BE" "834" "005010X220",
        InvalidSegmentVal[ST],
        InvalidSegmentVal[BGN],
        InvalidSegmentVal[N1],
        InvalidSegmentVal[N1],
        InvalidSegmentVal[INS],
        InvalidSegmentVal[REF],
        InvalidSegmentVal[REF],
        InvalidSegmentVal[DTP],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[PER],
        InvalidSegmentVal[N3],
        InvalidSegmentVal[N4],
        InvalidSegmentVal[DMG],
        InvalidSegmentVal[HD],
        InvalidSegmentVal[DTP],
        InvalidSegmentVal[LX],
        InvalidSegmentVal[NM1],
        InvalidSegmentVal[SE]), 
      SegmentVal[GE: Functional Group Trailer](
        Nn.value[  E97: Number of Transaction Sets Included](1),
        Nn.value[  E28: Group Control Number](1))), 
    SegmentVal[IEA: Interchange Control Trailer](
      Nn.value[  I16: Number of Included Functional Groups](1),
      Nn.value[  I12: Interchange Control Number](905))))
22 segments
0.139 seconds

Looks as if it does not like the transaction set BE. Ive also run this over some "valid" 834 files in my company with the same result, getting stuck in set BE.

Any ideas?

While traversing the document, elements cant be found using find method or element method

I tried traversing a HB271 document but it doesn't generate expected results. Can you just give a small demo as in how to traverse a document. I tried it multiple times with failure.
I tried positioning the cursor at first and could find ISA and GS segment, but nothing from there after and received message saying that segment is unreachable from current state.

"can't modify frozen String" from float_val.rb while generating 837 output

Using ruby 2.3.1 and latest stupidedi (1.2.9), I get the following error when trying to generate 837 output. Not sure exactly which field is triggering it, but it's some numeric one based on the stack trace. The code there (in float_val.rb) does look a bit suspicious with regards to frozen strings.

"can't modify frozen String"

stupidedi (1.2.9) lib/stupidedi/versions/functional_groups/005010/element_types/float_val.rb:295:in `to_x12'

composite elements - error parsing

I got the following composite element definition

          C001  = Schema::CompositeElementDef.build(:C001,
            "Composite Unit of Measure",
            "To identify a composite unit of measure",
            E355.component_use(r::Mandatory, s::RepeatCount.bounded(1)),
            E0  .component_use(r::Optional),
            E0  .component_use(r::Optional),
            E355.component_use(r::Optional,  s::RepeatCount.bounded(1)),
            E0  .component_use(r::Optional),
            E649.component_use(r::Optional,  s::RepeatCount.bounded(1)))

the data trying to parse is

UIT*PC>>>LB>>17.5*61.95

I am getting this exception

/usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/ruby/try.rb:20:in `try': undefined method `>' for #<Stupidedi::Schema::ComponentElementUse:0x3                    ffe442be9cc ...> (NoMethodError)
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/versions/functional_groups/004010/element_types/float_val.rb:16:in `ini                    tialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/versions/functional_groups/004010/element_types.rb:42:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/versions/functional_groups/004010/element_types.rb:42:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_use.rb:139:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_use.rb:145:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_use.rb:145:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_def.rb:95:in `block in initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_def.rb:95:in `map'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_def.rb:95:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_def.rb:101:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_def.rb:101:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_use.rb:205:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_use.rb:211:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/element_use.rb:211:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_def.rb:35:in `block in initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_def.rb:35:in `map'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_def.rb:35:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_def.rb:41:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_def.rb:41:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_use.rb:43:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_use.rb:49:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/segment_use.rb:49:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/loop_def.rb:40:in `block in initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/loop_def.rb:40:in `map'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/loop_def.rb:40:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/loop_def.rb:48:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/loop_def.rb:48:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/table_def.rb:31:in `block in initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/table_def.rb:31:in `map'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/table_def.rb:31:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/table_def.rb:38:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/table_def.rb:38:in `copy'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/transaction_set_def.rb:23:in `block in initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/transaction_set_def.rb:23:in `map'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/transaction_set_def.rb:23:in `initialize'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/transaction_set_def.rb:83:in `new'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/schema/transaction_set_def.rb:83:in `build'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/contrib/004010/transaction_set_defs/PS830.rb:9:in `<module:TransactionS                    etDefs>'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/contrib/004010/transaction_set_defs/PS830.rb:4:in `<module:FortyTen>'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/contrib/004010/transaction_set_defs/PS830.rb:3:in `<module:Contrib>'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/contrib/004010/transaction_set_defs/PS830.rb:2:in `<module:Stupidedi>'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/contrib/004010/transaction_set_defs/PS830.rb:1:in `<top (required)>'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/config.rb:125:in `block (3 levels) in contrib'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/config/transaction_set_config.rb:67:in `call'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/config/transaction_set_config.rb:67:in `at'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/states/transaction_set_state.rb:76:in `push'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/generation.rb:82:in `block (2 levels) in insert'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/generation.rb:36:in `each'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/generation.rb:36:in `block in insert'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/generation.rb:27:in `each'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/generation.rb:27:in `insert'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/generation.rb:14:in `block in read'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/reader/result.rb:102:in `call'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/reader/result.rb:102:in `deconstruct'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/either.rb:102:in `flatmap'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/lib/stupidedi/builder/generation.rb:12:in `read'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/bin/edi-pp:25:in `block (2 levels) in <top (required)>'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/bin/edi-pp:24:in `open'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/bin/edi-pp:24:in `block in <top (required)>'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/bin/edi-pp:18:in `each'
        from /usr/local/lib/ruby/gems/2.0.0/gems/stupidedi-1.1.0/bin/edi-pp:18:in `<top (required)>'
        from /usr/local/bin/edi-pp:23:in `load'
        from /usr/local/bin/edi-pp:23:in `<main>'

I believe I have things setup properly on my end.

Any thoughts?

hash.present? conflict between rails 4.2.4 and tins 1.x

Recently when I attempted to upgrade to use rails 4.2.4, along with stupidedi, I came across a method definition conflict.
stupidedi depends on term-ansicolor, which depends on tins. Tins add present? method to Hash.
rails 4.2.4 also add present? method to Hash in its active support core extensions.
The semantics of the above two methods are different.
Does stupidedi depend on term-ansicolor only because of being able to color the terminal output? If so, is there some way I can turn it off and remove that dependency? or other suggestions? Thanks.

Unable to create 210: 'unknown transaction set "IM" "210" "004010"'

I'm trying to create a 210. When I try to create the ST, I get the above error.

This is quite the grammar engine you've built here. AFAICT, this is happening because we're missing a suitable entry in lib/stupidedi/config/contrib/004010/guides.

I've done:
`builder.ISA "00", nil, "00", nil, "02", "ANOC", "ZZ", "PANALPINA", "160611", "1457", "U", "00400", "1", "0", "T", ">"

builder.GS "IM", "ANOC", "PANALPINA", "20160611", "1457", "1", "X", "004010"

builder.ST "210", "0001"`

at which point I get the error. I'd be grateful to know if this is a bug or I'm doing something wrong.

Many thanks.

cannot move to next after last node

While generating EDI 856 SH, I am getting this error. As far as I can tell this is a valid transition.

Here is my code

builder.DTM "011",req_date, req_time
  builder.HL "1", nil, "S"
  builder.MEA "PD", "G", weight_total, "LB", "0", "0"

call stack:

 stupidedi (1.2.2) lib/stupidedi/zipper/memoized_cursor.rb:44:in `next'
 - stupidedi (1.2.2) lib/stupidedi/zipper/abstract_cursor.rb:208:in `child'
 - stupidedi (1.2.2) lib/stupidedi/schema/syntax_note.rb:54:in `block in children'
 - stupidedi (1.2.2) lib/stupidedi/schema/syntax_note.rb:54:in `children'
 - stupidedi (1.2.2) lib/stupidedi/versions/functional_groups/002001/syntax_notes.rb:51:in `required'
 - stupidedi (1.2.2) lib/stupidedi/schema/syntax_note.rb:40:in `satisfied?'
 - stupidedi (1.2.2) lib/stupidedi/builder/builder_dsl.rb:174:in `block in critique'
 - stupidedi (1.2.2) lib/stupidedi/builder/builder_dsl.rb:171:in `critique'
 - stupidedi (1.2.2) lib/stupidedi/builder/builder_dsl.rb:48:in `block in segment!'
 - stupidedi (1.2.2) lib/stupidedi/builder/builder_dsl.rb:48:in `segment!'
 - stupidedi (1.2.2) lib/stupidedi/builder/builder_dsl.rb:93:in `method_missing'
 - app/models/edi856_sh2001.rb:201:in `create_edi'

stupidedi does not add end segments

In the example for generating an EDI file on README.md, the declarations of the end segments are omitted. I assumed that this was because stupidedi would generate them for me. However, when I copy that example into a ruby script and then change the definition of config to the following:

config = Stupidedi::Config.default
config.interchange.register("00501") {Stupidedi::Versions::Interchanges::FiveOhOne::InterchangeDef}
config.functional_group.register("005010") {Stupidedi::Versions::FunctionalGroups::FiftyTen::FunctionalGroupDef}
config.transaction_set.register("005010X222", "HC", "837") {Stupidedi::Guides::FiftyTen::X222::HC837P }
b = Stupidedi::Builder::BuilderDsl.build(config)

I have to change this definition or else it doesn't work at all. Anyway, when I do this, the output I get is missing the SE, GE, and IEA segments.

Iterate error: block did not return an instance of Either

I'm using the following to iterate over segments:

a.flatmap do |isa|
  isa.iterate(:GS) do |gs|
    gs.iterate(:ST) do |st|
      st.tap do |m|
         el(m.find(:L11, nil, '2I'), 1){|e| puts "Tracking Number: #{e}" }
      end
    end
  end
end

That works well, except after it's successfully iterated through all of the ST's, it throws this error:

TypeError: block did not return an instance of Either
   from /bundler/gems/stupidedi-499b645a6675/lib/stupidedi/either.rb:107:in `flatmap'
   from (irb):107
   from /gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
   from /gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
   from /gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
   from script/rails:6:in `require'
   from script/rails:6:in `<main>'

Fails on valid file

Doing this:

input = File.open("file.x12", :encoding => "ISO-8859-1")
config = Stupidedi::Config.default
p, result = parser.read(Stupidedi::Reader.build(input))

Fails on this believed-good input:
ISA_00_ 00 _ZZ_PANALPINA 02_ANOC 160503_2119_U_00401_000000001_0_T
GS_SM_PANALPINA_ANOC_20160503_2119_1_X_004010
ST_204_000000001
B2ANOC715658442-01PP
B2A_00
L11_PALA_SCA
L11_TPE540871_HB
L11_69539112301_MB
G62_11_20160430
AT5_DEL
NTE
DISPATCHER: Diane Johnson, [email protected]
S5_1_LD_218.00_L_1_PC
G62_69_20160430_U_0800
G62_69_20160430_K_1000
NTE**SL8D# 8296498DOCK HIGH TRUCK NEEDED
N1_SF_EVA AIRWAYS
N3_BLDG.151 JFK AIRPORT
N4_Jamaica_NY_11430
G61_IC_ISF PAYS THRU EPIC_TE_718-2445500
L5_1_WAFERSTEPPER COMPONENT LT ME ADJ. TOOL SET Q'TY:
S5_2_UL_218.00_L_1_PC
G62_70_20160430_X_1400
N1_ST_ASML C/O DB SCHENKER
N3_6 OLD STONE BREAK ROAD hrs:7day
/week 0700-1900,dock high 50lbs
N4_Ballston Spa_NY_12020
G61_IC_Receiving_TE_518-256-9197
L3_218.00*G********_1_L
SE_26_000000001
GE_1_1
IEA_1_000000001

Medicare Claim to 837 EDI

Im getting this error when try to generate EDI:
Stupidedi::Exceptions::ParseError: unknown transaction set "HC" "837" "005010X223A1"

Code:

config = Stupidedi::Config.default

config.interchange.register("00501") {Stupidedi::Versions::Interchanges::FiveOhOne::InterchangeDef}
config.functional_group.register("005010") {Stupidedi::Versions::FunctionalGroups::FiftyTen::FunctionalGroupDef}
config.transaction_set.register("005010X223", "HC", "837") { Stupidedi::Guides::FiftyTen::X222A1::HC837I }
b = Stupidedi::Builder::BuilderDsl.build(config)

b = Stupidedi::Builder::BuilderDsl.build(config)

# These methods perform error checking: number of elements, element types, min/max
# length requirements, conditionally required elements, valid segments, number of
# segment occurrences, number of loop occurrences, etc.
b.ISA "00", nil, "00", nil,
      "ZZ", fed_tax_number,
      "ZZ", receiver_id,
      submission_date, submission_time, '^', "00501", "000000111", "1", "#{mode}", ':'

# The API tracks the current position in the specification (e.g., the current loop,
# table, etc) to ensure well-formedness as each segment is generated.
b.GS "HC", fed_tax_number, receiver_id, submission_date_century, submission_time, "1", "X", "005010X223A1"

# The `b.default` value can be used to generate the appropriate value if it can
# be unambigously inferred from the grammar.
b.ST "837", "1234", b.default
  # You can use string representations of data or standard Ruby data types, like Time.
  b.BHT "0019", "00", "0000000333"*3, submission_date_century, submission_time, "CH"
  #Loop:2010AA
  b.NM1 b.default, "1", submitter_name, nil, nil, nil, nil, "46", claim.agency_npi
  b.PER "IC", submitter_contact_name, "EM", submitter_contact_person_email, "TE", submitter_contact_person_phone_number

  b.NM1 "40", "2", receiver_name, nil, nil, nil, nil, "46", receiver_id
  b.HL "1", nil, "20", "1"

  b.PRV "BI", "PXC", provider_taxonomy_code

  b.NM1 "85", "2", submitter_name, nil, nil, nil, nil, "XX", billing_provider_npi_number
  b.N3  billing_provider_address1
  b.N4  billing_provider_city, billing_provider_state, billing_provider_zip_code

  b.REF "EI", fed_tax_number
  b.PER "IC", submitter_contact_name, "EM", submitter_contact_person_email, "TE", submitter_contact_person_phone_number


#loop2000B
b.HL "2", "1", "22", "0"
  b.SBR "P", individual_relationship_code, nil, nil, nil, nil, nil, nil, code_identifying_type_of_claim

  #Loop:2010BA
  b.NM1 "IL", "1", subscriber_last_name, subscriber_first_name, nil, nil, nil, "MI", subscriber_identifier
    b.N3  subscriber.street_address, subscriber_suite_number
    b.N4  subscriber.city, subscriber.state, subscriber.zip_code
    b.DMG "D8", claim.patient_dob_century_format, claim.patient_gender
    b.REF "SY", subscriber_ssn

#loop2010BB
b.NM1 "PR", "2", claim.payer_name, nil, nil, nil, nil, "PI", claim.provider_number
  b.N3 payer_address1
  b.N4 payer_city, payer_state, payer_zip_code


#loop2300
  b.CLM claim_id, claim.invoice_amount, nil, nil, b.composite("03", 'B', '2'), 'Y', 'A', 'Y','Y', 'P'
   #b.DTP "096", "TM", discharge_hour
    # b.DTP "434", "RD8", statement_covers_period
  # b.DTP "435", "DT", admission_date
  # b.CL1 nil, claim.src, claim.status_of_discharge
  #b.HI b.composite('BE', '61', nil, nil, claim.value_codes)



  #ICD9 Diagnosis Codes
  claim.icd_9.each do |icd|
    b.HI b.composite("BK","#{icd}")
  end

#loop2400 SERVICE LINE
claim.receivables.each_with_index do |receivable, index|
  b.LX "#{index+1}"
  # b.NM1 "IL", "1", claim.primary_physician_last_name, claim.primary_physician_first_name, claim.primary_physician_middle_initials, "XX", claim.primary_physician_npi
  #b.SV2 receivable.revenue_code, b.composite("HC","#{receivable.hcpcs_code}"), receivable.receivable_amount, "UN", receivable.service_units
  # b.DTP "472", "D8", receivable.receivable_date
end

  #loop2310A ATTENDING PROVIDER INFORMATION
   #b.NM1 "IL", "1", claim.primary_physician_last_name, claim.primary_physician_first_name, claim.primary_physician_middle_initials, "XX", claim.primary_physician_npi




b.machine.zipper.tap do |z|
  # The :component, and :repetition parameters can also be specified as elements
  # of the ISA segment, at `b.ISA(...)` above. When generating a document from
  # scratch, :segment and :element must be specified -- if you've parsed the doc
  # from a file, these params will default to whatever was used in the file, or
  # you can override them here.
  separators =
      Stupidedi::Reader::Separators.build :segment    => "~\n",
                                          :element    => "*",
                                          :component  => ":",
                                          :repetition => "^"

  # You can also serialize any subtree within the document (e.g., everything inside
  # some ST..SE transaction set, or a single loop. Here, z.root is the entire tree.
  w = Stupidedi::Writer::Default.new(z.root, separators)
  w.write($stdout)
end

uninitialized constant Stupidedi::Builder::BuilderDsl::Set (NameError)

I was playing around with getting the example builder working in ruby verions 1.9.3 and ruby 2.0.0. However, I kept running the error that is listed in the title. From everything I gathered, the ruby "Set" class was not being included properly.

I was able to include the Set object in either of the following locations and building the sample EDI worked.

  • Sample script file with the builder
  • /lib/stupidedi/builder/builder_dsl
require 'set'

I could put in a pull request for this but I am also unsure if/where you would want the set require to be. Also, I don't know if it's intended for the Set object to be required in the application that interacts with stupidedi. Thoughts?

Rails 4.1 ActiveSupport MultiJSON

I am trying to add stupidedi to my project.

After adding stupidedi, immediately upon logging into my application (I am using Devise) I receive the following error,

ArgumentError - In Rails 4.1, ActiveSupport::JSON.decode no longer accepts an options hash for MultiJSON. MultiJSON reached its end of life and has been removed.

I saw what looked like a similar issue here,
#67

I removed term-ansicolor and tins from the dependencies. I also tried adding the multi_json gem to the stupidedi gem dependencies. Neither approach fixed the error.

Here is what I could find regarding Rails 4.1 and multijson
http://guides.rorlab.org/4_1_release_notes.html

Thank you for your help with this issue, let me know if you would like any additional information.

SH856 - Parsing Specific Loop / Navigating Document

I am having a hard time understanding exactly how to navigate with the API.

There are multiple Loop definitions for HL (one for the shipment, and one for each line item).

I am able to extract information for the first HL loop, but not the second one.

Here is the sample file:

ISA*00*          *00*          *ZZ*941714834VANP  *ISA Prefix*ISA Identifier *141001*1224*U*00401*410011224*0*P*>~
GS*SH*9417148340022*GSIdentifier*20141001*1224*8*X*004010~
ST*856*0007~
BSN*00*478157*20141001~
DTM*011*20141001~
HL*1**S~
TD5**2*FDEP*J~
REF*L2*1412105525~
N1*ST*COMPANY NAME~
N3*100 INFORMATION SUPER HIGHWAY*SUITE 66~
N4*BEVERLY HILLS*CA*90210~
HL*2*1*I~
LIN*1*BP*077775136920~

SN1**1*EA~
PRF*1412105525~
REF*WY*testwaybill95642634~
HL*3*2*X~
REF*BG*CLB1140010001~
SDQ*EA**ZZ*1~
SE*18*0007~
GE*1*8~
IEA*1*410011224~

Ruby Code:

            parser.first
              .flatmap{|m| m.sequence(:GS, :ST, :BSN, :DTM, :HL) }
              .tap do |m|
                el(m.find(:TD5), 3){|e| puts "Carrier SCAC: #{e}" }
              end
              .tap do |m|
                el(m.find(:REF), 2){|e| puts "OrderID: #{e}" }
              end
              .flatmap {|m| m.sequence(:HL) }
              .tap do |m|
                el(m.find(:REF), 1){|e| puts "WayBill: #{e}" }
              end

Output:

Carrier SCAC: FDEP
OrderID: 1412105525
Stupidedi::Exceptions::ParseError: REF segment cannot be reached from the current state

For more requirements, I'd only need the Carrier, OrderID, and a single WayBill for each document if that will make a difference.

Iterating ISA segments doesn't work

When we're positioned on an ISA segment, calling find(:ISA) never finds the next ISA segment. This may be due to a regression caused by #7, if we're ignoring

Instruction[ISA](pop: 1, drop: 0, push: InterchangeState)

when searching with #find because

Instruction[ISA](pop: 2, drop: 0, push: TransmissionState)

is favored, since it pops more nesting levels. This is one case were we actually don't create a new parent container, since TransmissionVal is the root and shouldn't have siblings. The fix might require a special case in ConstraintTable.

required element ISA02 is blank

I have the have the following definition data element summary definition:

M            ISA02             I02             Authorization Information     M  AN 10/10
Key Point:
Must be 10 spaces

it is a mandatory field but must contain 10 spaces. Any way to work around this?

I am trying to build the output file using:

config = Stupidedi::Config.contrib
    builder = Stupidedi::Builder::BuilderDsl.build(config)

    builder.ISA "00", "          ", "00", "          ",
      "01", "005548384",
      "01", "126444801",
      "990531", "1230", "U", "00200", "63373", "0", "P", ":"

The 4010 PO850 in contrib doesn't work

Some of the segments in the PO850 don't have enough elements to match their definitions. This results in an exception about not having the right number of elements. I'd like to fix it by adding some of them to it, but I would need the PDF that originally informed these definitions.

214: E66, E706 elements declared mandatory

I'm trying to create a 214 (Carrier Shipment Status Notification). I'm trying to create the N1 element,

b.N1 "SH", "SILVERADO VINEYARDS C/O DFS", "1"

but I'm being told that N103 and N104 elements are required.

Stupidedi::Exceptions::ParseError: value is too short in element N103

This would appear to be in functional_groups/004010/segment_defs/N1.rb.

I'm a little new to this EDI business, but from specifications I read (eg http://www.ryder.com/supply-chain/~/media/Ryder/Files/SupplyChain/EDIspecs/carrier_214.ashx) that these elements should not be marked as required.

I believe the correct code would be:

          N1  = s::SegmentDef.build(:N1, "Name",
            "To identify a party by type of organization, name, and code",
            e::E98  .simple_use(r::Mandatory,  s::RepeatCount.bounded(1)),
            e::E93  .simple_use(r::Mandatory, s::RepeatCount.bounded(1)),
            e::E66  .simple_use(r::Optional, s::RepeatCount.bounded(1)),
            e::E67  .simple_use(r::Optional, s::RepeatCount.bounded(1)),
            e::E706 .simple_use(r::Optional,   s::RepeatCount.bounded(1)),
            e::E98  .simple_use(r::Optional,   s::RepeatCount.bounded(1)),

Many thanks for this project, and for your help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.