Example #1
0
    def __init__(self, param, errh, src_file_obj, xslt_files=None, map_path=None):
        """
        @param param: pyx12.param instance
        @param errh: Error Handler object
        @param src_file_obj: Source document
        @type src_file_obj: string
        @rtype: boolean
        """
        self.param = param
        self.map_path = map_path
        self.errh = error_handler.errh_list()
        self.icvn = None
        self.fic = None
        self.vriic = None
        self.tspc = None

        # Get X12 DATA file
        self.src = x12file.X12Reader(src_file_obj)

        #Get Map of Control Segments
        self.map_file = 'x12.control.00501.xml' if self.src.icvn == '00501' else 'x12.control.00401.xml'
        self.control_map = map_if.load_map_file(self.map_file, param, self.map_path)
        self.map_index_if = map_index.map_index(self.map_path)
        self.x12_map_node = self.control_map.getnodebypath('/ISA_LOOP/ISA')
        self.walker = walk_tree()
Example #2
0
    def __init__(self,
                 param,
                 errh,
                 src_file_obj,
                 xslt_files=None,
                 map_path=None):
        """
        @param param: pyx12.param instance
        @param errh: Error Handler object
        @param src_file_obj: Source document
        @type src_file_obj: string
        @rtype: boolean
        """
        self.param = param
        self.map_path = map_path
        self.errh = error_handler.errh_list()
        self.icvn = None
        self.fic = None
        self.vriic = None
        self.tspc = None

        # Get X12 DATA file
        self.src = x12file.X12Reader(src_file_obj)

        #Get Map of Control Segments
        self.map_file = 'x12.control.00501.xml' if self.src.icvn == '00501' else 'x12.control.00401.xml'
        self.control_map = map_if.load_map_file(self.map_file, param,
                                                self.map_path)
        self.map_index_if = map_index.map_index(self.map_path)
        self.x12_map_node = self.control_map.getnodebypath('/ISA_LOOP/ISA')
        self.walker = walk_tree()
Example #3
0
    def iter_segments(self, loop_id=None):
        """
        Simple segment or tree iterator
        @return: X12 Data Node - simple segment or tree
        @rtype: L{node<x12context.X12DataNode>}
        """
        cur_tree = None
        cur_data_node = None
        for seg in self.src:
            #find node
            orig_node = self.x12_map_node
            pop_loops = []
            push_loops = []
            errh = error_handler.errh_list()

            if seg.get_seg_id() == 'ISA':
                tpath = '/ISA_LOOP/ISA'
                self.x12_map_node = self.control_map.getnodebypath(tpath)
            elif seg.get_seg_id() == 'GS':
                tpath = '/ISA_LOOP/GS_LOOP/GS'
                self.x12_map_node = self.control_map.getnodebypath(tpath)
            else:
                try:
                    (seg_node, pop_loops, push_loops) = self.walker.walk(self.x12_map_node,
                            seg, errh, self.src.get_seg_count(),
                            self.src.get_cur_line(), self.src.get_ls_id())
                    self.x12_map_node = seg_node
                except errors.EngineError:
                    raise
            if self.x12_map_node is None:
                self.x12_map_node = orig_node
            else:
                seg_id = seg.get_seg_id()
                if seg_id == 'ISA':
                    icvn = seg.get_value('ISA12')
                elif seg_id == 'GS':
                    fic = seg.get_value('GS01')
                    vriic = seg.get_value('GS08')
                    map_file_new = self.map_index_if.get_filename(icvn, vriic, fic)
                    if self.map_file != map_file_new:
                        self.map_file = map_file_new
                        if self.map_file is None:
                            raise pyx12.errors.EngineError("Map not found.  icvn=%s, fic=%s, vriic=%s" %
                                                           (icvn, fic, vriic))
                        cur_map = map_if.load_map_file(self.map_file, self.param, self.map_path)
                        if cur_map.id == '837':
                            self.src.check_837_lx = True
                        else:
                            self.src.check_837_lx = False
                        #self._apply_loop_count(orig_node, cur_map)
                        #self._reset_isa_counts(cur_map)
                        self._reset_counter_to_isa_counts()
                    #self._reset_gs_counts(cur_map)
                    self._reset_counter_to_gs_counts()
                    tpath = '/ISA_LOOP/GS_LOOP/GS'
                    self.x12_map_node = cur_map.getnodebypath(tpath)
                    #self.walker.forceWalkCounterToLoopStart('/ISA_LOOP/GS_LOOP', '/ISA_LOOP/GS_LOOP/GS')
                elif seg_id == 'BHT':
                    if vriic in ('004010X094', '004010X094A1'):
                        tspc = seg.get_value('BHT02')
                        map_file_new = self.map_index_if.get_filename(icvn, vriic, fic, tspc)
                        if self.map_file != map_file_new:
                            self.map_file = map_file_new
                            if self.map_file is None:
                                err_str = "Map not found.  icvn=%s, fic=%s, vriic=%s, tspc=%s" % \
                                    (icvn, fic, vriic, tspc)
                                raise pyx12.errors.EngineError(err_str)
                            cur_map = map_if.load_map_file(self.map_file, self.param, self.map_path)
                            if cur_map.id == '837':
                                self.src.check_837_lx = True
                            else:
                                self.src.check_837_lx = False
                            self._apply_loop_count(self.x12_map_node, cur_map)
                            tpath = '/ISA_LOOP/GS_LOOP/ST_LOOP/HEADER/BHT'
                            self.x12_map_node = cur_map.getnodebypath(tpath)

            node_x12path = self.x12_map_node.x12path
            # If we are in the requested tree, wait until we have the whole thing
            if loop_id is not None and loop_id in node_x12path.loop_list:
                # Are we at the start of the requested tree?
                if node_x12path.loop_list[-1] == loop_id and \
                        self.x12_map_node.is_first_seg_in_loop():
                    if cur_tree is not None:
                        # Found root loop repeat. Yield existing, create new tree
                        yield cur_tree
                    # Make new tree on parent loop
                    #pop_loops = get_pop_loops(cur_data_node.x12_map_node, self.x12_map_node)
                    #pop_loops = [x12_node for x12_node in pop_loops if x12_node.get_path().find(loop_id) == -1]
                    cur_tree = X12LoopDataNode(x12_node=self.x12_map_node.parent, end_loops=pop_loops)  # parent=cur_data_node)
                    cur_data_node = self._add_segment(cur_tree, self.x12_map_node, seg, pop_loops, push_loops)
                else:
                    if cur_data_node is None or self.x12_map_node is None:
                        raise errors.EngineError('Either cur_data_node or self.x12_map_node is None')
                    cur_data_node = self._add_segment(cur_data_node, self.x12_map_node, seg, pop_loops, push_loops)
            else:
                if cur_tree is not None:
                    # We have completed a tree
                    yield cur_tree
                    cur_tree = None
                if cur_data_node is not None:
                    #push_loops = get_push_loops(cur_data_node.x12_map_node, self.x12_map_node)
                    #pop_loops = get_pop_loops(cur_data_node.x12_map_node, self.x12_map_node)
                    if loop_id:
                        pop_loops = [x12_node for x12_node in pop_loops if x12_node.get_path().find(loop_id) == -1]
                    assert loop_id not in [x12.id for x12 in push_loops], 'Loop ID %s should not be in push loops' % (loop_id)
                    assert loop_id not in [x12.id for x12 in pop_loops], 'Loop ID %s should not be in pop loops' % (loop_id)
                    cur_data_node = X12SegmentDataNode(self.x12_map_node, seg, push_loops, pop_loops)
                else:
                    cur_data_node = X12SegmentDataNode(self.x12_map_node, seg)
                # Get errors caught by x12Reader
                errh.handle_errors(self.src.pop_errors())
                # Handle errors captured in errh_list
                cur_data_node.handle_errh_errors(errh)
                if cur_data_node.id != 'ISA' and cur_data_node is not None:
                    assert cur_data_node.parent is not None, 'Node "%s" has no parent' % (cur_data_node.id)
                yield cur_data_node
Example #4
0
def x12n_document(param, src_file, fd_997, fd_html, fd_xmldoc=None, xslt_files=None, map_path=None):
    """
    Primary X12 validation function
    @param param: param instance
    @param src_file: Source document
    @type src_file: string
    @param fd_997: 997/999 output document
    @type fd_997: file descriptor
    @param fd_html: HTML output document
    @type fd_html: file descriptor
    @param fd_xmldoc: XML output document
    @type fd_xmldoc: file descriptor
    @rtype: boolean
    """
    logger = logging.getLogger("pyx12")
    errh = error_handler.err_handler()

    # Get X12 DATA file
    try:
        src = x12file.X12Reader(src_file)
    except errors.X12Error:
        logger.error('"%s" does not look like an X12 data file' % (src_file))
        return False

    # Get Map of Control Segments
    map_file = "x12.control.00501.xml" if src.icvn == "00501" else "x12.control.00401.xml"
    logger.debug("X12 control file: %s" % (map_file))
    control_map = map_if.load_map_file(map_file, param, map_path)
    map_index_if = map_index.map_index(map_path)
    node = control_map.getnodebypath("/ISA_LOOP/ISA")
    walker = walk_tree()
    icvn = fic = vriic = tspc = None
    cur_map = None  # we do not initially know the X12 transaction type
    # XXX Generate TA1 if needed.

    if fd_html:
        html = error_html.error_html(errh, fd_html, src.get_term())
        html.header()
        err_iter = error_handler.err_iter(errh)
    if fd_xmldoc:
        xmldoc = x12xml_simple.x12xml_simple(fd_xmldoc, param.get("simple_dtd"))

    # basedir = os.path.dirname(src_file)
    # erx = errh_xml.err_handler(basedir=basedir)

    valid = True
    for seg in src:
        # find node
        orig_node = node

        if False:
            print("--------------------------------------------")
            print(seg)
            print("--------------------------------------------")
            # reset to control map for ISA and GS loops
            print("------- counters before --------")
            print(walker.counter._dict)
        if seg.get_seg_id() == "ISA":
            node = control_map.getnodebypath("/ISA_LOOP/ISA")
            walker.forceWalkCounterToLoopStart("/ISA_LOOP", "/ISA_LOOP/ISA")
        elif seg.get_seg_id() == "GS":
            node = control_map.getnodebypath("/ISA_LOOP/GS_LOOP/GS")
            walker.forceWalkCounterToLoopStart("/ISA_LOOP/GS_LOOP", "/ISA_LOOP/GS_LOOP/GS")
        else:
            # from the current node, find the map node matching the segment
            # keep track of the loops traversed
            try:
                (node, pop_loops, push_loops) = walker.walk(
                    node, seg, errh, src.get_seg_count(), src.get_cur_line(), src.get_ls_id()
                )
            except errors.EngineError:
                logger.error("Source file line %i" % (src.get_cur_line()))
                raise

        if False:
            print("------- counters after --------")
            print(walker.counter._dict)
        if node is None:
            node = orig_node
        else:
            if seg.get_seg_id() == "ISA":
                errh.add_isa_loop(seg, src)
                icvn = seg.get_value("ISA12")
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == "IEA":
                errh.handle_errors(src.pop_errors())
                errh.close_isa_loop(node, seg, src)
                # Generate 997
                # XXX Generate TA1 if needed.
            elif seg.get_seg_id() == "GS":
                fic = seg.get_value("GS01")
                vriic = seg.get_value("GS08")
                map_file_new = map_index_if.get_filename(icvn, vriic, fic)
                if map_file != map_file_new:
                    map_file = map_file_new
                    if map_file is None:
                        err_str = "Map not found.  icvn={}, fic={}, vriic={}".format(icvn, fic, vriic)
                        raise errors.EngineError(err_str)
                    cur_map = map_if.load_map_file(map_file, param, map_path)
                    src.check_837_lx = True if cur_map.id == "837" else False
                    logger.debug("Map file: %s" % (map_file))
                    # apply_loop_count(orig_node, cur_map)
                    # reset_isa_counts(cur_map)
                    # _reset_counter_to_isa_counts(walker)  # new counter
                # reset_gs_counts(cur_map)
                # _reset_counter_to_gs_counts(walker)  # new counter
                node = cur_map.getnodebypath("/ISA_LOOP/GS_LOOP/GS")
                errh.add_gs_loop(seg, src)
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == "BHT":
                # special case for 4010 837P
                if vriic in ("004010X094", "004010X094A1"):
                    tspc = seg.get_value("BHT02")
                    logger.debug("icvn=%s, fic=%s, vriic=%s, tspc=%s" % (icvn, fic, vriic, tspc))
                    map_file_new = map_index_if.get_filename(icvn, vriic, fic, tspc)
                    logger.debug("New map file: %s" % (map_file_new))
                    if map_file != map_file_new:
                        map_file = map_file_new
                        if map_file is None:
                            err_str = "Map not found.  icvn={}, fic={}, vriic={}, tspc={}".format(
                                icvn, fic, vriic, tspc
                            )
                            raise errors.EngineError(err_str)
                        cur_map = map_if.load_map_file(map_file, param, map_path)
                        src.check_837_lx = True if cur_map.id == "837" else False
                        logger.debug("Map file: %s" % (map_file))
                        # apply_loop_count(node, cur_map)
                        node = cur_map.getnodebypath("/ISA_LOOP/GS_LOOP/ST_LOOP/HEADER/BHT")
                errh.add_seg(node, seg, src.get_seg_count(), src.get_cur_line(), src.get_ls_id())
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == "GE":
                errh.handle_errors(src.pop_errors())
                errh.close_gs_loop(node, seg, src)
            elif seg.get_seg_id() == "ST":
                errh.add_st_loop(seg, src)
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == "SE":
                errh.handle_errors(src.pop_errors())
                errh.close_st_loop(node, seg, src)
            else:
                errh.add_seg(node, seg, src.get_seg_count(), src.get_cur_line(), src.get_ls_id())
                errh.handle_errors(src.pop_errors())

            # errh.set_cur_line(src.get_cur_line())
            valid &= node.is_valid(seg, errh)
            # erx.handleErrors(src.pop_errors())
            # erx.handleErrors(errh.get_errors())
            # errh.reset()

        if fd_html:
            if node is not None and node.is_first_seg_in_loop():
                html.loop(node.get_parent())
            err_node_list = []
            while True:
                try:
                    err_iter.next()
                    err_node = err_iter.get_cur_node()
                    err_node_list.append(err_node)
                except errors.IterOutOfBounds:
                    break
            html.gen_seg(seg, src, err_node_list)

        if fd_xmldoc:
            xmldoc.seg(node, seg)

        if False:
            print("\n\n")
        # erx.Write(src.cur_line)

    # erx.handleErrors(src.pop_errors())
    src.cleanup()  # Catch any skipped loop trailers
    errh.handle_errors(src.pop_errors())
    # erx.handleErrors(src.pop_errors())
    # erx.handleErrors(errh.get_errors())

    if fd_html:
        html.footer()
        del html

    if fd_xmldoc:
        del xmldoc

    # visit_debug = error_debug.error_debug_visitor(sys.stdout)
    # errh.accept(visit_debug)

    # If this transaction is not a 997/999, generate one.
    if fd_997 and fic != "FA":
        if vriic and vriic[:6] == "004010":
            try:
                visit_997 = error_997.error_997_visitor(fd_997, src.get_term())
                errh.accept(visit_997)
                del visit_997
            except Exception:
                logger.exception("Failed to create 997 response")
        if vriic and vriic[:6] == "005010":
            try:
                visit_999 = error_999.error_999_visitor(fd_997, src.get_term())
                errh.accept(visit_999)
                del visit_999
            except Exception:
                logger.exception("Failed to create 999 response")
    del node
    del src
    del control_map
    try:
        del cur_map
    except UnboundLocalError:
        pass
    try:
        if not valid or errh.get_error_count() > 0:
            return False
        else:
            return True
    except Exception:
        print(errh)
        return False
Example #5
0
def x12n_document(param,
                  src_file,
                  fd_997,
                  fd_html,
                  fd_xmldoc=None,
                  xslt_files=None,
                  map_path=None):
    """
    Primary X12 validation function
    @param param: param instance
    @param src_file: Source document
    @type src_file: string
    @param fd_997: 997/999 output document
    @type fd_997: file descriptor
    @param fd_html: HTML output document
    @type fd_html: file descriptor
    @param fd_xmldoc: XML output document
    @type fd_xmldoc: file descriptor
    @rtype: boolean
    """
    logger = logging.getLogger('pyx12')
    errh = error_handler.err_handler()

    # Get X12 DATA file
    try:
        src = x12file.X12Reader(src_file)
    except errors.X12Error:
        logger.error('"%s" does not look like an X12 data file' % (src_file))
        return False

    #Get Map of Control Segments
    map_file = 'x12.control.00501.xml' if src.icvn == '00501' else 'x12.control.00401.xml'
    logger.debug('X12 control file: %s' % (map_file))
    control_map = map_if.load_map_file(map_file, param, map_path)
    map_index_if = map_index.map_index(map_path)
    node = control_map.getnodebypath('/ISA_LOOP/ISA')
    walker = walk_tree()
    icvn = fic = vriic = tspc = None
    cur_map = None  # we do not initially know the X12 transaction type
    #XXX Generate TA1 if needed.

    if fd_html:
        html = error_html.error_html(errh, fd_html, src.get_term())
        html.header()
        err_iter = error_handler.err_iter(errh)
    if fd_xmldoc:
        xmldoc = x12xml_simple.x12xml_simple(fd_xmldoc,
                                             param.get('simple_dtd'))

    #basedir = os.path.dirname(src_file)
    #erx = errh_xml.err_handler(basedir=basedir)

    valid = True
    for seg in src:
        #find node
        orig_node = node

        if False:
            print('--------------------------------------------')
            print(seg)
            print('--------------------------------------------')
            # reset to control map for ISA and GS loops
            print('------- counters before --------')
            print(walker.counter._dict)
        if seg.get_seg_id() == 'ISA':
            node = control_map.getnodebypath('/ISA_LOOP/ISA')
            walker.forceWalkCounterToLoopStart('/ISA_LOOP', '/ISA_LOOP/ISA')
        elif seg.get_seg_id() == 'GS':
            node = control_map.getnodebypath('/ISA_LOOP/GS_LOOP/GS')
            walker.forceWalkCounterToLoopStart('/ISA_LOOP/GS_LOOP',
                                               '/ISA_LOOP/GS_LOOP/GS')
        else:
            # from the current node, find the map node matching the segment
            # keep track of the loops traversed
            try:
                (node,
                 pop_loops, push_loops) = walker.walk(node, seg, errh,
                                                      src.get_seg_count(),
                                                      src.get_cur_line(),
                                                      src.get_ls_id())
            except errors.EngineError:
                logger.error('Source file line %i' % (src.get_cur_line()))
                raise

        if False:
            print('------- counters after --------')
            print(walker.counter._dict)
        if node is None:
            node = orig_node
        else:
            if seg.get_seg_id() == 'ISA':
                errh.add_isa_loop(seg, src)
                icvn = seg.get_value('ISA12')
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == 'IEA':
                errh.handle_errors(src.pop_errors())
                errh.close_isa_loop(node, seg, src)
                # Generate 997
                #XXX Generate TA1 if needed.
            elif seg.get_seg_id() == 'GS':
                fic = seg.get_value('GS01')
                vriic = seg.get_value('GS08')
                map_file_new = map_index_if.get_filename(icvn, vriic, fic)
                if map_file != map_file_new:
                    map_file = map_file_new
                    if map_file is None:
                        err_str = "Map not found.  icvn={}, fic={}, vriic={}".format(
                            icvn, fic, vriic)
                        raise errors.EngineError(err_str)
                    cur_map = map_if.load_map_file(map_file, param, map_path)
                    src.check_837_lx = True if cur_map.id == '837' else False
                    logger.debug('Map file: %s' % (map_file))
                    #apply_loop_count(orig_node, cur_map)
                    #reset_isa_counts(cur_map)
                    #_reset_counter_to_isa_counts(walker)  # new counter
                #reset_gs_counts(cur_map)
                #_reset_counter_to_gs_counts(walker)  # new counter
                node = cur_map.getnodebypath('/ISA_LOOP/GS_LOOP/GS')
                errh.add_gs_loop(seg, src)
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == 'BHT':
                # special case for 4010 837P
                if vriic in ('004010X094', '004010X094A1'):
                    tspc = seg.get_value('BHT02')
                    logger.debug('icvn=%s, fic=%s, vriic=%s, tspc=%s' %
                                 (icvn, fic, vriic, tspc))
                    map_file_new = map_index_if.get_filename(
                        icvn, vriic, fic, tspc)
                    logger.debug('New map file: %s' % (map_file_new))
                    if map_file != map_file_new:
                        map_file = map_file_new
                        if map_file is None:
                            err_str = "Map not found.  icvn={}, fic={}, vriic={}, tspc={}".format(
                                icvn, fic, vriic, tspc)
                            raise errors.EngineError(err_str)
                        cur_map = map_if.load_map_file(map_file, param,
                                                       map_path)
                        src.check_837_lx = True if cur_map.id == '837' else False
                        logger.debug('Map file: %s' % (map_file))
                        #apply_loop_count(node, cur_map)
                        node = cur_map.getnodebypath(
                            '/ISA_LOOP/GS_LOOP/ST_LOOP/HEADER/BHT')
                errh.add_seg(node, seg, src.get_seg_count(),
                             src.get_cur_line(), src.get_ls_id())
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == 'GE':
                errh.handle_errors(src.pop_errors())
                errh.close_gs_loop(node, seg, src)
            elif seg.get_seg_id() == 'ST':
                errh.add_st_loop(seg, src)
                errh.handle_errors(src.pop_errors())
            elif seg.get_seg_id() == 'SE':
                errh.handle_errors(src.pop_errors())
                errh.close_st_loop(node, seg, src)
            else:
                errh.add_seg(node, seg, src.get_seg_count(),
                             src.get_cur_line(), src.get_ls_id())
                errh.handle_errors(src.pop_errors())

            #errh.set_cur_line(src.get_cur_line())
            valid &= node.is_valid(seg, errh)
            #erx.handleErrors(src.pop_errors())
            #erx.handleErrors(errh.get_errors())
            #errh.reset()

        if fd_html:
            if node is not None and node.is_first_seg_in_loop():
                html.loop(node.get_parent())
            err_node_list = []
            while True:
                try:
                    err_iter.next()
                    err_node = err_iter.get_cur_node()
                    err_node_list.append(err_node)
                except errors.IterOutOfBounds:
                    break
            html.gen_seg(seg, src, err_node_list)

        if fd_xmldoc:
            xmldoc.seg(node, seg)

        if False:
            print('\n\n')
        #erx.Write(src.cur_line)

    #erx.handleErrors(src.pop_errors())
    src.cleanup()  # Catch any skipped loop trailers
    errh.handle_errors(src.pop_errors())
    #erx.handleErrors(src.pop_errors())
    #erx.handleErrors(errh.get_errors())

    if fd_html:
        html.footer()
        del html

    if fd_xmldoc:
        del xmldoc

    #visit_debug = error_debug.error_debug_visitor(sys.stdout)
    #errh.accept(visit_debug)

    #If this transaction is not a 997/999, generate one.
    if fd_997 and fic != 'FA':
        if vriic and vriic[:6] == '004010':
            try:
                visit_997 = error_997.error_997_visitor(fd_997, src.get_term())
                errh.accept(visit_997)
                del visit_997
            except Exception:
                logger.exception('Failed to create 997 response')
        if vriic and vriic[:6] == '005010':
            try:
                visit_999 = error_999.error_999_visitor(fd_997, src.get_term())
                errh.accept(visit_999)
                del visit_999
            except Exception:
                logger.exception('Failed to create 999 response')
    del node
    del src
    del control_map
    try:
        del cur_map
    except UnboundLocalError:
        pass
    try:
        if not valid or errh.get_error_count() > 0:
            return False
        else:
            return True
    except Exception:
        print(errh)
        return False
Example #6
0
    def iter_segments(self, loop_id=None):
        """
        Simple segment or tree iterator
        @return: X12 Data Node - simple segment or tree
        @rtype: L{node<x12context.X12DataNode>}
        """
        cur_tree = None
        cur_data_node = None
        for seg in self.src:
            #find node
            orig_node = self.x12_map_node
            pop_loops = []
            push_loops = []
            errh = error_handler.errh_list()

            if seg.get_seg_id() == 'ISA':
                tpath = '/ISA_LOOP/ISA'
                self.x12_map_node = self.control_map.getnodebypath(tpath)
            elif seg.get_seg_id() == 'GS':
                tpath = '/ISA_LOOP/GS_LOOP/GS'
                self.x12_map_node = self.control_map.getnodebypath(tpath)
            else:
                try:
                    (seg_node, pop_loops,
                     push_loops) = self.walker.walk(self.x12_map_node, seg,
                                                    errh,
                                                    self.src.get_seg_count(),
                                                    self.src.get_cur_line(),
                                                    self.src.get_ls_id())
                    self.x12_map_node = seg_node
                except errors.EngineError:
                    raise
            if self.x12_map_node is None:
                self.x12_map_node = orig_node
            else:
                seg_id = seg.get_seg_id()
                if seg_id == 'ISA':
                    icvn = seg.get_value('ISA12')
                elif seg_id == 'GS':
                    fic = seg.get_value('GS01')
                    vriic = seg.get_value('GS08')
                    map_file_new = self.map_index_if.get_filename(
                        icvn, vriic, fic)
                    if self.map_file != map_file_new:
                        self.map_file = map_file_new
                        if self.map_file is None:
                            raise pyx12.errors.EngineError(
                                "Map not found.  icvn=%s, fic=%s, vriic=%s" %
                                (icvn, fic, vriic))
                        cur_map = map_if.load_map_file(self.map_file,
                                                       self.param,
                                                       self.map_path)
                        if cur_map.id == '837':
                            self.src.check_837_lx = True
                        else:
                            self.src.check_837_lx = False
                        #self._apply_loop_count(orig_node, cur_map)
                        #self._reset_isa_counts(cur_map)
                        self._reset_counter_to_isa_counts()
                    #self._reset_gs_counts(cur_map)
                    self._reset_counter_to_gs_counts()
                    tpath = '/ISA_LOOP/GS_LOOP/GS'
                    self.x12_map_node = cur_map.getnodebypath(tpath)
                    #self.walker.forceWalkCounterToLoopStart('/ISA_LOOP/GS_LOOP', '/ISA_LOOP/GS_LOOP/GS')
                elif seg_id == 'BHT':
                    if vriic in ('004010X094', '004010X094A1'):
                        tspc = seg.get_value('BHT02')
                        map_file_new = self.map_index_if.get_filename(
                            icvn, vriic, fic, tspc)
                        if self.map_file != map_file_new:
                            self.map_file = map_file_new
                            if self.map_file is None:
                                err_str = "Map not found.  icvn=%s, fic=%s, vriic=%s, tspc=%s" % \
                                    (icvn, fic, vriic, tspc)
                                raise pyx12.errors.EngineError(err_str)
                            cur_map = map_if.load_map_file(
                                self.map_file, self.param, self.map_path)
                            if cur_map.id == '837':
                                self.src.check_837_lx = True
                            else:
                                self.src.check_837_lx = False
                            self._apply_loop_count(self.x12_map_node, cur_map)
                            tpath = '/ISA_LOOP/GS_LOOP/ST_LOOP/HEADER/BHT'
                            self.x12_map_node = cur_map.getnodebypath(tpath)

            node_x12path = self.x12_map_node.x12path
            # If we are in the requested tree, wait until we have the whole thing
            if loop_id is not None and loop_id in node_x12path.loop_list:
                # Are we at the start of the requested tree?
                if node_x12path.loop_list[-1] == loop_id and \
                        self.x12_map_node.is_first_seg_in_loop():
                    if cur_tree is not None:
                        # Found root loop repeat. Yield existing, create new tree
                        yield cur_tree
                    # Make new tree on parent loop
                    #pop_loops = get_pop_loops(cur_data_node.x12_map_node, self.x12_map_node)
                    #pop_loops = [x12_node for x12_node in pop_loops if x12_node.get_path().find(loop_id) == -1]
                    cur_tree = X12LoopDataNode(
                        x12_node=self.x12_map_node.parent,
                        end_loops=pop_loops)  # parent=cur_data_node)
                    cur_data_node = self._add_segment(cur_tree,
                                                      self.x12_map_node, seg,
                                                      pop_loops, push_loops)
                    cur_data_node.seg_count = self.src.get_seg_count()
                    cur_data_node.cur_line_number = self.src.get_cur_line()
                else:
                    if cur_data_node is None or self.x12_map_node is None:
                        raise errors.EngineError(
                            'Either cur_data_node or self.x12_map_node is None'
                        )
                    cur_data_node = self._add_segment(cur_data_node,
                                                      self.x12_map_node, seg,
                                                      pop_loops, push_loops)
                    cur_data_node.seg_count = self.src.get_seg_count()
                    cur_data_node.cur_line_number = self.src.get_cur_line()
            else:
                if cur_tree is not None:
                    # We have completed a tree
                    yield cur_tree
                    cur_tree = None
                if cur_data_node is not None:
                    #push_loops = get_push_loops(cur_data_node.x12_map_node, self.x12_map_node)
                    #pop_loops = get_pop_loops(cur_data_node.x12_map_node, self.x12_map_node)
                    if loop_id:
                        pop_loops = [
                            x12_node for x12_node in pop_loops
                            if x12_node.get_path().find(loop_id) == -1
                        ]
                    assert loop_id not in [
                        x12.id for x12 in push_loops
                    ], 'Loop ID %s should not be in push loops' % (loop_id)
                    assert loop_id not in [
                        x12.id for x12 in pop_loops
                    ], 'Loop ID %s should not be in pop loops' % (loop_id)
                    cur_data_node = X12SegmentDataNode(self.x12_map_node, seg,
                                                       push_loops, pop_loops)
                    cur_data_node.seg_count = self.src.get_seg_count()
                    cur_data_node.cur_line_number = self.src.get_cur_line()
                else:
                    cur_data_node = X12SegmentDataNode(self.x12_map_node, seg)
                    cur_data_node.seg_count = self.src.get_seg_count()
                    cur_data_node.cur_line_number = self.src.get_cur_line()
                # Get errors caught by x12Reader
                errh.handle_errors(self.src.pop_errors())
                # Handle errors captured in errh_list
                cur_data_node.handle_errh_errors(errh)
                if cur_data_node.id != 'ISA' and cur_data_node is not None:
                    assert cur_data_node.parent is not None, 'Node "%s" has no parent' % (
                        cur_data_node.id)
                yield cur_data_node