x12 ISA (header) validation

293 views
Skip to first unread message

Jason Capriotti

unread,
May 11, 2016, 12:17:24 PM5/11/16
to Bots Open Source EDI Translator
Hello,
In using Bots to process x12 files, we are making calls to a third-party system in order to do some validation on the sender/receiver found in the ISA header of the document. If validation does not pass, we want the file to fail and a 997 response to be sent with a "rejected" status.

The problem we are running into is we are doing this in a map. Errors thrown with in a map will not trigger the "rejected" status to be reflected in the 997 (which makes sense). 

I am wondering if there is a different place to do ISA/header validation, before translation occurs?

Thanks
Jason

henk-jan ebbers

unread,
May 11, 2016, 2:28:50 PM5/11/16
to bots...@googlegroups.com
hi Jason,

this code:
def get_frompartner(thisnode):
partner = thisnode.get({'BOTSID':'UNB','S002.0004':None})
return partner

structure = [
{ID:'UNB',MIN:0,MAX:99999,
QUERIES:{
'frompartner': get_frompartner,
},

works in a grammar.
in the QUERIES, instead of having something like: 'frompartner': {'BOTSID':'UNB','S002.0004':None},
the name of a function is used (frompartner).
the function is just above.

this migth help.
if you would validate in sender/receiver in such a fucntion,
you could thow an error there.
(do not know if throwing an error works over there....give it a try ;-))

kind regards,
henk-jan
> --
> You received this message because you are subscribed to the Google Groups "Bots Open Source EDI Translator" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to botsmail+u...@googlegroups.com <mailto:botsmail+u...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.

Jason Capriotti

unread,
May 11, 2016, 3:38:36 PM5/11/16
to Bots Open Source EDI Translator
Thanks; I've been wondering about putting code in the grammar.

I made a simple example to test with (see below), but unfortunately it doesn't work. The error is thrown, but that causes the message to have "errorfatal" = True, which then causes the 997/acknowledgement to not send. Currently investigating workarounds to see if I'm missing anything...


My Test Code:
def validate(thisnode):
raise StandardError

structure = [
{ID: 'ISA', MIN: 0, MAX: 99999,
QUERIES: {
'validate': validate
},

Jason Capriotti

unread,
May 11, 2016, 5:51:01 PM5/11/16
to Bots Open Source EDI Translator
So I think the route I'm going to go is use a custom map for the outgoing 997. I noticed the x12 'handleconfirm' method supports using maps, so I think this will work. It shouldn't be too hard to get the validation results in there, and set the ack/reject character accordingly.


On Wednesday, May 11, 2016 at 1:28:50 PM UTC-5, eppye wrote:

henk-jan ebbers

unread,
May 11, 2016, 7:33:14 PM5/11/16
to bots...@googlegroups.com
yes, that would be next suggestion.

kind regards,
henk-jan
> > To unsubscribe from this group and stop receiving emails from it, send an email to botsmail+u...@googlegroups.com <javascript:> <mailto:botsmail+u...@googlegroups.com <javascript:>>.
> > For more options, visit https://groups.google.com/d/optout <https://groups.google.com/d/optout>.

Jason Capriotti

unread,
May 12, 2016, 11:28:47 AM5/12/16
to Bots Open Source EDI Translator
I haven't quite got this working (yet), but it seems like it will work. 

One thing I noticed is the inn value passed to the map from handleconfirm doesn't have ta_info attached to it. I think I can get the information I need from the queries property (inn.queries), but this seems like a slight discrepancy from how other maps work.

Another comment... Outside of my desire to modify the 997, I'm wondering if there could be a way to tap into the header portion of the translation? Two ideas are:
  • Provide a new route exit point that fires between parsing the file and running the translations.
  • Maybe a better option is along the lines of adding a function the grammar, which is very easy... allow the grammar function to raise a MessageError which would stop processing (similar to when you're missing a mandatory field). 

The second bullet would look something like this...

In the grammar:
def validate(thisnode):
    raise MessageError('Some validation failed')

In bots/inmessage.py (parse_edi_file, after UnicodeError is caught):
except botslib.MessageError as e:
    ediobject.errorfatal = False  # Important to still allow confirmation to send
    ediobject.errorlist.append(e.msg)  # Important so the "real" MessageError is raised up in transform.py (when edifile.checkforerrorlist is called)

I could do a pull request for the inmessage.py update if it looks good, assuming I'm not missing a better way to do this.

Jason

Tom Westrick

unread,
May 12, 2016, 1:17:43 PM5/12/16
to Bots Open Source EDI Translator
You can access the ta_info using the following method:
senderQualifier = inn.ta_info['bots_accessenvelope'].children[0].get({'BOTSID':'ISA','ISA05':None}).rstrip()
senderId
= inn.ta_info['bots_accessenvelope'].children[0].get({'BOTSID':'ISA','ISA06':None}).rstrip()
receiverQualifier
= inn.ta_info['bots_accessenvelope'].children[0].get({'BOTSID':'ISA','ISA07':None}).rstrip()
receiverId
= inn.ta_info['bots_accessenvelope'].children[0].get({'BOTSID':'ISA','ISA08':None}).rstrip()

-Tom

Jason Capriotti

unread,
May 12, 2016, 1:44:01 PM5/12/16
to Bots Open Source EDI Translator
I'm not sure I follow. 

The inn object passed to the 997 translation does not have a ta_info property. So calling inn.ta_info fails with an error like "AttributeError: 'Node' object has no attribute 'ta_info'

Jason

henk-jan ebbers

unread,
May 12, 2016, 1:49:50 PM5/12/16
to bots...@googlegroups.com
read this 4 times.
still no idea what you are saying.

kind regards,
henk-jan

On 05/12/2016 05:28 PM, Jason Capriotti wrote:
> I haven't quite got this working (yet), but it seems like it will work.
>
> One thing I noticed is the *inn* value passed to the map from *handleconfirm* doesn't have *ta_info* attached to it. I think I can get the information I need from the *queries* property
> (inn.queries), but this seems like a slight discrepancy from how other maps work.
>
> Another comment... Outside of my desire to modify the 997, I'm wondering if there /could/ be a way to tap into the header portion of the translation? Two ideas are:
>
> * Provide a new route exit point that fires between parsing the file and running the translations.
> * Maybe a better option is along the lines of adding a function the grammar, which is very easy... allow the grammar function to raise a MessageError which would stop processing (similar to when
> you're missing a mandatory field).
>
>
> The second bullet would look something like this...
>
> *In the grammar:*
>
> def validate(thisnode):
> raise MessageError('Some validation failed')
>
>
> *In bots/inmessage.py (parse_edi_file, after UnicodeError is caught):*
> > > For more options, visit https://groups.google.com/d/optout <https://groups.google.com/d/optout> <https://groups.google.com/d/optout <https://groups.google.com/d/optout>>.

Jason Capriotti

unread,
May 12, 2016, 2:21:55 PM5/12/16
to Bots Open Source EDI Translator
Hah... sorry for the ramble. There are two things... Related to the earlier part of the thread, the ta_info object is not available in the 997 map function. In other maps, inn.ta_info is available, which jives with the documentation that says "In a mapping script this information is inn.ta_info". 

That other, longer part is not 100% related and is a suggestion that should probably a separate thread/topic.

henk-jan ebbers

unread,
May 14, 2016, 8:23:24 AM5/14/16
to bots...@googlegroups.com
hi Jason,

will try to explain (not saying it is good, just how it works now).

in translation you receive object message (inmessage, out=message)
object message has a ta_info dict.
object message has root -> node object (actually a tree of nodes (each node is edi-record, or segment))

in that 997 you receive a node obejct, which indeed does not have the ta_info dict.
note that what 997 receives is not the message (starting with ST), but edi-file (ISA).
997 is generated for GS-level....

hope this makes sense
henk-jan

henk-jan ebbers

unread,
May 14, 2016, 8:30:19 AM5/14/16
to bots...@googlegroups.com
hi Jason,

but I admit it is a good idea!
like using in translation:
raise StopInterchange("blah blah reason ro rejecting interchange blah blah")

kind regards
henk-jan

On 05/11/2016 06:17 PM, Jason Capriotti wrote:

henk-jan ebbers

unread,
May 14, 2016, 8:52:58 AM5/14/16
to bots...@googlegroups.com


On 05/12/2016 05:28 PM, Jason Capriotti wrote:
> I haven't quite got this working (yet), but it seems like it will work.
>
> One thing I noticed is the *inn* value passed to the map from *handleconfirm* doesn't have *ta_info* attached to it. I think I can get the information I need from the *queries* property
> (inn.queries), but this seems like a slight discrepancy from how other maps work.
>
> Another comment... Outside of my desire to modify the 997, I'm wondering if there /could/ be a way to tap into the header portion of the translation? Two ideas are:
>
> * Provide a new route exit point that fires between parsing the file and running the translations.
>
will note that one.
but that would be a quite complicated one with limited use case, as far as I can see -> but convince me!
check transform.py. around line 168
first except clause catches from message (not edi file)
(should add specific exception type here)



> * Maybe a better option is along the lines of adding a function the grammar, which is very easy... allow the grammar function to raise a MessageError which would stop processing (similar to when
> you're missing a mandatory field).
>
think having the option to raise exception that reject whole interchange does about the same.
(I am trying to pull as much as possible to translations ('translation is the centre').


kind regards,
henk-jan ebbers
>
> The second bullet would look something like this...
>
> *In the grammar:*
>
> def validate(thisnode):
> raise MessageError('Some validation failed')
>
>
> *In bots/inmessage.py (parse_edi_file, after UnicodeError is caught):*
> > > For more options, visit https://groups.google.com/d/optout <https://groups.google.com/d/optout> <https://groups.google.com/d/optout <https://groups.google.com/d/optout>>.

Anup Khadka

unread,
Apr 21, 2023, 4:38:06 AM4/21/23
to Bots Open Source EDI Translator
Hello Jason, I know its a long time but, did you solve triggering reject status in 997 in case of default exception ?
Reply all
Reply to author
Forward
0 new messages