Beispiel #1
0
def delete_others(data, model, patient=None, episode=None):
    """
    Deletes all subrecords that are not in data
    """
    # We can't import these at module load because we're imported by
    # opal.core.pathways.__init__
    from opal.models import EpisodeSubrecord, PatientSubrecord

    if issubclass(model, EpisodeSubrecord):
        existing = model.objects.filter(episode=episode)
    elif issubclass(model, PatientSubrecord):
        existing = model.objects.filter(patient=patient)
    else:
        err = "Delete others called with {} requires a subrecord"
        raise exceptions.APIError(err.format(model.__name__))

    if model._is_singleton:
        err = "You can't mass delete a singleton for {}"
        raise exceptions.APIError(err.format(model.__name__))

    existing_data = data.get(model.get_api_name(), [])
    ids = [i["id"] for i in existing_data if "id" in i]
    existing = existing.exclude(id__in=ids)

    for i in existing:
        i.delete()
Beispiel #2
0
    def update_from_dict(self, data, user):
        logging.info("updating {0} with {1} for {2}".format(
            self.__class__.__name__, data, user))
        if self.consistency_token:
            try:
                consistency_token = data.pop('consistency_token')
            except KeyError:
                raise exceptions.APIError('Missing field (consistency_token)')

            if consistency_token != self.consistency_token:
                raise exceptions.ConsistencyError

        fields = set(self._get_fieldnames_to_serialize())

        post_save = []

        unknown_fields = set(data.keys()) - fields

        if unknown_fields:
            raise exceptions.APIError('Unexpected fieldname(s): %s' %
                                      list(unknown_fields))

        for name in fields:
            value = data.get(name, None)

            if name.endswith('_fk_id'):
                if name[:-6] in fields:
                    continue
            if name.endswith('_ft'):
                if name[:-3] in fields:
                    continue

            if name == 'consistency_token':
                continue  # shouldn't be needed - Javascripts bug?
            setter = getattr(self, 'set_' + name, None)
            if setter is not None:
                setter(value, user, data)
            else:
                if name in data:
                    field_type = self._get_field_type(name)

                    if field_type == models.fields.related.ManyToManyField:
                        post_save.append(
                            functools.partial(self.save_many_to_many, name,
                                              value, field_type))
                    else:
                        if value and field_type == models.fields.DateField:
                            value = datetime.datetime.strptime(
                                value, '%Y-%m-%d').date()
                        if value and field_type == models.fields.DateTimeField:
                            value = dateparse.parse_datetime(value)

                        setattr(self, name, value)

        self.set_consistency_token()
        self.save()

        for some_func in post_save:
            some_func()
Beispiel #3
0
    def save_many_to_many(self, name, values, field_type):
        field = getattr(self, name)
        new_lookup_values = self.get_lookup_list_values_for_names(
            field.model, values)

        new_values = new_lookup_values.values_list("id", flat=True)
        existing_values = field.all().values_list("id", flat=True)

        to_add = set(new_values) - set(existing_values)
        to_remove = set(existing_values) - set(new_values)

        if len(new_values) != len(values):
            # the only way this should happen is if one of the incoming
            # values is a synonym for another incoming value so lets check this
            synonym_found = False
            new_names = new_lookup_values.filter(name__in=values)
            values_set = set(values)

            for new_name in new_names:
                synonyms = set(new_name.synonyms.all().values_list("name",
                                                                   flat=True))
                if values_set.intersection(synonyms):
                    synonym_found = True
                    logging.info("found synonym {0} for {1}".format(
                        synonyms, values_set))
                    break

            if not synonym_found:
                error_msg = 'Unexpected fieldname(s): {}'.format(values)
                logging.error(error_msg)
                raise exceptions.APIError(error_msg)

        field.add(*to_add)
        field.remove(*to_remove)
Beispiel #4
0
 def get_data_from_fhir_server(self, cerner_mrn):
     query_type = "Patient"
     url = self.API_DETAILS['cerner_open']['api_base_url'] + query_type
     identifier_string = self.API_DETAILS['cerner_open']['ident_token_prefix'] + "|" + cerner_mrn
     querystring = {"identifier": identifier_string}
     headers = {'accept': "application/json",}
     response = requests.request("GET", url, headers=headers, params=querystring)
     if response.status_code == 200:
         return response.json()
     else:
         msg = "Error contacting external FHIR demographic API from Epidur.io"
         raise exceptions.APIError(msg)
Beispiel #5
0
    def _get_field_default(cls, name):
        field = cls._get_field(name)

        if isinstance(field, models.ManyToOneRel):
            default = []
        else:
            default = field.get_default()

        # for blank fields the result is a blank string, lets just remove that
        if default == '':
            return None

        if isinstance(default, datetime.date):
            raise exceptions.APIError(
                "{0}.{1} returned a date as a default, Opal currently does "
                "not support sending dates/datetimes as defaults".format(
                    cls, name
                )
            )

        return default
Beispiel #6
0
    def update_from_dict(self, data, user, force=False, fields=None):
        logging.info("updating {0} with {1} for {2}".format(
            self.__class__.__name__, data, user
        ))
        if fields is None:
            fields = set(self._get_fieldnames_to_serialize())

        if self.consistency_token and not force:
            try:
                consistency_token = data.pop('consistency_token')
            except KeyError:
                msg = 'Missing field (consistency_token) for {}'
                raise exceptions.MissingConsistencyTokenError(
                    msg.format(self.__class__.__name__)
                )

            if consistency_token != self.consistency_token:
                raise exceptions.ConsistencyError

        post_save = []

        unknown_fields = set(data.keys()) - fields

        if unknown_fields:
            raise exceptions.APIError(
                'Unexpected fieldname(s): %s' % list(unknown_fields))

        for name in fields:
            value = data.get(name, None)

            if name == 'consistency_token':
                continue  # shouldn't be needed - Javascripts bug?
            setter = getattr(self, 'set_' + name, None)
            if setter is not None:
                setter(value, user, data)
            else:
                if name in data:
                    field_type = self._get_field_type(name)

                    if field_type == models.fields.related.ManyToManyField:
                        post_save.append(
                            functools.partial(self.save_many_to_many,
                                              name,
                                              value,
                                              field_type))
                    else:
                        DateTimeField = models.fields.DateTimeField
                        if value and field_type == models.fields.DateField:
                            value = serialization.deserialize_date(value)
                        elif value and field_type == DateTimeField:
                            value = serialization.deserialize_datetime(value)
                        elif value and field_type == models.fields.TimeField:
                            value = serialization.deserialize_time(value)

                        setattr(self, name, value)

        self.set_consistency_token()
        self.save()

        for some_func in post_save:
            some_func()