The Interchange or TA1 Acknowledgment is a means of replying to an interchange or transmission that has been sent. The TA1 acknowledgment verifies the envelopes only.
Transaction set-specific verification is accomplished through use of the Functional Acknowledgment Transaction Set, 997. See A.1.5.2, Functional Acknowledgment, 997, for more details.
In this example we create “Interchange Acknowledgment, TA1”. Creating “Functional Acknowledgment Transaction Set, 997” is subject for different example.
The TA1 is a single segment and is unique in the sense that this single segment is transmitted without the GS/GE envelope structures. A TA1 can be included in an interchange with other functional groups and transactions.
For complete description refer to A.1.5.1 in “Electronic Data Interchange Transaction Set Implementation Guide” for “HealthCare Eligibility Benefit Inquiry and Response” (Includes October 2002 Addenda Changes) the “270/271 Combined May 2000 004010X092 and October 2002” 004010X092A1
require 'x12node'
require 'x12TA1'
function main(Message)
   local In = x12.parse{
      vmd = 'x12.vmd', data = Message }
   local Out = x12.message{
      vmd = 'TA1.vmd',name = 'TA1' }
   Ack = x12TA1.TA1Ack_004010X091(In, Out)
   return Ack    
end
Example is using three shared files: x12node, subs, and x12TA1, presented below.
When dealing with conformance to Standard, many values forced to appear *hard-coded*. However, lists of *valid* values are subject to any specific interface implementation. Lists can be expanded with additional values as needed.
Shared file ‘x12node’:
-- node functions for use with X12
function node.N(n)
   return type(tonumber(n:nodeValue())) == "number" 
end
function node.S(n)
   return tostring(n)
end
function node.E(n)
   return ((#(string.gsub( n:nodeValue(),' ', ''))) == 0)
end
function node.L(n,l)
   for i, v in ipairs(l) do
      if  string.gsub( n:nodeValue(), ' ', '') == v then
         return true
      end
   end
end
Shared file ‘x12TA1’:
Functions in this file bound by recommendations and “hardcoded” values based on document “Electronic Data Interchange Transaction Set Implementation Guide” for “HealthCare Eligibility Benefit Inquiry and Response” (Includes October 2002 Addenda Changes) the “270/271 Combined May 2000 004010X092 and October 2002” 004010X092A1
x12TA1 = {}
local function toX12(S)
   S = string.gsub (S, "|", "*")
   S = string.gsub (S, "r", "~")
   return string.gsub(S..'~',"*~","~")
end
local function TA105_004010X091(n)
    -- supported Standard List
    SSL =
        {'U'}
    -- supported Controls Version List
    SCV =
        {'00401'}
    -- valid Interchange ID Qualifier For Sender List
    VIIQFS =
        {'01','14','20','27','28','29','30','33','ZZ'}
    -- valid Interchange Sender ID List
    VISI =
        {'345529167','Sender'}
    -- valid Interchange ID Qualifier For Receiver List
    VIIQFR =
        {'01','14','20','27','28','29','30','33','ZZ'}
    -- valid Interchange Receiver ID List
    VIRI =
        {'445483154','ReceiverID','4000136'}
    -- valid Authorization Information Qualifier Value List
    VAIQV =
        {'00','03'}
    -- valid Security Information Qualifier Value List
    VSIQV =
        {'00','01'}
    I07L = 15
    I01L = 10
    I03L = 10
    I11L = 5
   if n.ISA[13]:nodeValue() ~= n.IEA[2]:nodeValue() then
      return '001'
   end
   if n.ISA[13]:E() then
      return "018"
    end
    if n.IEA[2]:E() then
      return "018"
    end
   if not n.ISA[13]:N() then
      return "018"
    end
    if not n.IEA[2]:N() then
      return "018"
    end
     if not n.ISA[11]:L(SSL) then
      return "002"
    end
     if n.ISA[11]:E() then
      return "016"
    end
    if #(n.ISA[11]:nodeValue()) > 1 then
      return "016"
    end
    if not n.ISA[12]:L(SCV) then
      return "003"
    end
    if not n.ISA[5]:L(VIIQFS) then
      return "005"
    end     
    if not n.ISA[7]:L(VIIQFR) then
      return "007"
    end
   if #(n.ISA[8]:nodeValue()) > I07L
            or n.ISA[8]:E() then
      return "008"
    end
    if not n.ISA[8]:L(VIRI) then
       return "009"
    end
    if not n.ISA[1]:L(VAIQV) then
      return "010"
    end                                           
    if n.ISA[1]:nodeValue() == '00' and
            not n.ISA[2]:E()
            then
       return '011'
    end        
    if n.ISA[1]:nodeValue() == '03' and
            n.ISA[2]:E()
            then
       return '011'
    end
    if n.ISA[1]:nodeValue() == '03' and
            #(n.ISA[2]:nodeValue()) > I01L
            then
       return '011'
    end
    if not n.ISA[3]:L(VSIQV) then
      return "012"
    end
    if n.ISA[3]:nodeValue() == '00' and
            not n.ISA[4]:E()
            then
       return '013'
    end
    if n.ISA[3]:nodeValue() == '03' and
            n.ISA[4]:E()
            then
       return '013'
    end
    if n.ISA[3]:nodeValue() == '03' and
            #(n.ISA[4]:nodeValue()) > I03L
            then
       return '013'
    end
    if n.ISA[9]:nodeValue() ~=
       os.date("%y%m%d",os.time{
            year = "20"..string.sub(
               n.ISA[9]:nodeValue(),1,2
            ),
            month = string.sub(
               n.ISA[9]:nodeValue(),3,4
            ),
            day = string.sub(
               n.ISA[9]:nodeValue(),5,6
            ),
            hour = string.sub(
               n.ISA[10]:nodeValue(),1,2
            ),
            minute = string.sub(
               n.ISA[10]:nodeValue(),3,4
            )}
      ) then
       return "014"
    end
    if n.ISA[10]:nodeValue() ~=
       os.date("%H%M",os.time{
            year = "20"..string.sub(
               n.ISA[9]:nodeValue(),1,2
            ),
            month = string.sub(
               n.ISA[9]:nodeValue(),3,4
            ),
            day = string.sub(
               n.ISA[9]:nodeValue(),5,6
            ),
            hour = string.sub(
               n.ISA[10]:nodeValue(),1,2
            ),
            minute = string.sub(
               n.ISA[10]:nodeValue(),3,4
            )}
      ) then
       return "015"
     end     
    if #(n.ISA[12]:nodeValue()) ~= I11L then
       return '017'
    end              
    return '000'   
end
function x12TA1.TA1Ack_004010X091(In, Out)
   InIE = In.IE
   Out.ISA = InIE.ISA
   Out.IEA = InIE.IEA
   Out.ISA[14] = '0'
   Out.ISA[16] = ':'
   Out.TA1[1] = InIE.IEA[2]
   Out.TA1[2] = InIE.ISA[9]
   Out.TA1[3] = InIE.ISA[10]
   Out.TA1[5] = TA105_004010X091(InIE)
   if Out.TA1[5]:nodeValue()  == '000' then
      Out.TA1[4] = 'A'
   else
      Out.TA1[4] = 'R'
   end     
   return (toX12(Out:S()))
end
Two generic vmd files added to “other” files: X12.vmd and TA1.vmd (attached below). Both are generic and dealing only with those parts of X12 message structure which are relevant in scope of automatic generation of TA1 Acknowledgment. There is no practical need to expand (AKA complicate) these vmd files to deal with other particulars of X12 messages. This example shows TA1 for 270/271 “HealthCare Eligibility Benefit Inquiry and Response” scenario, but in similar way it can be reworked to service acknowledgments to other transactions.
