How to sanity check X12 interchange content format

Before processing EDI content, we need to validate whether data is in compatible to Standard and processor requirements format.

Some format incompatibilities can be recovered from automatically, and some not.

On this page we will see how to evaluate given data format to match some of Standard definitions, one example with automatic recovery and the other will require to reject given data.

Personally, I would have chosen to validate every EDI interchange format, as a routine, before processing the content data.

Using the project and sample data from page How to approach X12 parsing, we add functionality.

There is additional example of content validation on page Automatic TA1 acknowledgment to X12 messages

require ('split') -- http://wiki.interfaceware.com/534.html

function trace (a,b,c,d) return end

function EDIformatSanity(d)

   local function ISAL()
      if d:find('GS') - #'ISA' - 1 < 103 then
         return false
      end
      return true
   end

   local function chunkedEqually()      
      local a = {}
      a = d:split('r')      

      if #a > 1 then 
         if #a[1] == #a[2] and #a[1] == #a[#a-1] then
            return true      
         end
         return false
      end

      return false
   end

   local errid, reason = {}, {}

   if not ISAL() then
      errid[#errid+1], reason[#errid+1] = 1, 'ISA segment too short.'
   end

   if chunkedEqually() then
      errid[#errid+1], reason[#errid+1] = 2, 'Message is in equal length lines.'
   end

   return errid, reason
end

function consolidateMessage()
   --TBD
end

function returnNack()
   --TBD
end

function main(Data)  

   local function readMyFile(fn)
      local f = assert(io.open(fn, 'rb'))
      local d = f:read('*a')
      f:close()      
      return d
   end

   local Data = readMyFile('/Users/levblum/270BlueCrossEdited.edi')

   -- Sanity test ISA segment
   -- Sanity test general appearance of Data

   local errid, reason = EDIformatSanity(Data)

   if #errid > 0 then

      for i = 1, #errid do

         if errid[i] == 1 then -- example of error which cannot be recovered from
            iguana.logDebug(reason[i])
            trace(reason[i])
            returnNack()  -- return Nack ? 
         end

         if errid[i] == 2 then -- example of error which we can recover from
            iguana.logDebug(reason[i])
            trace(reason[i])
            consolidateMessage(Data) -- fix Data
         end 

      end
   end     
end