def convert_instance(in_node, out_node, form_name=None):
    xmlns, name = util.split_tag(in_node.tag)

    if list(in_node):
        if form_name:
            group = et.SubElement(out_node, _('FormData'))
            group.attrib['FormOID'] = form_name
        else:
            group = et.SubElement(out_node, _('ItemGroupData'))
            group.attrib['ItemGroupOID'] = name
            group.attrib['ItemGroupRepeatKey'] = str(1)
            group.attrib['TransactionType'] = 'Insert'

        for child in in_node:
            convert_instance(child, group)
    else:
        value = (in_node.text or '')
        
        # hack to fix time answers
        m = re.match(r'(\d{1,2}):(\d{2}):\d{2}', value)
        if m:
            value = '%02d%02d' % (int(m.group(1)), int(m.group(2)))

        ALLOW_FORCE_COMPLETION = True  # if we allow form to be submitted in incomplete state -- required questions might be blank
        is_required = True # TODO figure out how to pull this from the crf definition; i think currently everything is required so doesn't matter

        if ALLOW_FORCE_COMPLETION and is_required and value == '':
            # strip this answer from the submission or OC will complain about data integrity
            return

        q = et.SubElement(out_node, _('ItemData'))
        q.attrib['ItemOID'] = name
        q.attrib['Value'] = value
def odm_scaffold(metadata, resp):
    odm = et.Element(_('ODM'))
    clindata = et.SubElement(odm, _('ClinicalData'))
    clindata.attrib['StudyOID'] = metadata['study']
    clindata.attrib['MetaDataVersionOID'] = metadata['mdv']

    subjdata = et.SubElement(clindata, _('SubjectData'))
    subjdata.attrib['SubjectKey'] = resp['subject_id']

    seevtdata = et.SubElement(subjdata, _('StudyEventData'))
    seevtdata.attrib['StudyEventOID'] = metadata['studyevent']
    if resp['event_ordinal']:
        seevtdata.attrib['StudyEventRepeatKey'] = str(resp['event_ordinal'])

    return odm, seevtdata
def convert_odm(context, f, source):
    doc = et.parse(f)
    if source:
        ref_instance = list(source.find('.//%s' % _('instance', 'xf')))[0]
    else:
        ref_instance = None

    return build_submission(context, doc.getroot(), ref_instance)