Exemplo n.º 1
0
def view_json(context, request, deep=True):
    study = context
    data = {
        '__url__': request.route_path('studies.study', study=study.name),
        'id': study.id,
        'name': study.name,
        'title': study.title,
        'code': study.code,
        'short_title': study.short_title,
        'consent_date': study.consent_date.isoformat(),
        'reference_pattern': study.reference_pattern,
        'reference_hint': study.reference_hint,
        'is_randomized': study.is_randomized,
        'is_blinded': study.is_blinded,
        'termination_form':
            study.termination_schema
            and form2json(study.termination_schema),
        'randomization_form':
            study.randomization_schema
            and form2json(study.randomization_schema),
        }

    if deep:
        data.update({
            'cycles': [
                cycle_views.view_json(cycle, request)
                for cycle in study.cycles],
            'forms': form2json(study.schemata)})

    return data
Exemplo n.º 2
0
def available_schemata(context, request):
    """
    Returns a list of available schemata for the given context

    Criteria for available schemata:
        * Must be configured for a study (i.e NOT patient/enrollment forms)
        * Must NOT be retracted

    GET parameters:
        schema -- (optional) only shows results for specific schema name
                  (useful for searching for a schema's publish dates)
        term -- (optional) filters by schema title or publish date
        grouped -- (optional) groups all results by schema name

    """
    db_session = request.db_session

    class SearchForm(Form):
        term = wtforms.StringField()
        schema = wtforms.StringField()
        grouped = wtforms.BooleanField()

    form = SearchForm(request.GET)
    form.validate()

    query = (
        db_session.query(datastore.Schema)
        # only allow forms that are available to active studies
        .join(models.study_schema_table)
        .join(models.Study)
        .filter(datastore.Schema.retract_date == sa.null()))

    if form.schema.data:
        query = query.filter(datastore.Schema.name == form.schema.data)

    if form.term.data:
        wildcard = u'%' + form.term.data + u'%'
        query = query.filter(
            datastore.Schema.title.ilike(wildcard)
            | sa.cast(datastore.Schema.publish_date,
                      sa.Unicode).ilike(wildcard))

    query = (
        query.order_by(
            datastore.Schema.title,
            datastore.Schema.publish_date.asc())
        .limit(100))

    if form.grouped.data:
        schemata = form2json(query)
    else:
        schemata = [version2json(i) for i in query]

    return {
        '__query__': form.data,
        'schemata': schemata
    }
Exemplo n.º 3
0
def forms_list_json(context, request):
    """
    Returns a listing of available patient forms
    """
    db_session = request.db_session
    query = (db_session.query(datastore.Schema).join(
        models.patient_schema_table).order_by(datastore.Schema.name,
                                              datastore.Schema.publish_date))

    return {'forms': [form2json(s) for s in query]}
Exemplo n.º 4
0
def view_json(context, request, deep=True):
    study = context
    data = {
        '__url__':
        request.route_path('studies.study', study=study.name),
        'id':
        study.id,
        'name':
        study.name,
        'title':
        study.title,
        'code':
        study.code,
        'short_title':
        study.short_title,
        'consent_date':
        study.consent_date.isoformat(),
        'reference_pattern':
        study.reference_pattern,
        'reference_hint':
        study.reference_hint,
        'is_randomized':
        study.is_randomized,
        'is_blinded':
        study.is_blinded,
        'termination_form':
        study.termination_schema and form2json(study.termination_schema),
        'randomization_form':
        study.randomization_schema and form2json(study.randomization_schema),
    }

    if deep:
        data.update({
            'cycles':
            [cycle_views.view_json(cycle, request) for cycle in study.cycles],
            'forms':
            form2json(study.schemata)
        })

    return data
Exemplo n.º 5
0
def view_json(context, request):
    cycle = context
    return {
        '__url__': request.route_path('studies.cycle',
                                      study=cycle.study.name,
                                      cycle=cycle.name),
        'id': cycle.id,
        'name': cycle.name,
        'title': cycle.title,
        'week': cycle.week,
        'is_interim': cycle.is_interim,
        'forms': form2json(cycle.schemata)
        }
Exemplo n.º 6
0
def available_schemata(context, request):
    """
    Returns a list of available schemata for the given context

    Criteria for available schemata:
        * Must be configured for a study (i.e NOT patient/enrollment forms)
        * Must NOT be retracted

    GET parameters:
        schema -- (optional) only shows results for specific schema name
                  (useful for searching for a schema's publish dates)
        term -- (optional) filters by schema title or publish date
        grouped -- (optional) groups all results by schema name

    """
    db_session = request.db_session

    class SearchForm(Form):
        term = wtforms.StringField()
        schema = wtforms.StringField()
        grouped = wtforms.BooleanField()

    form = SearchForm(request.GET)
    form.validate()

    query = (
        db_session.query(datastore.Schema)
        # only allow forms that are available to active studies
        .join(models.study_schema_table).join(
            models.Study).filter(datastore.Schema.retract_date == sa.null()))

    if form.schema.data:
        query = query.filter(datastore.Schema.name == form.schema.data)

    if form.term.data:
        wildcard = u'%' + form.term.data + u'%'
        query = query.filter(
            datastore.Schema.title.ilike(wildcard)
            | sa.cast(datastore.Schema.publish_date, sa.Unicode).ilike(
                wildcard))

    query = (query.order_by(datastore.Schema.title,
                            datastore.Schema.publish_date.asc()).limit(100))

    if form.grouped.data:
        schemata = form2json(query)
    else:
        schemata = [version2json(i) for i in query]

    return {'__query__': form.data, 'schemata': schemata}
Exemplo n.º 7
0
def forms_list_json(context, request):
    """
    Returns a listing of available patient forms
    """
    db_session = request.db_session
    query = (
        db_session.query(datastore.Schema)
        .join(models.patient_schema_table)
        .order_by(
            datastore.Schema.name,
            datastore.Schema.publish_date))

    return {
        'forms': [form2json(s) for s in query]
    }
Exemplo n.º 8
0
def add_schema_json(context, request):
    check_csrf_token(request)
    db_session = request.db_session

    def check_not_patient_schema(form, field):
        (exists, ) = (db_session.query(
            db_session.query(datastore.Schema).join(
                models.patient_schema_table).filter(
                    datastore.Schema.name == field.data).exists()).one())
        if exists:
            raise wtforms.ValidationError(
                request.localizer.translate(_(u'Already a patient form')))

    def check_not_randomization_schema(form, field):
        if (context.randomization_schema
                and context.randomization_schema.name == field.data):
            raise wtforms.ValidationError(
                request.localizer.translate(
                    _(u'Already a randomization form')))

    def check_not_termination_schema(form, field):
        if (context.termination_schema is not None
                and context.termination_schema.name == field.data):
            raise wtforms.ValidationError(
                request.localizer.translate(_(u'Already a termination form')))

    def check_same_schema(form, field):
        versions = form.versions.data
        schema = form.schema.data
        invalid = [i.publish_date for i in versions if i.name != schema]
        if invalid:
            raise wtforms.ValidationError(
                request.localizer.translate(
                    _(_(u'Incorrect versions: ${versions}'),
                      mapping={'versions': ', '.join(map(str, invalid))})))

    def check_published(form, field):
        if field.data.publish_date is None:
            raise wtforms.ValidationError(
                request.localizer.translate(
                    _(u'Selected version is not published')))

    class SchemaManagementForm(Form):
        schema = wtforms.StringField(validators=[
            wtforms.validators.InputRequired(), check_not_patient_schema,
            check_not_randomization_schema, check_not_termination_schema
        ])
        versions = wtforms.FieldList(
            ModelField(db_session=db_session,
                       class_=datastore.Schema,
                       validators=[
                           wtforms.validators.InputRequired(), check_published
                       ]),
            validators=[wtforms.validators.DataRequired(), check_same_schema])

    form = SchemaManagementForm.from_json(request.json_body)

    if not form.validate():
        raise HTTPBadRequest(json={'errors': wtferrors(form)})

    old_items = set(i for i in context.schemata if i.name == form.schema.data)
    new_items = set(form.versions.data)

    # Remove unselected
    context.schemata.difference_update(old_items - new_items)

    # Add newly selected
    context.schemata.update(new_items)

    # Get a list of cycles to update
    cycles = (db_session.query(models.Cycle).options(
        orm.joinedload(models.Cycle.schemata)).filter(
            models.Cycle.study == context).filter(
                models.Cycle.schemata.any(name=form.schema.data)))

    # Also update available cycle schemata versions
    for cycle in cycles:
        cycle.schemata.difference_update(old_items - new_items)
        cycle.schemata.update(new_items)

    return form2json(new_items)[0]
Exemplo n.º 9
0
def available_schemata(context, request):
    """
    Returns a listing of available schemata for the study

    The results will try to exclude schemata configured for patients,
    or schemata that is currently used by the context study (if editing).

    GET parameters:
        term -- (optional) filters by schema title or publish date
        schema -- (optional) only shows results for specific schema name
                  (useful for searching for a schema's publish dates)
        grouped -- (optional) groups all results by schema name
    """
    db_session = request.db_session

    class SearchForm(Form):
        term = wtforms.StringField()
        schema = wtforms.StringField()
        grouped = wtforms.BooleanField()

    form = SearchForm(request.GET)
    form.validate()

    query = (
        db_session.query(datastore.Schema).filter(
            datastore.Schema.publish_date != sa.null()).filter(
                datastore.Schema.retract_date == sa.null()).filter(
                    ~datastore.Schema.name.in_(
                        # Exclude patient schemata
                        db_session.query(datastore.Schema.name).join(
                            models.patient_schema_table).subquery())))

    if form.schema.data:
        query = query.filter(datastore.Schema.name == form.schema.data)

    if form.term.data:
        wildcard = u'%' + form.term.data + u'%'
        query = query.filter(
            datastore.Schema.title.ilike(wildcard)
            | sa.cast(datastore.Schema.publish_date, sa.Unicode).ilike(
                wildcard))

    if isinstance(context, models.Study):

        # Filter out schemata that is already in use by the study

        if context.randomization_schema:
            query = query.filter(
                datastore.Schema.name != context.randomization_schema.name)

        if context.termination_schema:
            query = query.filter(
                datastore.Schema.name != context.termination_schema.name)

        query = query.filter(~datastore.Schema.id.in_(
            db_session.query(datastore.Schema.id).select_from(
                models.Study).filter(models.Study.id == context.id).join(
                    models.Study.schemata).subquery()))

    query = (query.order_by(datastore.Schema.title,
                            datastore.Schema.publish_date.asc()).limit(100))

    return {
        '__query__':
        form.data,
        'schemata': (form2json(query) if form.grouped.data else
                     [version2json(i) for i in query])
    }
Exemplo n.º 10
0
def add_schema_json(context, request):
    check_csrf_token(request)
    db_session = request.db_session

    def check_not_patient_schema(form, field):
        (exists,) = (
            db_session.query(
                db_session.query(datastore.Schema)
                .join(models.patient_schema_table)
                .filter(datastore.Schema.name == field.data)
                .exists())
            .one())
        if exists:
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'Already a patient form')))

    def check_not_randomization_schema(form, field):
        if (context.randomization_schema
                and context.randomization_schema.name == field.data):
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'Already a randomization form')))

    def check_not_termination_schema(form, field):
        if (context.termination_schema is not None
                and context.termination_schema.name == field.data):
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'Already a termination form')))

    def check_same_schema(form, field):
        versions = form.versions.data
        schema = form.schema.data
        invalid = [i.publish_date for i in versions if i.name != schema]
        if invalid:
            raise wtforms.ValidationError(request.localizer.translate(_(
                _(u'Incorrect versions: ${versions}'),
                mapping={'versions': ', '.join(map(str, invalid))})))

    def check_published(form, field):
        if field.data.publish_date is None:
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'Selected version is not published')))

    class SchemaManagementForm(Form):
        schema = wtforms.StringField(
            validators=[
                wtforms.validators.InputRequired(),
                check_not_patient_schema,
                check_not_randomization_schema,
                check_not_termination_schema])
        versions = wtforms.FieldList(
            ModelField(
                db_session=db_session,
                class_=datastore.Schema,
                validators=[
                    wtforms.validators.InputRequired(),
                    check_published]),
            validators=[
                wtforms.validators.DataRequired(),
                check_same_schema])

    form = SchemaManagementForm.from_json(request.json_body)

    if not form.validate():
        raise HTTPBadRequest(json={'errors': wtferrors(form)})

    old_items = set(i for i in context.schemata if i.name == form.schema.data)
    new_items = set(form.versions.data)

    # Remove unselected
    context.schemata.difference_update(old_items - new_items)

    # Add newly selected
    context.schemata.update(new_items)

    # Get a list of cycles to update
    cycles = (
        db_session.query(models.Cycle)
        .options(orm.joinedload(models.Cycle.schemata))
        .filter(models.Cycle.study == context)
        .filter(models.Cycle.schemata.any(name=form.schema.data)))

    # Also update available cycle schemata versions
    for cycle in cycles:
        cycle.schemata.difference_update(old_items - new_items)
        cycle.schemata.update(new_items)

    return form2json(new_items)[0]
Exemplo n.º 11
0
def available_schemata(context, request):
    """
    Returns a listing of available schemata for the study

    The results will try to exclude schemata configured for patients,
    or schemata that is currently used by the context study (if editing).

    GET parameters:
        term -- (optional) filters by schema title or publish date
        schema -- (optional) only shows results for specific schema name
                  (useful for searching for a schema's publish dates)
        grouped -- (optional) groups all results by schema name
    """
    db_session = request.db_session

    class SearchForm(Form):
        term = wtforms.StringField()
        schema = wtforms.StringField()
        grouped = wtforms.BooleanField()

    form = SearchForm(request.GET)
    form.validate()

    query = (
        db_session.query(datastore.Schema)
        .filter(datastore.Schema.publish_date != sa.null())
        .filter(datastore.Schema.retract_date == sa.null())
        .filter(~datastore.Schema.name.in_(
            # Exclude patient schemata
            db_session.query(datastore.Schema.name)
            .join(models.patient_schema_table)
            .subquery())))

    if form.schema.data:
        query = query.filter(datastore.Schema.name == form.schema.data)

    if form.term.data:
        wildcard = u'%' + form.term.data + u'%'
        query = query.filter(
            datastore.Schema.title.ilike(wildcard)
            | sa.cast(datastore.Schema.publish_date,
                      sa.Unicode).ilike(wildcard))

    if isinstance(context, models.Study):

        # Filter out schemata that is already in use by the study

        if context.randomization_schema:
            query = query.filter(
                datastore.Schema.name != context.randomization_schema.name)

        if context.termination_schema:
            query = query.filter(
                datastore.Schema.name != context.termination_schema.name)

        query = query.filter(~datastore.Schema.id.in_(
            db_session.query(datastore.Schema.id)
            .select_from(models.Study)
            .filter(models.Study.id == context.id)
            .join(models.Study.schemata)
            .subquery()))

    query = (
        query.order_by(
            datastore.Schema.title,
            datastore.Schema.publish_date.asc())
        .limit(100))

    return {
        '__query__': form.data,
        'schemata': (form2json(query)
                     if form.grouped.data
                     else [version2json(i) for i in query])
    }
Exemplo n.º 12
0
def forms_add_json(context, request):
    """
    Updates the available patient forms
    """
    check_csrf_token(request)
    db_session = request.db_session

    def check_not_study_form(form, field):
        studies = (db_session.query(models.Study).filter(
            models.Study.schemata.any(id=field.data.id)).order_by(
                models.Study.title).all())
        if studies:
            raise wtforms.ValidationError(
                request.localizer.translate(
                    _(u'This form is already used by: {studies}'),
                    mapping={'studies': ', '.join(s.title for s in studies)}))

    def check_not_termination_form(form, field):
        studies = (db_session.query(models.Study).filter(
            models.Study.termination_schema.has(
                name=field.data.name)).order_by(models.Study.title).all())
        if studies:
            raise wtforms.ValidationError(
                request.localizer.translate(_(
                    u'This form is already a termination form for: {studies}'),
                                            mapping={
                                                'studies':
                                                ', '.join(s.title
                                                          for s in studies)
                                            }))

    def check_not_randomization_form(form, field):
        studies = (db_session.query(models.Study).filter(
            models.Study.randomization_schema.has(
                name=field.data.name)).order_by(models.Study.title).all())
        if studies:
            raise wtforms.ValidationError(
                request.localizer.translate(_(
                    u'This form is already a randomization form for: {studies}'
                ),
                                            mapping={
                                                'studies':
                                                ', '.join(s.title
                                                          for s in studies)
                                            }))

    def check_unique_form(form, field):
        exists = (db_session.query(sa.literal(True)).filter(
            db_session.query(datastore.Schema).join(
                models.patient_schema_table).filter(
                    datastore.Schema.name ==
                    field.data.name).exists()).scalar())
        if exists:
            raise wtforms.ValidationError(
                request.localizer.translate(
                    _(u'Only a single version of forms are currently supported'
                      )))

    class AddForm(Form):
        form = ModelField(db_session=db_session,
                          class_=datastore.Schema,
                          validators=[
                              wtforms.validators.InputRequired(),
                              check_not_study_form,
                              check_not_randomization_form,
                              check_not_termination_form, check_unique_form
                          ])

    form = AddForm.from_json(request.json_body)

    if not form.validate():
        raise HTTPBadRequest(json={'errors': wtferrors(form)})

    db_session.execute(models.patient_schema_table.insert().values(
        schema_id=form.form.data.id))

    mark_changed(db_session)

    return form2json(form.form.data)
Exemplo n.º 13
0
def forms_add_json(context, request):
    """
    Updates the available patient forms
    """
    check_csrf_token(request)
    db_session = request.db_session

    def check_not_study_form(form, field):
        studies = (
            db_session.query(models.Study)
            .filter(models.Study.schemata.any(id=field.data.id))
            .order_by(models.Study.title)
            .all())
        if studies:
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'This form is already used by: {studies}'),
                mapping={'studies': ', '.join(s.title for s in studies)}))

    def check_not_termination_form(form, field):
        studies = (
            db_session.query(models.Study)
            .filter(models.Study.termination_schema.has(name=field.data.name))
            .order_by(models.Study.title)
            .all())
        if studies:
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'This form is already a termination form for: {studies}'),
                mapping={'studies': ', '.join(s.title for s in studies)}))

    def check_not_randomization_form(form, field):
        studies = (
            db_session.query(models.Study)
            .filter(models.Study.randomization_schema.has(
                name=field.data.name))
            .order_by(models.Study.title)
            .all())
        if studies:
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'This form is already a randomization form for: {studies}'),
                mapping={'studies': ', '.join(s.title for s in studies)}))

    def check_unique_form(form, field):
        exists = (
            db_session.query(sa.literal(True))
            .filter(
                db_session.query(datastore.Schema)
                .join(models.patient_schema_table)
                .filter(datastore.Schema.name == field.data.name)
                .exists())
            .scalar())
        if exists:
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'Only a single version of forms are currently supported')))

    class AddForm(Form):
        form = ModelField(
            db_session=db_session,
            class_=datastore.Schema,
            validators=[
                wtforms.validators.InputRequired(),
                check_not_study_form,
                check_not_randomization_form,
                check_not_termination_form,
                check_unique_form])

    form = AddForm.from_json(request.json_body)

    if not form.validate():
        raise HTTPBadRequest(json={'errors': wtferrors(form)})

    db_session.execute(
        models.patient_schema_table.insert()
        .values(schema_id=form.form.data.id))

    mark_changed(db_session)

    return form2json(form.form.data)