Esempio n. 1
0
    def save(self, subject, protocol):
        if self.is_valid():
            cleaned_data = self.cleaned_data
            # Legacy Information
            old_subject = deepcopy(subject)
            old_subject.organization_id
            old_subject.group_name = SubjectUtils.protocol_subject_record_group_name(protocol, old_subject)
            # Updated Information
            subject.old_subject = old_subject
            subject.first_name = cleaned_data.get('first_name')
            subject.last_name = cleaned_data.get('last_name')
            subject.dob = cleaned_data.get('dob')
            subject.organization_subject_id = cleaned_data.get('subject_id')
            org = self.getOrgFromSelection(cleaned_data.get('organization'))
            subject.organization_id = org.id
            srh = ServiceClient.get_rh_for(record_type=ServiceClient.SUBJECT)
            subject.group_name = SubjectUtils.protocol_subject_record_group_name(protocol, subject)
            r = srh.update(subject)[0]
            if SubjectUtils.create_protocol_subject_record_group(protocol, subject):
                SubjectUtils.delete_protocol_subject_record_group(protocol, old_subject)

            success = r.get('success')
            errors = r.get('errors')
            return [success, subject, errors]
        else:
            return None
    def cache_records(self):
        datasources = DataSource.objects.all()
        protocols = Protocol.objects.all()


        er_rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)
        for ds in datasources:
            try:
                ers = er_rh.query({'external_system_id': ds.ehb_service_es_id})[0]['external_record']
            except:
                print 'failed retrieval of records from external system: {0}'.format(ds)
            for record in ers:
                cache.set('externalrecord_{0}'.format(record.id), record.json_from_identity(record))
                # Make sure key lasts a day
                cache.expire('externalrecord_{0}'.format(record.id), 60*60*24)
        for protocol in protocols:
            subs = protocol.getSubjects()
            if subs:
                subs_dict = [json.loads(subject.json_from_identity(subject)) for subject in subs]
                for sub in subs:
                    sub_records = []
                    for record in ers:
                        if record.subject_id == sub.id:
                            sub_records.append(json.loads(record.json_from_identity(record)))
                    ck = '{0}_{1}_externalrecords'.format(protocol.id, sub.id)
                    cache.set(ck, json.dumps(sub_records))
                    cache.expire(ck, 60*60*24)
        print 'Caching of ExternalRecords complete'
Esempio n. 3
0
def getExternalIdentifiers(pds, subject, labels):
    er_rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)
    ck = '{0}_{1}_externalrecords'.format(pds.protocol.id, subject.id)
    # See if our records are in the cache.
    resp = cache.get(ck)
    if resp:
        pds_records = []
        for record in json.loads(resp):
            if record['external_system'] == pds.id:
                pds_records.append(
                    ExternalRecord(-1).identity_from_jsonObject(record))
    else:
        try:
            pds_records = er_rh.get(external_system_url=pds.data_source.url,
                                    path=pds.path,
                                    subject_id=subject.id)
        except PageNotFound:
            pds_records = []

    for ex_rec in pds_records:
        for label in labels:
            if ex_rec.label_id == label['id']:
                if label['label'] == '':
                    ex_rec.label_desc = 'Record'
                else:
                    ex_rec.label_desc = label['label']
    return pds_records
Esempio n. 4
0
 def getEhbServiceInstance(self):
     '''
     Gets the record for this organization as maintained in the ehb service
     PageNotFound Exception will be thrown if no record is found
     '''
     rh = ServiceClient.get_rh_for(record_type=ServiceClient.ORGANIZATION)
     return rh.get(name=self.name)
Esempio n. 5
0
 def getOrgFromSelection(self, selection):
     # This is the organization object in the local portal app db
         _org = protocols.Organization.objects.get(pk=selection)
         _org_name = _org.name
         # the ehb-service organization object this is guaranteed to have the correct id
         orh = ServiceClient.get_rh_for(record_type=ServiceClient.ORGANIZATION)
         return orh.get(name=_org_name)
Esempio n. 6
0
 def clean(self):
     rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_SYSTEM)
     try:
         json.loads(self.driver_configuration)
     except ValueError:
         msg = ('Please enter a valid JSON object in Driver Configuration Options. ' +
                'If there is no configuration enter "{}"')
         raise ValidationError(msg)
 def getProtocolGroup(self, protocol):
     gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
     ck = self._settings_prop('CLIENT_KEY', 'key', '')
     n = 'BRP:'+protocol.immutable_key.key
     grp = gh.get(name=n)
     grp.client_key = ck
     # grp = Group(name = n, description = 'A BRP Protocol Group', is_locking=True, client_key=ck)
     # gh.create(grp)
     return (gh, grp)
Esempio n. 8
0
 def getSubjects(self):
     '''
     Returns the ehb-service representation of the subjects that have
     external_records for this data_source
     '''
     es = self.getExternalSystem()
     if es:
         rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_SYSTEM)
         return rh.subjects(es.id)
 def cache_records(self):
     datasources = DataSource.objects.all()
     er_rh = ServiceClient.get_rh_for(
         record_type=ServiceClient.EXTERNAL_RECORD)
     for ds in datasources:
         ers = er_rh.query({'external_system_id':
                            ds.ehb_service_es_id})[0]['external_record']
         for record in ers:
             print record.record_id
    def delete_old_ehb_entities(self):
        '''
        This will remove the external_system entry for this protocol and the
        uneeded external records
        '''
        try:
            esrh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_SYSTEM)
            brp = esrh.get(url=ServiceClient.APP_URL)
            errh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)

            print 'deleting records on external system: {0}'.format(brp.name)
            errh.delete(external_system_id=brp.id)

            print 'deleting external system: {0}'.format(brp.name)
            esrh.delete(id=brp.id)
        except PageNotFound:
            # This only happens if NO records are found when making the record
            # requests, indicates there are no subjects
            print '******** page not found in delete old ehb entities'
 def migrate_subject(self, subject, protocol):
     try:
         # Create a Group for this subject / protocol combination
         orh = ServiceClient.get_rh_for(record_type=ServiceClient.ORGANIZATION)
         ehb_org = orh.get(id=subject.organization_id)
         brp_org = Organization.objects.get(name=ehb_org.name)
         gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
         ck = self._settings_prop('CLIENT_KEY', 'key', '')
         n = 'BRP:'+protocol.immutable_key.key+':'+brp_org.immutable_key.key+':'+subject.organization_subject_id
         grp = Group(name=n,
                     description='A BRP Protocol Subject Record Group',
                     is_locking=True,
                     client_key=ck)
         gh.create(grp)
         print 'created subject records group: {0} for subject: {1} on protocol: {2}'.format(
             n,
             subject.organization_subject_id,
             protocol.name)
         # Add the subjects records to this group
         errh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)
         records = errh.get(subject_id=subject.id, path=protocol.name)
         print 'subject {0}, {1}, id={2} has the following records:'.format(
             subject.last_name,
             subject.first_name,
             subject.id)
         for rec in records:
             print 'id={0}, path={1}, ex_sys_id={2}, subject_id={3}'.format(
                 rec.id,
                 rec.path,
                 rec.external_system_id,
                 rec.subject_id
             )
             gh.add_records(grp, records)
         print 'added {0} records for subject: {1} on protocol: {2} to group: {3}'.format(
             len(records),
             subject.organization_subject_id,
             protocol.name,
             grp.name
         )
 except Exception:
     print '********failed to move subject records for ', subject.organization_subject_id
Esempio n. 12
0
 def getExternalSystem(self):
     '''
     This returns the ehb-service representation of this DataSource
     '''
     rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_SYSTEM)
     es = rh.get(url=self.url)
     if es:
         if es.id != self.ehb_service_es_id:
             # The record id's changed on the ehb-service, so update
             self.ehb_service_es_id = es.id
             self.save()
     return es
Esempio n. 13
0
    def create_new_ehb_external_record(protocol_data_source, user, subject, record_id, label=None):
        '''
        Creates a new external record in the ehb-service for this data source,
        subject, record_id and

        Output
        ------
        If successful returns the

        ehb_client.external_record_request_handler.ExternalRecord object
        '''

        es = protocol_data_source.data_source.getExternalSystem()

        # Want to make sure we're not going to overwrite a record already in the system
        try:
            if not label:
                label = 1
            er = ExternalRecord(
                record_id=record_id,
                subject_id=subject.id,
                external_system_id=es.id,
                path=protocol_data_source.path,
                label_id=label
            )
            errh = ServiceClient.get_rh_for(
                record_type=ServiceClient.EXTERNAL_RECORD
            )
            response = errh.create(er)[0]
            if(response.get('success')):
                SubjectUtils.add_record_to_subject_record_group(
                    protocol_data_source.protocol,
                    subject,
                    er
                )
                return er
            else:
                errors = response.get('errors')
                raise RecordCreationError(
                    'electronic Honest Broker',
                    '',
                    record_id,
                    errors
                )
        except RecordCreationError as rce:
            raise rce
        except Exception as e:
            raise RecordCreationError(
                'electronic Honest Broker',
                '',
                record_id,
                str(e)
            )
Esempio n. 14
0
 def delete_protocol_subject_record_group(protocol, subject):
     try:
         n = SubjectUtils.protocol_subject_record_group_name(protocol, subject)
         gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
         ck = protocol._settings_prop('CLIENT_KEY', 'key', '')
         grp = Group(
             name=n,
             description='A BRP Protocol Subject Record Group',
             is_locking=True,
             client_key=ck
         )
         r = gh.delete(grp)
         return r[0].get('success')
     except:
         return False
Esempio n. 15
0
def notify_record_creation_listeners(notifier, notifier_rec_id, notifier_pds,
                                     user, subject_id):
    '''
    Inputs:
    notifier : the driver that created the new record
    notifier_rec_id : the record in in the external system (not the eHB id)
    notifier_pds : the protocol data source where the new record was created
    subject_id : the eHB subject record id (not the organization subject id)
    '''
    # get the data link plugin selections
    for link in ProtocolDataSourceLink.objects.all():
        mod_name = link.linker_module()
        mod = __import__(mod_name)
        the_split = mod_name.split('.')
        subname = '.'
        for i in range(len(the_split) - 1):
            subname += the_split[i + 1] + '.'

        listener = None
        cmd = 'listener = mod' + subname + link.linker_class() + '()'
        exec(cmd)

        do_notify = 0 in listener.notify_on()
        if do_notify:
            listener_pds = None
            if notifier_pds == link.pds_one:
                listener_pds = link.pds_two
            else:
                listener_pds = link.pds_one

            listener_driver = DriverUtils.getDriverFor(
                protocol_data_source=listener_pds, user=user)
            listener.set_listener(listener_driver)

            es_url = listener_pds.data_source.url
            # Get the ehb-service external-records, it has the record-id for
            # the pds
            er_rh = ServiceClient.get_rh_for(
                record_type=ServiceClient.EXTERNAL_RECORD)
            try:
                records = er_rh.get(external_system_url=es_url,
                                    subject_id=subject_id,
                                    path=listener_pds.path)
                if len(records) == 1:
                    listener.set_listener_rec_id(records[0].record_id)
            except PageNotFound:
                listener.set_listener_rec_id(None)
            listener.notify(notifier, notifier_rec_id)
Esempio n. 16
0
 def save(self, *args, **kwargs):
     '''
     On save we need to make sure this organization exists in the
     ehb-service, otherwise create it
     '''
     rh = ServiceClient.get_rh_for(record_type=ServiceClient.ORGANIZATION)
     try:
         org = rh.get(name=self.name)
         super(Organization, self).save(*args, **kwargs)
     except PageNotFound:
         org = Organization(name=self.name, subject_id_label=self.subject_id_label)
         r = rh.create(org)[0]
         if(r.get('success')):
                 super(Organization, self).save(*args, **kwargs)
         else:
             raise Exception('Unable to create Organization record in ehb-service')
Esempio n. 17
0
 def create_protocol_subject_record_group(protocol, subject):
     try:
         n = SubjectUtils.protocol_subject_record_group_name(protocol, subject)
         gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
         ck = protocol._settings_prop('CLIENT_KEY', 'key', '')
         grp = Group(
             name=n,
             description='A BRP Protocol Subject Record Group',
             is_locking=True,
             client_key=ck
         )
         r = gh.create(grp)
         return r[0].get('success')
     except:
         logger.error("Failure creating a subject record group for {0}".format(n))
         return False
Esempio n. 18
0
 def save(self, *args, **kwargs):
     super(Protocol, self).save(*args, **kwargs)
     # Need to create a group for this protocol if it doesn't exist
     # (i.e. before there is a pk) that will be used to identify subjects
     # on the protocol
     gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
     try:
         gh.get(name=self.ehb_group_name())
     except RequestedRangeNotSatisfiable:
         grp = Group(
             name=self.ehb_group_name(),
             description='A BRP Protocol Group',
             is_locking=True,
             client_key=self._client_key()
         )
         r = gh.create(grp)[0]
         if not (r.get("success")):
             raise Exception(
                 'Unable to create Protocol Subject Group in ehb-service')
Esempio n. 19
0
def getPDSSubject(pds, sub_id):
    ck = '{0}_subjects'.format(pds.protocol.id)
    resp = cache.get(ck)
    if resp:
        subs = json.loads(resp)
        for subject in subs:
            if subject['id'] == int(sub_id):
                return Subject(-1).identity_from_jsonObject(subject)
    else:
        try:
            s_rh = ServiceClient.get_rh_for(record_type=ServiceClient.SUBJECT)
            subject = s_rh.get(id=sub_id)
            if not pds.protocol.isSubjectOnProtocol(subject):
                raise Http404
            else:
                return subject
        except PageNotFound:
            raise Http404

    return None
Esempio n. 20
0
 def save(self, *args, **kwargs):
     '''
     On save we need to make sure this source exists in the ehb service, otherwise create it
     '''
     rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_SYSTEM)
     try:
         es = rh.get(url=self.url)
         self.ehb_service_es_id = es.id
         super(DataSource, self).save(*args, **kwargs)
     except PageNotFound:
         es = ExternalSystem(
             name=self.name,
             url=self.url,
             description=self.description
         )
         r = rh.create(es)[0]
         if(r.get('success')):
                 self.ehb_service_es_id = es.id
                 super(DataSource, self).save(*args, **kwargs)
         else:
             raise Exception('Unable to create ExternalSystem record in ehb-service')
Esempio n. 21
0
    def validate_new_record_id(protocol_data_source, subject, record_id, include_path):
        '''
        Checks if the record_id (an external system record id, not the eHB
        record id) is acceptable by eHB uniqueness rules.
        If yes, returns 0.
        Else returns:
            1 : record id already exists for this subject on this
                protocoldatasource
            2 : record id exists for this protocoldatasource for a
                different subject.
        '''

        er_rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)

        try:
            ehb_recs = None
            if include_path:
                ehb_recs = er_rh.get(
                    external_system_url=protocol_data_source.data_source.url,
                    path=protocol_data_source.path
                )
            else:
                ehb_recs = er_rh.get(
                    external_system_url=protocol_data_source.data_source.url
                )
            for record in ehb_recs:
                if record.record_id == record_id:
                    if record.subject_id == subject.id:
                        logger.error(
                            'Record id {0} already exists for subject {1} on datasource {2}'.format(
                                record.record_id,
                                subject.id,
                                protocol_data_source))
                        return 1
                    else:
                        logger.error('Record id {0} already exists for a different Subject'.format(record.record_id))
                        return 2
            return 0
        except PageNotFound:
            return 0
Esempio n. 22
0
    def clean(self):
        rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_SYSTEM)
        try:
            es = rh.get(url=self.url)
            if(self.name != es.name):
                self.name = es.name
                msg = ('Accept existing name? There is already a system in the' +
                       ' ehb-service with this URL but with the name: ' + es.name +
                       '. This DataSource can only be saved with that name.')
                raise ValidationError(msg)
        except PageNotFound:
            # The save method will create the record in the ehb-service
            pass

        try:
            es = rh.get(name=self.name)
            if(self.url != es.url):
                msg = ('Please change the name or correct the URL. There is ' +
                       'already a system in the ehb-service with this name but' +
                       ' with URL: ' + es.url)
                raise ValidationError(msg)
        except PageNotFound:
            # The save method will create the record in the ehb-service
            pass
Esempio n. 23
0
def pds_dataentry_list(request, pds_id, subject_id):
    '''
    renders a page with the list of current records in the procotol_data_source
    with id = pds_id for the Subject with ehb-service id = subject_id. The
    exact form of this page is protocol_data_source dependent as determined by
    the driver
    '''
    pds = getProtocolDataSource(pds_id)
    if not pds.protocol.isUserAuthorized(request.user):
        return forbidden(request)

    MANAGE_EXTERNAL_IDS = False
    er_label_rh = ServiceClient.get_rh_for(
        record_type=ServiceClient.EXTERNAL_RECORD_LABEL)
    lbls = er_label_rh.query()

    # Check to see if this PDS is managing external identifiers
    for _pds in pds.protocol.getProtocolDataSources():
        if _pds.driver == 3:
            ExIdSource = _pds
            MANAGE_EXTERNAL_IDS = True

    subject = getPDSSubject(pds=pds, sub_id=subject_id)

    # If we are managing external identifiers add them to the subject
    if MANAGE_EXTERNAL_IDS:
        subject.external_ids = getExternalIdentifiers(ExIdSource, subject,
                                                      lbls)

    o_rh = ServiceClient.get_rh_for(record_type=ServiceClient.ORGANIZATION)
    org = o_rh.get(id=subject.organization_id)
    es_url = pds.data_source.url

    # Get record ids for this (protocol, subject, data source) combination
    er_rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)
    er_label_rh = ServiceClient.get_rh_for(
        record_type=ServiceClient.EXTERNAL_RECORD_LABEL)

    if request.method == 'GET':
        record_list_html = '<div class="alert alert-info"><h4>No records found.</h4></div>'
        allow_more_records = False
        labels = filterLabels(pds, er_label_rh.query())
        try:
            records = er_rh.get(external_system_url=es_url,
                                subject_id=subject_id,
                                path=pds.path)
            records.sort(key=lambda x: x.created)
            records = [
                json.loads(record.json_from_identity(record))
                for record in records
            ]
            allow_more_records = pds.max_records_per_subject == (
                -1) or len(records) < pds.max_records_per_subject
            if len(records) > 0:
                prefix = '%s/dataentry/protocoldatasource/%s/subject/%s/record/' % (
                    ServiceClient.self_root_path, pds.id, subject.id)
                record_urls = [
                    '%s%s/start/' % (prefix, each['id']) for each in records
                ]
                driver = DriverUtils.getDriverFor(protocol_data_source=pds,
                                                  user=request.user)
                record_list_html = driver.recordListForm(
                    record_urls, records, labels)
        except PageNotFound:
            allow_more_records = pds.max_records_per_subject != 0

        authorized_sources, unauthorized_sources = _auth_unauth_source_lists(
            pds.protocol, request.user, pds)

        # TODO ADD A BOOLEAN ALLOW_CREATE_MORE_RECORDS =
        # pds.max_recrods_allowed < 0 or pds.max_records_allowed < len(records)
        # and pass this to render_to_response method to decide to show/hide create
        # button
        context = {
            'protocol': pds.protocol,
            'organization': org,
            'subject': subject,
            'root_path': ServiceClient.self_root_path,
            'pds': pds,
            'authorized_data_sources': authorized_sources,
            'unauthorized_data_sources': unauthorized_sources,
            'record_list_html': record_list_html,
            'allow_more_records': allow_more_records,
            'record_labels': labels,
            'redcap_status': getRedcapStatus()
        }
        resp = render_to_response('pds_dataentry_list.html',
                                  context,
                                  context_instance=RequestContext(request))
        return resp
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
        except:
            return HttpResponse(json.dumps({'status': 'error'}), 400)
        record = er_rh.get(id=data['er'])
        record.label_id = int(data['label_id'])
        er_rh.update(record)
        return HttpResponse(json.dumps({'status': 'ok'}), 200)
Esempio n. 24
0
 def protocol_subject_record_group_name(protocol, subject):
     orh = ServiceClient.get_rh_for(record_type=ServiceClient.ORGANIZATION)
     ehb_org = orh.get(id=subject.organization_id)
     brp_org = Organization.objects.get(name=ehb_org.name)
     return 'BRP:' + protocol.immutable_key.key + ':' +\
         brp_org.immutable_key.key + ':' + subject.organization_subject_id
Esempio n. 25
0
 def get_protocol_subject_record_group(protocol, subject):
     gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
     return gh.get(
         name=SubjectUtils.protocol_subject_record_group_name(protocol, subject)
     )
    def getProtocolSubjects(self, protocol):
        '''returns the Subject records for this protocol'''
        try:
            esrh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_SYSTEM)
            es = esrh.get(url=ServiceClient.APP_URL)
            return esrh.subjects(es.id, path=protocol.name)
        except PageNotFound:
            # This only happens if NO records are found when making the record
            # requests, indicates there are no subjects
            print '******** page not found for {0}, in get protocol subjects'.format(protocol.name)

        def migrate_subject(self, subject, protocol):
            try:
                # Create a Group for this subject / protocol combination
                orh = ServiceClient.get_rh_for(record_type=ServiceClient.ORGANIZATION)
                ehb_org = orh.get(id=subject.organization_id)
                brp_org = Organization.objects.get(name=ehb_org.name)
                gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
                ck = self._settings_prop('CLIENT_KEY', 'key', '')
                n = 'BRP:'+protocol.immutable_key.key+':'+brp_org.immutable_key.key+':'+subject.organization_subject_id
                grp = Group(name=n,
                            description='A BRP Protocol Subject Record Group',
                            is_locking=True,
                            client_key=ck)
                gh.create(grp)
                print 'created subject records group: {0} for subject: {1} on protocol: {2}'.format(
                    n,
                    subject.organization_subject_id,
                    protocol.name)
                # Add the subjects records to this group
                errh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)
                records = errh.get(subject_id=subject.id, path=protocol.name)
                print 'subject {0}, {1}, id={2} has the following records:'.format(
                    subject.last_name,
                    subject.first_name,
                    subject.id)
                for rec in records:
                    print 'id={0}, path={1}, ex_sys_id={2}, subject_id={3}'.format(
                        rec.id,
                        rec.path,
                        rec.external_system_id,
                        rec.subject_id
                    )
                    gh.add_records(grp, records)
                print 'added {0} records for subject: {1} on protocol: {2} to group: {3}'.format(
                    len(records),
                    subject.organization_subject_id,
                    protocol.name,
                    grp.name
                )
        except Exception:
            print '********failed to move subject records for ', subject.organization_subject_id

    def migrate_orgs(self):
        for org in Organization.objects.all():
            org.save()  # This should generate the immutable keys

    def migrate(self):
        self.migrate_orgs()
        for protocol in Protocol.objects.all():
            print '----------------------------------'
            print 'protocol ', protocol.name
            protocol.save()  # This should cause the protocol to create key and create it's group
            print 'created immutable key: {0} for protocol {1}'.format(
                protocol.immutable_key.key,
                protocol.name)

            gh, group = self.getProtocolGroup(protocol)
            print 'created protocol subject group {0} with id={1}'.format(
                group.name,
                group.id)
            subjects = self.getProtocolSubjects(protocol)
            if subjects:
                print 'adding {0} subjects to protocol {1} using group {2}'.format(
                    str(len(subjects)),
                    protocol.name,
                    group.name
                )
                gh.add_subjects(group, subjects)
                for subject in subjects:
                    self.migrate_subject(subject, protocol)
            else:
                print '********no subjects for protocol ', protocol.name
            print '----------------------------------'
        self.delete_old_ehb_entities()

        def handle(self, *args, **options):
            self.migrate()
Esempio n. 27
0
 def add_record_to_subject_record_group(protocol, subject, record):
     grp = SubjectUtils.get_protocol_subject_record_group(protocol, subject)
     grp.client_key = protocol._settings_prop('CLIENT_KEY', 'key', '')
     gh = ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
     gh.add_records(grp, [record])
Esempio n. 28
0
def pds_dataentry_form(request, pds_id, subject_id, form_spec, record_id):
    '''renders a page with a data form as generated by the driver for protocol_data_source with pk=pds_id for
    Subject with subject_id=subject_id. The specific data form is determined by the driver using the form_spec arg.
    '''
    def generateSubRecordForm(driver, external_record, form_spec,
                              attempt_count, max_attempts):
        try:
            key = 'subrecordform_{0}_{1}'.format(external_record.id, form_spec)
            # Caching turned off for the time being on SRF
            # cf = cache.get(key)
            cf = None
            if cf:
                return cf
            else:
                form = driver.subRecordForm(external_record=external_record,
                                            form_spec=form_spec,
                                            session=request.session)
            return form
        except RecordDoesNotExist:
            return None

    pds = getProtocolDataSource(pds_id)
    if not pds.protocol.isUserAuthorized(request.user):
        return forbidden(request)

    MANAGE_EXTERNAL_IDS = False
    er_label_rh = ServiceClient.get_rh_for(
        record_type=ServiceClient.EXTERNAL_RECORD_LABEL)
    lbls = er_label_rh.query()

    # Check to see if this PDS is managing external identifiers
    for _pds in pds.protocol.getProtocolDataSources():
        if _pds.driver == 3:
            ExIdSource = _pds
            MANAGE_EXTERNAL_IDS = True

    subject = getPDSSubject(pds=pds, sub_id=subject_id)

    # If we are managing external identifiers add them to the subject
    if MANAGE_EXTERNAL_IDS:
        subject.external_ids = getExternalIdentifiers(ExIdSource, subject,
                                                      lbls)

    er_rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)
    # this will be the ehb-service externalRecord for this pds, subject NOT the actual datasource record
    record = None
    error_msgs = []

    try:
        r = cache.get('externalrecord_{0}'.format(record_id))
        if r:
            record = ExternalRecord(1).identity_from_jsonObject(json.loads(r))
        else:
            record = er_rh.get(id=record_id)
    except PageNotFound:
        raise Http404

    try:
        driver = DriverUtils.getDriverFor(protocol_data_source=pds,
                                          user=request.user)
        # Need the external record for this pds, protcol, and subject
        # Get all external_record objects on the ehb-service for this system,
        # path, subject combination.
        if request.method == 'POST':
            # have the driver process this request
            key = 'subrecordform_{0}_{1}'.format(record.id, form_spec)
            # cache.delete(key)
            errors = driver.processForm(request=request,
                                        external_record=record,
                                        form_spec=form_spec,
                                        session=request.session)
            if errors:
                error_msgs = [e for e in errors]
            else:
                path = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/start/' % (
                    ServiceClient.self_root_path, pds.id, subject_id,
                    record_id)
                return HttpResponseRedirect(path)
        else:
            # Generate a new form
            form = generateSubRecordForm(driver, record, form_spec, 0, 1)
            if form:
                o_rh = ServiceClient.get_rh_for(
                    record_type=ServiceClient.ORGANIZATION)
                org = o_rh.get(id=subject.organization_id)
                form_submission_url = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/form_spec/%s/' % (
                    ServiceClient.self_root_path, pds.id, subject_id,
                    record_id, form_spec)
                # Find next form to support guided entry
                try:
                    forms = json.loads(pds.driver_configuration)['form_order']
                    current_index = forms.index(form_spec)
                    next_form = forms[current_index + 1]
                    next_form_url = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/form_spec/%s/' % (
                        ServiceClient.self_root_path, pds.id, subject_id,
                        record_id, next_form)
                except:
                    next_form_url = ''
                context = {
                    'subRecordForm': form,
                    'protocol': pds.protocol,
                    'organization': org,
                    'subject': subject,
                    'root_path': ServiceClient.self_root_path,
                    'pds': pds,
                    'form_submission_url': form_submission_url,
                    'next_form_url': next_form_url,
                    'rec_id': str(record_id),
                    'redcap_status': getRedcapStatus()
                }

                return render_to_response(
                    'pds_dataentry_srf.html',
                    context,
                    context_instance=RequestContext(request))
            else:
                error_msgs.append(
                    'No record exists in the data source with the record id supplied by the eHB.'
                )
                log.error('Error {0}'.format(' '.join(error_msgs)))
    except PageNotFound:
        error_msgs.append(
            'No record could be found in the eHB for this request')
        log.error('Error {0}'.format(' '.join(error_msgs)))
    except ProtocolUserCredentials.DoesNotExist:
        error_msgs.append(
            'Your user credentials were not found for %s. Please contact system administrator.'
            % pds.data_source.name)

    # Some error must have occured:
    log.error('Error {0}'.format(' '.join(error_msgs)))
    return HttpResponse(' '.join(error_msgs))
Esempio n. 29
0
def pds_dataentry_create(request, pds_id, subject_id):
    '''renders a page with a data record creation form as generated by the driver for protocol_data_source with pk=pds_id
    for Subject with subject_id=subject_id. The specific record creation form is driver dependent - and not all drivers
    implement the form.'''

    pds = getProtocolDataSource(pk=pds_id)
    log.info(
        'Attempting record creation for {0} on Protocol Datasource {1}'.format(
            subject_id, pds_id))

    MANAGE_EXTERNAL_IDS = False
    # Check to see if this PDS is managing external identifiers
    for _pds in pds.protocol.getProtocolDataSources():
        if _pds.driver == 3:
            ExIdSource = _pds
            MANAGE_EXTERNAL_IDS = True

    subject = getPDSSubject(pds=pds, sub_id=subject_id)
    er_label_rh = ServiceClient.get_rh_for(
        record_type=ServiceClient.EXTERNAL_RECORD_LABEL)
    lbls = er_label_rh.query()

    # If we are managing external identifiers add them to the subject
    if MANAGE_EXTERNAL_IDS:
        subject.external_ids = getExternalIdentifiers(ExIdSource, subject,
                                                      lbls)

    es_url = pds.data_source.url
    # get record ids for this protocol, subject, data source combination
    er_rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)

    allow_more_records = False

    try:
        records = er_rh.get(external_system_url=es_url,
                            subject_id=subject_id,
                            path=pds.path)
        allow_more_records = pds.max_records_per_subject == (
            -1) or len(records) < pds.max_records_per_subject
    except PageNotFound:
        allow_more_records = pds.max_records_per_subject != 0
    if not allow_more_records:
        log.error('Maximum number of records created for subject {0}'.format(
            subject_id))
        return HttpResponse(
            'Error: The maximum number of records has been created.')

    if not pds.protocol.isUserAuthorized(request.user):
        return forbidden(request)

    def rec_id_validator(new_record_id, include_path):
        return SubjectUtils.validate_new_record_id(pds, subject, new_record_id,
                                                   include_path)

    error_msgs = []
    try:
        driver = DriverUtils.getDriverFor(protocol_data_source=pds,
                                          user=request.user)
        # TODO ADD A BOOLEAN ALLOW_CREATE_MORE_RECORDS =
        # pds.max_recrods_allowed < 0 or pds.max_records_allowed < len(records)
        # if false show error message
        if driver.new_record_form_required():
            form_submission_url = '%s/dataentry/protocoldatasource/%s/subject/%s/create/' % (
                ServiceClient.self_root_path, pds.id, subject_id)
            if request.method == 'POST':
                # have the driver process the record create form
                try:
                    grp = SubjectUtils.get_protocol_subject_record_group(
                        pds.protocol, subject)
                    grp.client_key = pds.protocol._settings_prop(
                        'CLIENT_KEY', 'key', '')
                    rec_id_prefix = ''
                    data = extract_data_from_post_request(request)
                    label_id = data.get('label_id', 1)
                    label = er_label_rh.get(id=label_id)
                    if grp:
                        rec_id_prefix = grp.ehb_key
                    else:
                        log.error(
                            'Subject record group not found for {0}'.format(
                                subject_id))
                        raise Exception('No subject record group found')
                    try:
                        rec_id = driver.process_new_record_form(
                            request=request,
                            record_id_prefix=rec_id_prefix,
                            record_id_validator=rec_id_validator)
                        try:
                            notify_record_creation_listeners(
                                driver, rec_id, pds, request.user, subject_id)
                            # this will create the ehb external_record entry
                            # and add that record to the subject's record group
                            ehb_rec_id = SubjectUtils.create_new_ehb_external_record(
                                pds, request.user, subject, rec_id,
                                label_id).id

                            path = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/start/' % (
                                ServiceClient.self_root_path, pds.id,
                                subject_id, ehb_rec_id)
                            return HttpResponseRedirect(path)
                        except RecordCreationError as rce:  # exception from the eHB
                            log.error(rce.errmsg)
                            error_msgs.append(
                                ('The record could not be created on the '
                                 'electronic Honest Broker. Please contact a '
                                 'system administrator. There could be a '
                                 'connection problem.'))
                    except IgnoreEhbExceptions as iee:
                        # TODO this is a hack until BRP can create Nautilus records
                        rec_id = iee.record_id
                        ehb_rec_id = ''
                        path = None
                        label_id = request.REQUEST.get('label_id', 1)
                        label = er_label_rh.get(id=label_id)
                        try:
                            # this will create the ehb external_record entry
                            # and add that record to the subject's record group
                            ehb_rec = SubjectUtils.create_new_ehb_external_record(
                                pds, request.user, subject, rec_id, label_id)
                            ehb_rec_id = ehb_rec.id
                            path = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/start/' % (
                                ServiceClient.self_root_path, pds.id,
                                subject_id, ehb_rec_id)
                            notify_record_creation_listeners(
                                driver, rec_id, pds, request.user, subject_id)
                        except RecordCreationError as rce:  # exception from the eHB
                            log.error(rce.errmsg)
                            record_already_exists = 6
                            cause = rce.raw_cause
                            if cause and len(
                                    cause
                            ) == 1 and record_already_exists == cause[0]:
                                er_rh = ServiceClient.get_rh_for(
                                    record_type=ServiceClient.EXTERNAL_RECORD)
                                ehb_recs = er_rh.get(
                                    external_system_url=pds.data_source.url,
                                    subject_id=subject_id,
                                    path=pds.path)
                                ehb_rec_id = None
                                for record in ehb_recs:
                                    if record.record_id == rec_id:
                                        ehb_rec_id = record.id
                                if ehb_rec_id:
                                    path = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/start' % (
                                        ServiceClient.self_root_path, pds.id,
                                        subject_id, ehb_rec_id)
                                else:
                                    path = None
                                    error_msgs.append(
                                        'This Subject ID has already been assigned to another subject.'
                                    )
                                    form = driver.create_new_record_form(
                                        request)
                                    o_rh = ServiceClient.get_rh_for(
                                        record_type=ServiceClient.ORGANIZATION)
                                    org = o_rh.get(id=subject.organization_id)
                                    label = er_label_rh.get(id=label_id)
                                    context = {
                                        'recordCreateForm': form,
                                        'protocol': pds.protocol,
                                        'organization': org,
                                        'subject': subject,
                                        'root_path':
                                        ServiceClient.self_root_path,
                                        'pds': pds,
                                        'form_submission_url':
                                        form_submission_url,
                                        'errors': error_msgs,
                                        'label': label,
                                        'redcap_status': getRedcapStatus()
                                    }
                                    return render_to_response(
                                        'pds_dataentry_rec_create.html',
                                        context,
                                        context_instance=RequestContext(
                                            request))
                            else:
                                log.error('Record could not be created')
                                path = None
                                error_msgs.append((
                                    'The record could not be created on the '
                                    'electronic Honest Broker. Please contact '
                                    'a system administrator. There could be a'
                                    ' connection problem.'))
                        if path:
                            return HttpResponseRedirect(path)
                    # END OF HACK CODE
                except RecordCreationError as rce:  # exceptions from the driver (i.e. errors in the form)
                    log.error(rce.errmsg)
                    error_msgs.append(rce.cause)
                    form = driver.create_new_record_form(request)
                    o_rh = ServiceClient.get_rh_for(
                        record_type=ServiceClient.ORGANIZATION)
                    org = o_rh.get(id=subject.organization_id)
                    label = er_label_rh.get(id=label_id)
                    context = {
                        'recordCreateForm': form,
                        'protocol': pds.protocol,
                        'organization': org,
                        'subject': subject,
                        'root_path': ServiceClient.self_root_path,
                        'pds': pds,
                        'form_submission_url': form_submission_url,
                        'errors': error_msgs,
                        'label': label,
                        'redcap_status': getRedcapStatus()
                    }
                    return render_to_response(
                        'pds_dataentry_rec_create.html',
                        context,
                        context_instance=RequestContext(request))
            else:  # request method not post
                # have the driver generate the form and render it
                form = driver.create_new_record_form(request)
                o_rh = ServiceClient.get_rh_for(
                    record_type=ServiceClient.ORGANIZATION)
                org = o_rh.get(id=subject.organization_id)
                label_id = request.REQUEST.get('label_id', 1)
                label = er_label_rh.get(id=label_id)
                context = {
                    'recordCreateForm': form,
                    'protocol': pds.protocol,
                    'organization': org,
                    'subject': subject,
                    'root_path': ServiceClient.self_root_path,
                    'pds': pds,
                    'form_submission_url': form_submission_url,
                    'label': label,
                    'redcap_status': getRedcapStatus()
                }
                return render_to_response(
                    'pds_dataentry_rec_create.html',
                    context,
                    context_instance=RequestContext(request))
        else:
            # Show a confirmation form and on POST just ask driver to create
            # the new record, and redirect to start page
            try:
                label_id = request.REQUEST.get('label_id', 1)
                label = er_label_rh.get(id=label_id)
                ehb_rec_id = _create_external_system_record(request,
                                                            driver,
                                                            pds,
                                                            subject,
                                                            label=label_id)
                path = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/start/' % (
                    ServiceClient.self_root_path, pds.id, subject_id,
                    ehb_rec_id)
                return HttpResponseRedirect(path)
            except RecordCreationError as rce:  # exception from the eHB
                log.error(rce.errmsg)
                error_msgs.append(
                    ('The record could not be created. Please contact a system'
                     ' administrator. There could be a connection problem.'))
    except ProtocolUserCredentials.DoesNotExist:
        error_msgs.append('Your user credentials were not found for ' +
                          pds.data_source.name +
                          '. Please contact system administrator.')

    # some error must have occurred if this code is reached
    return HttpResponse(' '.join(error_msgs))
Esempio n. 30
0
def edit_subject(request, protocol_id, subject_ehb_id):
    '''
    renders / processes a subject edit form to update subject phi in ehb system
    '''
    try:
        protocol = Protocol.objects.get(pk=protocol_id)
        # is this user authorized for this protocol? A user could accidently /
        # maliciously manually enter the URL for an unauthorized protocol
        if not protocol.isUserAuthorized(request.user):
            return forbidden(request)
        organizations = protocol.organizations.all()
        s_rh = ServiceClient.get_rh_for(record_type=ServiceClient.SUBJECT)

        msg = None

        try:
            subject = s_rh.get(id=subject_ehb_id)
            '''
            Is this subject on this protocol? A user could accidently /
            maliciously manually enter the URL a protocol they are authorized
            on but for which the subject is not on OR the link could be stale
            because the ehb primary key is used to ask for this subject record.
            this key is NOT stored in this app's DB. Rather it is dynamically
            added to the link in the subject select page. There is the unlikely
            chance that the link becomes stale between the time it is rendered
            and the time it is clicked. Hence, a second check is done to make
            sure this subject is on this protocol. This check done without
            reference to the ehb's primary key values
            '''
            if not protocol.isSubjectOnProtocol(subject):
                raise Http404
        except PageNotFound:
            raise Http404

        if request.method == 'POST':
            # process the form
            form = EditSubjectForm(request.POST)
            if form.is_valid():
                success, subject, errors = form.save(subject=subject,
                                                     protocol=protocol)
                if success:
                    cache.delete('{0}_subjects'.format(protocol.id))
                    return HttpResponseRedirect(
                        '%s/dataentry/protocol/%s/' %
                        (ServiceClient.self_root_path, protocol_id))
                else:
                    msg = []
                    selected_organization = form.selectedOrg()
                    for error in errors:
                        if error == ErrorConstants.ERROR_SUBJECT_ORG_ID_EXISTS:
                            l = Organization.objects.get(
                                pk=int(selected_organization)).subject_id_label
                            msg.append(
                                'A Subject record with this %s is already in the ehb-service system.'
                                % l)
                        else:
                            msg.append(error)
            else:
                selected_organization = form.selectedOrg()
        else:
            # render new form for this subject
            context = {
                'subject_id': str(subject.organization_subject_id),
                'subject_id_verify': str(subject.organization_subject_id),
                'first_name': subject.first_name,
                'last_name': subject.last_name,
                'dob': RequestBase.stringFromDate(subject.dob)
            }
            form = EditSubjectForm(context)
            o_rh = ServiceClient.get_rh_for(
                record_type=ServiceClient.ORGANIZATION)
            selected_organization = '0'
            try:
                org = o_rh.get(id=subject.organization_id)
                for o in organizations:
                    if o.name == org.name:
                        selected_organization = str(o.id)
            except PageNotFound:
                raise Http404

        return render_to_response('subject_edit.html', {
            'errors': msg,
            'form': form,
            'selected_organization': selected_organization,
            'protocol': protocol,
            'organizations': organizations,
            'subject': subject,
            'root_path': ServiceClient.self_root_path,
            'redcap_status': getRedcapStatus()
        },
                                  context_instance=RequestContext(request))

    except Protocol.DoesNotExist:
        raise Http404
Esempio n. 31
0
def pds_dataentry_start(request, pds_id, subject_id, record_id):
    '''
    Renders a page with the start page for the protocol_data_source with
    id = pds_id for the Subject with ehb-service id = subject_id. The exact
    form of this page is protocol_data_source dependent as determined by the
    driver
    '''
    def generateSubRecordSelectionForm(driver,
                                       record_id,
                                       form_url,
                                       print_url,
                                       attempt_count,
                                       max_attempts,
                                       allow_print=False,
                                       allow_zpl=False,
                                       allow_chop_print=False):
        try:
            return driver.subRecordSelectionForm(
                form_url=form_url,
                print_url=print_url,
                allow_print=allow_print,
                allow_zpl=allow_zpl,
                allow_chop_print=allow_chop_print,
                record_id=record_id)
        except RecordDoesNotExist:
            return None

    pds = getProtocolDataSource(pds_id)
    if not pds.protocol.isUserAuthorized(request.user):
        return forbidden(request)

    er_label_rh = ServiceClient.get_rh_for(
        record_type=ServiceClient.EXTERNAL_RECORD_LABEL)
    lbls = er_label_rh.query()

    MANAGE_EXTERNAL_IDS = False
    # Check to see if this PDS is managing external identifiers
    for _pds in pds.protocol.getProtocolDataSources():
        if _pds.driver == 3:
            ExIdSource = _pds
            MANAGE_EXTERNAL_IDS = True

    subject = getPDSSubject(pds=pds, sub_id=subject_id)

    # If we are managing external identifiers add them to the subject
    if MANAGE_EXTERNAL_IDS:
        subject.external_ids = getExternalIdentifiers(ExIdSource, subject,
                                                      lbls)

    er_rh = ServiceClient.get_rh_for(record_type=ServiceClient.EXTERNAL_RECORD)
    record = None  # this will be the ehb-service externalRecord for this pds, subject NOT the actual datasource record
    error_msgs = []
    # get the record from the ehb with this record id and verify that it is in
    # the protocol data source for this subject
    try:
        pds_records = er_rh.get(external_system_url=pds.data_source.url,
                                path=pds.path,
                                subject_id=subject.id)
        record = er_rh.get(id=record_id)
        if record and pds_records:
            if record not in pds_records:
                raise Http404
        else:
            raise Http404
    except PageNotFound:
        raise Http404

    # if a proper record exists, get the html from the driver and display it
    if record:
        try:
            o_rh = ServiceClient.get_rh_for(
                record_type=ServiceClient.ORGANIZATION)
            er_label_rh = ServiceClient.get_rh_for(
                record_type=ServiceClient.EXTERNAL_RECORD_LABEL)
            org = o_rh.get(id=subject.organization_id)
            driver = DriverUtils.getDriverFor(protocol_data_source=pds,
                                              user=request.user)

            form_url = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/form_spec/' % (
                ServiceClient.self_root_path, pds.id, subject_id, record_id)
            print_url = '%s/dataentry/protocoldatasource/%s/subject/%s/record/%s/print/' % (
                ServiceClient.self_root_path, pds.id, subject_id, record_id)

            creds = ProtocolUserCredentials.objects.get(protocol=pds.protocol,
                                                        user=request.user,
                                                        data_source=pds)

            srsf = generateSubRecordSelectionForm(
                driver,
                record.record_id,
                form_url,
                print_url,
                0,
                1,
                allow_print=creds.allow_label_printing,
                allow_zpl=creds.allow_zpl_export,
                allow_chop_print=creds.allow_chop_printing)
            label = er_label_rh.get(id=record.label_id)
            if srsf:
                authorized_sources, unauthorized_sources = _auth_unauth_source_lists(
                    pds.protocol, request.user, pds)
                context = {
                    'subRecordSelectionForm': srsf,
                    'protocol': pds.protocol,
                    'authorized_data_sources': authorized_sources,
                    'unauthorized_data_sources': unauthorized_sources,
                    'organization': org,
                    'subject': subject,
                    'root_path': ServiceClient.self_root_path,
                    'pds_id': pds.id,
                    'label': label,
                    'redcap_status': getRedcapStatus()
                }
                return render_to_response(
                    'pds_dataentry_start.html',
                    context,
                    context_instance=RequestContext(request))
            else:
                # the ehb has a record id, but the records wasn't created in
                # the external system.
                error_msgs.append(
                    'No record exists in the data source with the record id supplied by the eHB.'
                )

        except ProtocolUserCredentials.DoesNotExist:
            log.error(
                'User {0} attempted access on {1}. Credentials not found'.
                format(request.user, pds.data_source.name))
            error_msgs.append(('Your user credentials were not found for'
                               ' %s. Please contact system administrator.') %
                              (pds.data_source.name))
    '''
    Either multiple records exist in the ehb-service for this
    system/path/subject and hence proper record cannot be identified # OR the
    record does not exist and creation of the record failed
    '''
    return HttpResponse(' '.join(error_msgs))
Esempio n. 32
0
 def _gh(self):
     return ServiceClient.get_rh_for(record_type=ServiceClient.GROUP)
Esempio n. 33
0
def subject_select(request, protocol_id):
    '''
    renders a page with a table of subjects on the protocol with links to
    access the data sources with data on each subject
    '''
    try:
        p = Protocol.objects.get(pk=protocol_id)
    except Protocol.DoesNotExist:
        raise Http404

    if not p.isUserAuthorized(request.user):
        return forbidden(request)

    subjects = getProtocolSubjects(p)

    er_label_rh = ServiceClient.get_rh_for(
        record_type=ServiceClient.EXTERNAL_RECORD_LABEL)
    lbls = er_label_rh.query()

    addl_id_column = None

    MANAGE_EXTERNAL_IDS = False

    for pds in p.getProtocolDataSources():
        if pds.driver == 3:
            ExIdSource = pds
            MANAGE_EXTERNAL_IDS = True

    organizations = p.organizations.all()
    # add the organization name to the subject object for use in template
    ehb_orgs = []
    for o in organizations:
        ehb_orgs.append(o.getEhbServiceInstance())
    if subjects:
        for s in subjects:
            s.dob = s.dob.strftime('%Y-%m-%d')
            # Check whether or not we're managing External Identifiers
            if MANAGE_EXTERNAL_IDS:
                try:
                    config = json.loads(ExIdSource.driver_configuration)
                    if 'sort_on' in config.keys():
                        lbl = None
                        for l in lbls:
                            if l['id'] == config['sort_on']:
                                lbl = l
                        addl_id_column = lbl
                except:
                    pass

                s.external_ids = getExternalIdentifiers(ExIdSource, s, lbls)

            for o in ehb_orgs:
                if s.organization_id == o.id:
                    s.organization_name = o.name

    authorized_sources, unauthorized_sources = _auth_unauth_source_lists(
        p, request.user)

    context = {
        'addl_id_column': addl_id_column,
        'subjects': subjects,
        'protocol': p,
        'organizations': ehb_orgs,
        'authorized_data_sources': authorized_sources,
        'unauthorized_data_sources': unauthorized_sources,
        'root_path': ServiceClient.self_root_path,
        'redcap_status': getRedcapStatus()
    }

    return render_to_response('subject_select.html',
                              context,
                              context_instance=RequestContext(request))
Esempio n. 34
0
    def save(self, protocol):
        '''
        Attempts to save the data provided in the form as a new subject in
        ehb-service database.

        Output
        ------

        If the form is valid:
            {
                subject: Subject_instance,
                "success": boolean,
                "errors": errors
            }
            (Where errors is only present if there were errors in creating the
            object in the server db)

        else:
            None
        '''
        if self.is_valid():
            cleandata = self.cleaned_data
            sub_id = cleandata.get('subject_id')
            fn = cleandata.get('first_name')
            ln = cleandata.get('last_name')
            dob = cleandata.get('dob')
            org = self.getOrgFromSelection(cleandata.get('organization'))

            # Create the subject record for this organization
            # First check if the subject is in the system at all, if not create it
            srh = ServiceClient.get_rh_for(record_type=ServiceClient.SUBJECT)

            errors = []
            try:
                subject = srh.get(organization_id=org.id, organization_subject_id=sub_id)
                # If found this indicates the subject is already in the ehb for
                # this organization, but not necessarily for this protocol.
                # That will be checked below in the external record search

                # check if all new_subject form fields match this existing
                # subject if not, the form data must be corrected
                # should add an option to update the record (permission to do so might be role based)
                success = True
                prefix = "A subject with this " + org.subject_id_label + " exists but with "
                if subject.first_name != fn:
                    success = False
                    errors.append(prefix + "first name: " + subject.first_name)
                if subject.last_name != ln:
                    success = False
                    errors.append(prefix + "last name: " + subject.last_name)
                if subject.dob != dob:
                    success = False
                    errors.append(prefix + "birth date: " + str(subject.dob))
            except PageNotFound:
                # Subject not in system so create it
                s = Subject(first_name=fn,
                            last_name=ln,
                            dob=dob,
                            organization_id=org.id,
                            organization_subject_id=sub_id)
                r = srh.create(s)[0]
                success = r.get('success')
                errors = r.get('errors')
                subject = r.get(Subject.identityLabel)

            # Don't proceed any further if there are already errors
            if not success:
                logger.error('There was an error creating the subject.')
                return [success, subject, errors]

            if not errors:
                errors = []
            # First check if the subject is already in the group
            if protocol.getSubjects() and subject in protocol.getSubjects():
                # Subject is already on this protocol
                errors.append(
                    'This subject ' + org.subject_id_label +
                    ' has already been added to this project.'
                )
                logger.error("Could not add subject. They already exist on this protocol.")
                success = False
            else:
                # Add this subject to the protocol and create external record group
                # Create subject/protocol external record group
                if SubjectUtils.create_protocol_subject_record_group(protocol, subject):
                    # Add subject to protocol subject group
                    if protocol.addSubject(subject):
                        success = True
                    else:
                        logger.error("Could not add subject. Failure to create Protocol Subject Record Group.")
                        errors.append(
                            'Failed to complete eHB transactions. Could not add subject to project. Please try again.')
                        success = False
                else:
                    # For some reason we couldn't get the eHB to add the subject to the protocol group
                    logger.error("Could not add subject to project. Could not add subject to the protocol group.")
                    errors.append(
                        'Failed to complete eHB transactions. Could not add subject to project. Please try again.')
                    success = False

            return [success, subject, errors]
        else:
            return None