Exemplo n.º 1
0
def _find_group(segment, search_data, validation_level=None):
    """
    Recursively find the group the segment belongs to

    :param segment: a :class:`hl7apy.core.Segment` instance

    :param search_data: a dictionary containing current chain of parent, current indexes and element
        structures

    :param validation_level: the validation level. Possible values are those defined in
        :class:`VALIDATION_LEVEL <hl7apy.consts.VALIDATION_LEVEL>` class or ``None`` to use the default
        validation level (see :func:`set_default_validation_level <hl7apy.set_default_validation_level>`)

    :return: the index of the parent children list where the segment has been found
    """
    search_index = -1
    current_index = search_data['indexes'][-1]
    structure = search_data['structures'][-1]
    try:
        search_index = structure['ordered_children'].index(segment.name)
    except ValueError:
        # groups of the current parent
        groups = [k for k in structure['ordered_children']
                  if structure['structure_by_name'][k]['cls'] == Group]
        # for any group found, create the group and check if the segment is one of its children
        for g in groups:
            group = Group(g, version=segment.version, reference=structure['structure_by_name'][g]['ref'],
                          validation_level=validation_level)
            p_structure = {'structure_by_name':  group.structure_by_name,
                           'ordered_children': group.ordered_children,
                           'repetitions': group.repetitions}
            search_data['structures'].append(p_structure)
            search_data['parents'].append(group)
            search_data['indexes'].append(-1)
            found_index = _find_group(segment, search_data, validation_level)
            # the segment is a child of the current group
            if found_index > -1:
                find_parent = search_data['parents'].index(group) - 1
                group.parent = search_data['parents'][find_parent]
                search_index = structure['ordered_children'].index(g)
                search_data['indexes'][find_parent] = search_index
                break
            else:  # the segment is not a child of the current group, continue the search
                _go_back(search_data)
    else:
        if search_index <= current_index and structure['repetitions'][segment.name][1] == 1:
            # if more than one instance of the segment has been found and only one instance is allowed,
            # go up of one level to create another instance of the group the segment belongs to
            _go_back(search_data)
            return _find_group(segment, search_data, validation_level)
        search_data['indexes'][-1] = search_index
        parent = search_data['parents'][-1]
        parent.add(segment)
    return search_index
Exemplo n.º 2
0
 def test_wrong_group(self):
     """
     Tests that if there is an unexpected segment the message in not validated
     The message used has an unexpected OML_O33_PATIENT
     """
     msg = self._create_message(self.rsp_k21)
     oml_o33_patient = Group('OML_O33_PATIENT')
     segments = parse_segments('PID|||1010110909194822^^^GATEWAY_IL&1.3.6.1.4.1.21367.2011.2.5.17&ISO^PK||PIPPO^PLUTO^^^^^L||19790515|M|||VIA DI TOPOLINO^CAGLIARI^CAGLIARI^^09100^100^H^^092009~^^^^^^L|||||||PPPPPP79E15B354I^^^CF|||||CAGLIARI|||100\rPV1||O|||||||||||||||||1107080001^^^LIS')
     oml_o33_patient.children = segments
     msg.add(oml_o33_patient)
     self.assertRaises(ValidationError, msg.validate, report_file=self.report_file)
     self._test_report_file('ERROR')
Exemplo n.º 3
0
 def test_having_more_groups(self):
     """
     Tests that when a group occurs more than the allowed times the message is not validated
     The message used has 2 occurrence of oml_o33_group
     """
     msg = self._create_message(self.oml_o33)
     oml_o33_patient = Group('OML_O33_PATIENT')
     segments = parse_segments('PID|||1010110909194822^^^GATEWAY_IL&1.3.6.1.4.1.21367.2011.2.5.17&ISO^PK||PIPPO^PLUTO^^^^^L||19790515|M|||VIA DI TOPOLINO^CAGLIARI^CAGLIARI^^09100^100^H^^092009~^^^^^^L|||||||PPPPPP79E15B354I^^^CF|||||CAGLIARI|||100\rPV1||O|||||||||||||||||1107080001^^^LIS')
     oml_o33_patient.children = segments
     msg.add(oml_o33_patient)
     self.assertRaises(ValidationError, msg.validate, report_file=self.report_file)
     self._test_report_file('ERROR')
Exemplo n.º 4
0
    def test_to_string_message_with_z_segment(self):
        msg = self._create_test_message(self.msh_values_standard)
        msg.zin = 'ZIN||abc||cba^www~abc^yyy'
        self.assertEqual(msg.to_er7(), self.msh_standard + '\rZIN||abc||cba^www~abc^yyy')

        msg.zbe = 'ZBE|yyy|ww||||||yyy'
        self.assertEqual(msg.to_er7(), self.msh_standard + '\rZIN||abc||cba^www~abc^yyy\rZBE|yyy|ww||||||yyy')

        g = Group('OML_O33_PATIENT', validation_level=VALIDATION_LEVEL.TOLERANT)
        g.pid = 'PID|1'
        g.zbe = 'ZBE||ab|ab'

        msg.add(g)
        self.assertEqual(msg.to_er7(), self.msh_standard + '\rZIN||abc||cba^www~abc^yyy\rZBE|yyy|ww||||||yyy\rPID|1\rZBE||ab|ab')
Exemplo n.º 5
0
def parse_segments(text, version=None, encoding_chars=None, validation_level=None, references=None, find_groups=False):
    """
    Parse the given ER7-encoded segments and return a list of :class:`hl7apy.core.Segment` instances.

    :type text: ``str``
    :param text: the ER7-encoded string containing the segments to be parsed

    :type version: ``str``
    :param version: the HL7 version (e.g. "2.5"), or ``None`` to use the default
        (see :func:`set_default_version <hl7apy.set_default_version>`)

    :type encoding_chars: ``dict``
    :param encoding_chars: a dictionary containing the encoding chars or None to use the default
        (see :func:`set_default_encoding_chars <hl7apy.set_default_encoding_chars>`)

    :type validation_level: ``int``
    :param validation_level: the validation level. Possible values are those defined in
        :class:`VALIDATION_LEVEL <hl7apy.consts.VALIDATION_LEVEL>` class or ``None`` to use the default
        validation level (see :func:`validation_level <hl7apy.set_default_validation_level>`)

    :type references: ``list``
    :param references: A list of the references of the :class:`Segment <hl7apy.core.Segment>`'s children

    :type find_groups: ``bool``
    :param find_groups: if ``True``, automatically assign the segments found to the appropriate
        :class:`Groups <hl7apy.core.Group>` instances. If ``False``, the segments found are assigned as
        children of the :class:`Message <hl7apy.core.Message>` instance

    :return: a list of :class:`Segment <hl7apy.core.Segment>` instances

    >>> segments = "EVN||20080115153000||||20080114003000\\rPID|1||566-554-3423^^^GHH^MR||EVERYMAN^ADAM^A|||M|||" \
    "2222 HOME STREET^^ANN ARBOR^MI^^USA||555-555-2004|||M\\r"
    >>> print(parse_segments(segments))
    [<Segment EVN>, <Segment PID>]
    """
    version = _get_version(version)
    encoding_chars = _get_encoding_chars(encoding_chars, version)
    validation_level = _get_validation_level(validation_level)

    segment_sep = encoding_chars['SEGMENT']
    segments = []

    parents_refs = [(None, references)]
    current_parent = None
    for s in text.split(segment_sep):
        if len(s) > 0:
            segment_name = s[:3]
            for x in xrange(len(parents_refs)):
                if not find_groups:
                    segment = parse_segment(s.strip(), version, encoding_chars, validation_level)
                    segments.append(segment)
                else:
                    ref, parents_refs = _get_segment_reference(segment_name, parents_refs)
                    if ref is None:
                        # group not found at the current level, go back to the previous level
                        if current_parent is not None:
                            parents_refs.pop()
                            current_parent = current_parent.parent
                    else:
                        if current_parent is None and parents_refs[-1][0] is not None or \
                                current_parent is not None and parents_refs[-1][0] != current_parent.name:
                            # create the parents group of the segment
                            if current_parent is not None:
                                cur_idx = parents_refs.index((current_parent.name, current_parent.reference))
                            else:
                                cur_idx = parents_refs.index((None, references))
                            for p_ref in parents_refs[cur_idx + 1:]:
                                group = Group(p_ref[0], version=version, reference=p_ref[1],
                                              validation_level=validation_level)
                                if current_parent is None:
                                    segments.append(group)
                                else:
                                    current_parent.add(group)
                                current_parent = group
                        elif current_parent is not None and segment_name in [c.name for c in current_parent.children] \
                                and current_parent.repetitions[segment_name][1] == 1:
                            # The number of instances allowed is reached so we create another instance of the same
                            group = Group(current_parent.name, version=version, reference=current_parent.reference,
                                          validation_level=validation_level)

                            if current_parent.parent is None:
                                segments.append(group)
                            else:
                                current_parent.parent.add(group)
                            current_parent = group

                        segment = parse_segment(s.strip(), version, encoding_chars, validation_level, ref)
                        if current_parent is None:
                            segments.append(segment)
                        else:
                            current_parent.add(segment)
                        break
    return segments