Example #1
0
class DemographicsRequestColumn(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    demographics_request_id = db.Column(db.Integer,
                                        db.ForeignKey(DemographicsRequest.id))
    demographics_request = db.relationship(
        DemographicsRequest,
        foreign_keys=[demographics_request_id],
        backref=db.backref("columns"))
    name = db.Column(db.String(500))
    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(
        User, foreign_keys=[last_updated_by_user_id])

    def __lt__(self, other):
        return self.name < other.name

    def __repr__(self):
        fields = '; '.join([
            f'{key}="{value}"' for key, value in self.__dict__.items()
            if key[0] != '_'
        ])
        return f'[{type(self).__name__}({fields})]'
Example #2
0
class LegacyId(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    legacy_id_provider_id = db.Column(db.Integer,
                                      db.ForeignKey(LegacyIdProvider.id))
    legacy_id_provider = db.relationship(LegacyIdProvider)
    number = db.Column(db.Integer, nullable=False)
    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)

    def __repr__(self):
        return str(self.__class__) + ": " + str(self.__dict__)

    def __str__(self):
        return self.prefix + self.zero_filled_number

    @property
    def barcode(self):
        return '{}{}'.format(
            self.legacy_id_provider.prefix,
            str(self.number).zfill(
                self.legacy_id_provider.number_fixed_length),
        )
Example #3
0
class TaskFile(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    filename = db.Column(db.UnicodeText())
    local_filepath = db.Column(db.UnicodeText())
    task_id = db.Column(db.Integer, db.ForeignKey(Task.id))
    task = db.relationship(Task,
                           backref=backref('files',
                                           cascade='all, delete-orphan'))
    field_id = db.Column(db.Integer, db.ForeignKey(Field.id))
    field = db.relationship(Field, lazy="joined")

    def set_filename_and_save(self, file):
        self.filename = file.filename

        local_filepath = self._new_local_filepath(
            filename=file.filename,
            parent=str(self.task.id),
        )

        self.local_filepath = str(local_filepath)

        local_filepath.parent.mkdir(parents=True, exist_ok=True)
        file.save(local_filepath)

    def _new_local_filepath(self, filename, parent=None):
        result = pathlib.Path(current_app.config["FILE_UPLOAD_DIRECTORY"])

        if parent:
            result = result.joinpath(secure_filename(parent))

        result = result.joinpath(
            secure_filename("{}_{}".format(uuid.uuid1().hex, filename)))

        return result
Example #4
0
class Organisation(db.Model, CommonMixin):

    CARDIOVASCULAR = 'BRC Cardiovascular Theme'
    LIFESTYLE = 'BRC Lifestyle Theme'
    PRECICION = 'BRC Precision Medicine Theme'
    RESPIRATORY = 'BRC Respiratory Theme'
    LDC = 'Leicester Diabetes Centre'
    PRC = 'Patient Recruitment Centre'
    RandI = 'R&I'
    OTHER = 'Other - please specify'

    all_organisations = [
        CARDIOVASCULAR, LIFESTYLE, PRECICION, RESPIRATORY, LDC, PRC, RandI,
        OTHER
    ]

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(255))

    @classmethod
    def get_organisation(cls, name):
        return Organisation.query.filter_by(name=name).one()

    @classmethod
    def get_other(cls):

        return cls.get_organisation(Organisation.OTHER)
Example #5
0
class BlindingSet(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    study_id = db.Column(db.Integer, db.ForeignKey(Study.id), nullable=False)
    study = db.relationship(Study, backref=db.backref("blinding_sets"))

    def __repr__(self):
        return self.name

    def __lt__(self, other):
        return self.name < other.name

    def get_blind_ids(self, unblind_id, user):
        result = []

        for bt in self.blinding_types:
            blind_id = bt.get_blind_id(unblind_id, user)
            if blind_id:
                result.append(blind_id)

        return result

    def get_unblind_id(self, blind_id):
        for bt in self.blinding_types:
            unblind_id = bt.get_unblind_id(blind_id)
            if unblind_id:
                return unblind_id
Example #6
0
class TaskAssignedUser(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    task_id = db.Column(db.Integer, db.ForeignKey(Task.id), nullable=False)
    task = db.relationship(Task, backref="assigned_user_history")
    user_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
    user = db.relationship(User)
    notes = db.Column(db.String(255))
Example #7
0
class ApiKey(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    key = db.Column(GUID, nullable=False, default=uuid.uuid4)
    user_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
    user = db.relationship(User, backref=db.backref("api_key", uselist=False))

    def __repr__(self):
        return f'API Key for User {self.user.full_name}'
Example #8
0
class FieldGroup(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String)

    def __str__(self):
        return self.name

    def get_field_for_field_name(self, field_name):
        return {f.field_name: f for f in self.fields}.get(field_name)
Example #9
0
class AbstractSection(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    publication_id = db.Column(db.Integer(), db.ForeignKey(Publication.id))
    publication = db.relationship(Publication,
                                  lazy="joined",
                                  backref='abstracts')
    label = db.Column(db.String(200))
    text = db.Column(db.UnicodeText())
Example #10
0
class LabelPack(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(100), nullable=False)
    study_id = db.Column(db.Integer, db.ForeignKey(Study.id))
    study = db.relationship(Study, backref=db.backref("label_packs"))

    __mapper_args__ = {
        "polymorphic_identity": "Pack",
        "polymorphic_on": type,
    }

    def user_defined_participant_id(self):
        return False

    def allow_batch_printing(self):
        return True

    @property
    def name(self):
        return re.sub('([a-z])([A-Z])', r'\1 \2', self.__class__.__name__)

    def print(self, count):
        for _ in range(count):
            current_app.logger.info(
                f'Printing label for study {self.study.name}')

            self._do_print()

            db.session.commit()

            time.sleep(current_app.config['PRINTING_SET_SLEEP'])

    def save_participant_id(self, participant_id):
        pit = ParticipantIdentifierType.get_study_participant_id()

        pi = ParticipantIdentifier.query.filter_by(
            participant_identifier_type_id=pit.id,
            identifier=participant_id,
        ).one_or_none()

        if pi is None:
            db.session.add(
                ParticipantIdentifier(
                    participant_identifier_type_id=pit.id,
                    identifier=participant_id,
                    last_updated_by_user_id=current_user.id,
                ))

    def _do_print(self, participant_id=None):
        pass

    def __repr__(self):
        return self.name

    def __lt__(self, other):
        return self.name < other.name
Example #11
0
class StudyParticipant(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    study_id = db.Column(db.Integer, db.ForeignKey(Study.id), nullable=False)
    study = db.relationship(Study, backref=db.backref("participants"))

    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)
Example #12
0
class TaskStatus(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    task_id = db.Column(db.Integer, db.ForeignKey(Task.id), nullable=False)
    task = db.relationship(Task, backref="status_history")
    notes = db.Column(db.String(255))
    task_status_type_id = db.Column(db.Integer,
                                    db.ForeignKey(TaskStatusType.id),
                                    nullable=False)
    task_status_type = db.relationship(TaskStatusType,
                                       backref="assigned_tasks")
Example #13
0
class UploadData(db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    upload_id = db.Column(db.Integer(), db.ForeignKey(Upload.id))
    upload = db.relationship(Upload, backref=db.backref("data"))
    field_id = db.Column(db.Integer(), db.ForeignKey(Field.id))
    field = db.relationship(Field)
    value = db.Column(db.String)

    def __repr__(self):
        items = ("%s = %r" % (k, v) for k, v in self.__dict__.items())
        return "<%s: {%s}>" % (self.__class__.__name__, ', '.join(items))
Example #14
0
class Publication(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    pm_id = db.Column(db.Integer())
    journal = db.Column(db.String(200))
    published_date = db.Column(db.Date)
    title = db.Column(db.UnicodeText())

    academics = db.relationship("Academic",
                                secondary=academics_publications,
                                collection_class=set,
                                backref=db.backref("publications",
                                                   lazy="joined"))
Example #15
0
class BioresourceId(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    bioresource_id_provider_id = db.Column(
        db.Integer, db.ForeignKey(BioresourceIdProvider.id))
    bioresource_id_provider = db.relationship(BioresourceIdProvider)
    number = db.Column(db.Integer, nullable=False)
    check_character = db.Column(db.String(1), nullable=False)
    legacy_number = db.Column(db.Integer)
    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)

    def __repr__(self):
        return str(self.__class__) + ": " + str(self.__dict__)

    def __str__(self):
        return self.full_code

    @property
    def full_code(self):
        return self.bioresource_id_provider.prefix + str(
            self.number) + self.check_character

    @property
    def barcode(self):
        return self.full_code
Example #16
0
class Study(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    edge_id = db.Column(db.Integer, nullable=True)
    name = db.Column(db.String(50), nullable=False)

    def __str__(self):
        return self.name or ""

    def get_blind_ids(self, unblind_id, user):
        result = []

        for bs in self.blinding_sets:
            for bt in [t for t in bs.blinding_types if not t.deleted]:
                blind_id = bt.get_blind_id(unblind_id, user)
                if blind_id:
                    result.append(blind_id)

        return result
Example #17
0
class TaskData(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    value = db.Column(db.UnicodeText())
    task_id = db.Column(db.Integer, db.ForeignKey(Task.id))
    task = db.relationship(Task,
                           backref=backref('data',
                                           cascade='all, delete-orphan'))
    field_id = db.Column(db.Integer, db.ForeignKey(Field.id))
    field = db.relationship(Field, lazy="joined")

    @property
    def formated_value(self):
        return self.field.format_value(self.value)

    @property
    def data_value(self):
        return self.field.data_value(self.value)
Example #18
0
class LabelParticipantIdentifierSource(ParticipantIdentifierSource):
    __tablename__ = 'label_participant_identifier_source'

    id = db.Column(db.Integer,
                   db.ForeignKey('participant_identifier_source.id'),
                   primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'label_participant_identifier_source',
    }
Example #19
0
class Task(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(255))
    organisation_id = db.Column(db.Integer, db.ForeignKey(Organisation.id))
    organisation = db.relationship(Organisation,
                                   lazy="joined",
                                   backref='tasks')
    organisation_description = db.Column(db.String(255))
    service_id = db.Column(db.Integer, db.ForeignKey(Service.id))
    service = db.relationship(Service, lazy="joined", backref='tasks')
    requestor_id = db.Column(db.Integer,
                             db.ForeignKey(User.id),
                             nullable=False)
    requestor = db.relationship(User,
                                lazy="joined",
                                backref='tasks',
                                foreign_keys=[requestor_id])
    current_status_type_id = db.Column(db.Integer,
                                       db.ForeignKey(TaskStatusType.id),
                                       nullable=False)
    current_status_type = db.relationship(TaskStatusType)
    current_assigned_user_id = db.Column(db.Integer,
                                         db.ForeignKey(User.id),
                                         nullable=True)
    current_assigned_user = db.relationship(
        User, foreign_keys=[current_assigned_user_id])

    @property
    def long_name(self):
        return "{}: {}".format(self.service.name, self.name)

    @property
    def total_todos(self):
        return len(self.todos)

    @property
    def required_todos(self):
        return len([t for t in self.todos if t.is_required])

    @property
    def complete_todos(self):
        return len([t for t in self.todos if t.is_complete])

    @property
    def notification_email_addresses(self):
        return self.service.notification_email_addresses + [
            self.requestor.email
        ]

    def get_data_for_task_id(self, field_id):
        return next((t for t in self.data if t.field_id == field_id), None)
Example #20
0
class Site(db.Model):

    LBRC = "Leicester Biomedical Research Centre"

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(255))
    number = db.Column(db.String(20))
    date_created = db.Column(db.DateTime,
                             nullable=False,
                             default=datetime.utcnow)

    def __str__(self):
        return self.name

    @property
    def name_and_number(self):
        number_portion = ""
        if self.number:
            number_portion = " ({})".format(self.number)
        return self.name + number_portion
Example #21
0
class Blinding(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    unblind_id = db.Column(db.String(100), nullable=False)
    blinding_type_id = db.Column(db.Integer,
                                 db.ForeignKey(BlindingType.id),
                                 nullable=False)
    blinding_type = db.relationship(BlindingType,
                                    backref=db.backref("blindings"))
    pseudo_random_id_id = db.Column(db.Integer,
                                    db.ForeignKey(PseudoRandomId.id),
                                    nullable=False)
    pseudo_random_id = db.relationship(PseudoRandomId)
    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)

    def __repr__(self):
        return '; '.join([
            self.blinding_type.name,
            self.unblind_id,
            self.pseudo_random_id.full_code,
        ])

    def __lt__(self, other):
        return self.name < other.name
Example #22
0
class ToDo(AuditMixin, CommonMixin, db.Model):

    OUTSTANDING = 'Outstanding'
    COMPLETED = 'Completed'
    NOT_REQUIRED = 'Not Required'

    _status_map = {
        -1: NOT_REQUIRED,
        0: OUTSTANDING,
        1: COMPLETED,
    }

    @staticmethod
    def get_status_code_from_name(name):
        return {v: k for k, v in ToDo._status_map.items()}[name]

    id = db.Column(db.Integer(), primary_key=True)
    task_id = db.Column(db.Integer, db.ForeignKey(Task.id))
    task = db.relationship(Task, backref='todos')
    description = db.Column(db.UnicodeText())
    status = db.Column(db.Integer,
                       db.CheckConstraint("status IN (-1, 0, 1)"),
                       nullable=False,
                       default=0)

    @property
    def status_name(self):
        return ToDo._status_map[self.status]

    @property
    def is_outstanding(self):
        return self.status == 0

    @property
    def is_required(self):
        return self.status > -1

    @property
    def is_complete(self):
        return self.status == 1
Example #23
0
class ParticipantIdentifierSource(db.Model):
    __tablename__ = 'participant_identifier_source'

    id = db.Column(db.Integer, primary_key=True)
    linked_minimum_patient_identifier_source_id = db.Column(
        db.Integer,
        db.ForeignKey("participant_identifier_source.id"),
        nullable=True)
    type = db.Column(db.String(100), nullable=False)
    study_id = db.Column(db.Integer, db.ForeignKey(Study.id), nullable=True)
    study = db.relationship(
        Study, backref=db.backref("participant_identifier_sources"))

    __mapper_args__ = {
        'polymorphic_identity': 'participant_identifier_source',
        'polymorphic_on': type,
    }

    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)

    identifiers = db.relationship(
        "ParticipantIdentifier",
        secondary=participant_identifiers__participant_identifier_sources,
        back_populates="sources",
        collection_class=set)

    def __str__(self):
        return f"{self.type.name}: {self.identifier}"
Example #24
0
class Academic(AuditMixin, CommonMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    google_scholar_id = db.Column(db.String(255))
    name = db.Column(db.String(500))
    affiliation = db.Column(db.String(500))
    cited_by = db.Column(db.Integer)
    h_index = db.Column(db.Integer)
    i10_index = db.Column(db.Integer)
    is_updating = db.Column(db.Boolean)

    @property
    def pubmed_name(self):
        firstname, *_, lastname = self.name.split()
        return f'{lastname} {firstname[0]}'
Example #25
0
class ParticipantIdentifierType(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)

    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)

    def __str__(self):
        return self.name

    @staticmethod
    def get_type(type_name):
        return ParticipantIdentifierType.query.filter_by(
            name=type_name, ).one_or_none()

    @staticmethod
    def get_study_participant_id():
        return ParticipantIdentifierType.get_type(
            ParticipantIdentifierTypeName.STUDY_PARTICIPANT_ID)
Example #26
0
class ParticipantIdentifier(db.Model):
    __tablename__ = 'participant_identifier'

    id = db.Column(db.Integer, primary_key=True)
    identifier = db.Column(db.String(100), nullable=False)
    participant_identifier_type_id = db.Column(
        db.Integer, db.ForeignKey(ParticipantIdentifierType.id))
    participant_identifier_type = db.relationship(ParticipantIdentifierType)

    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)

    sources = db.relationship(
        "ParticipantIdentifierSource",
        secondary=participant_identifiers__participant_identifier_sources,
        back_populates="identifiers",
        collection_class=set)

    def __str__(self):
        return f"{self.type.name}: {self.identifier}"
Example #27
0
class Study(db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(100))
    date_created = db.Column(db.DateTime,
                             nullable=False,
                             default=datetime.utcnow)
    allow_duplicate_study_number = db.Column(db.Boolean,
                                             nullable=False,
                                             default=False)
    allow_empty_study_number = db.Column(db.Boolean,
                                         nullable=False,
                                         default=False)
    study_number_format = db.Column(db.String(50))
    study_number_name = db.Column(db.String(100))
    field_group_id = db.Column(db.Integer(), db.ForeignKey(FieldGroup.id))
    field_group = db.relationship(FieldGroup, backref=db.backref("study"))

    owners = db.relationship(
        User,
        secondary=studies_owners,
        backref=db.backref("owned_studies", lazy="dynamic"),
    )
    collaborators = db.relationship(
        User,
        secondary=studies_collaborators,
        backref=db.backref("collaborator_studies", lazy="dynamic"),
    )

    def __str__(self):
        return self.name

    @property
    def upload_count(self):
        return len([u for u in self.uploads if not u.deleted])

    def upload_count_for_user(self, user):
        return len(
            [u for u in self.uploads if not u.deleted and u.uploader == user])

    @property
    def outstanding_upload_count(self):
        return len(
            [u for u in self.uploads if not u.deleted and not u.completed])

    def get_study_number_name(self):
        return self.study_number_name or 'Study Number'
Example #28
0
class Upload(db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    study_id = db.Column(db.Integer(), db.ForeignKey(Study.id))
    study_number = db.Column(db.String(20))
    uploader_id = db.Column(db.Integer(), db.ForeignKey(User.id))
    date_created = db.Column(db.DateTime,
                             nullable=False,
                             default=datetime.utcnow)
    study = db.relationship(Study, backref=db.backref("uploads"))
    uploader = db.relationship(User)
    completed = db.Column(db.Boolean, default=0)
    deleted = db.Column(db.Boolean, default=0)
Example #29
0
class UploadFile(db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    upload_id = db.Column(db.Integer(), db.ForeignKey(Upload.id))
    upload = db.relationship(Upload, backref=db.backref("files"))
    field_id = db.Column(db.Integer(), db.ForeignKey(Field.id))
    field = db.relationship(Field)
    filename = db.Column(db.String(500))

    def get_download_filename(self):
        if len(self.field.download_filename_format or '') == 0:
            return self.filename
        else:
            return self.field.download_filename_format.format(
                file=self) + os.path.splitext(self.filename)[-1]

    def filepath(self):
        return os.path.join(
            secure_filename("{}_{}".format(self.upload.study.id,
                                           self.upload.study.name)),
            secure_filename("{}_{}_{}".format(self.id,
                                              self.upload.study_number,
                                              self.filename)),
        )
Example #30
0
class PseudoRandomId(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    pseudo_random_id_provider_id = db.Column(
        db.Integer, db.ForeignKey(PseudoRandomIdProvider.id))
    pseudo_random_id_provider = db.relationship(PseudoRandomIdProvider)
    ordinal = db.Column(db.Integer, nullable=False)
    unique_code = db.Column(db.Integer, nullable=False)
    check_character = db.Column(db.String(1), nullable=False)
    full_code = db.Column(db.String(20), nullable=False)
    last_updated_datetime = db.Column(db.DateTime,
                                      nullable=False,
                                      default=datetime.utcnow)
    last_updated_by_user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    last_updated_by_user = db.relationship(User)

    @property
    def barcode(self):
        return self.full_code