Esempio n. 1
0
def _get_randomized_form(context, request):
    db_session = request.db_session
    try:
        entity = (db_session.query(datastore.Entity).join(
            datastore.Entity.contexts).filter_by(external='stratum',
                                                 key=context.stratum.id).one())
    except orm.exc.MultipleResultsFound:
        raise Exception('Should only have one...')
    except orm.exc.NoResultFound:
        raise HTTPNotFound()
    else:
        Form = make_form(db_session, entity.schema, show_metadata=False)
        form = Form(data=entity_data(entity))
    return form
Esempio n. 2
0
def _get_randomized_form(context, request):
    db_session = request.db_session
    try:
        entity = (
            db_session.query(datastore.Entity)
            .join(datastore.Entity.contexts)
            .filter_by(external='stratum', key=context.stratum.id)
            .one())
    except orm.exc.MultipleResultsFound:
        raise Exception('Should only have one...')
    except orm.exc.NoResultFound:
        raise HTTPNotFound()
    else:
        Form = make_form(db_session, entity.schema, show_metadata=False)
        form = Form(data=entity_data(entity))
    return form
Esempio n. 3
0
    def test_skip_validation_if_from_complete(self, db_session):
        from webob.multidict import MultiDict
        from occams_datastore import models as datastore
        from occams_forms.renderers import \
            make_form, states, modes, entity_data

        schema = self._make_schema(db_session)
        entity = datastore.Entity(
            schema=schema,
            state=(
                db_session.query(datastore.State)
                .filter_by(name=states.COMPLETE)
                .one()))
        Form = make_form(
            db_session, schema, entity=entity, transition=modes.ALL)
        formdata = MultiDict({
            'ofworkflow_-state': states.PENDING_CORRECTION,
        })
        form = Form(formdata, data=entity_data(entity))
        assert form.validate(), form.errors
Esempio n. 4
0
    def test_skip_validation_if_from_complete(self, db_session):
        from webob.multidict import MultiDict
        from occams_datastore import models as datastore
        from occams_forms.renderers import \
            make_form, states, modes, entity_data

        schema = self._make_schema(db_session)
        entity = datastore.Entity(
            schema=schema,
            state=(
                db_session.query(datastore.State)
                .filter_by(name=states.COMPLETE)
                .one()))
        Form = make_form(
            db_session, schema, entity=entity, transition=modes.ALL)
        formdata = MultiDict({
            'ofworkflow_-state': states.PENDING_CORRECTION,
        })
        form = Form(formdata, data=entity_data(entity))
        assert form.validate(), form.errors
Esempio n. 5
0
def markup_ajax(context, request):
    """
    Returns the HTML markup of a form.

    This usually happens when a user has requested a different version
    of the form that they are trying to enter.
    """
    db_session = request.db_session
    version = request.GET.get('version')
    if not version:
        raise HTTPBadRequest()
    if version == context.schema.publish_date.isoformat():
        data = entity_data(context)
        schema = context.schema
    else:
        schema = (db_session.query(datastore.Schema).filter_by(
            name=context.schema.name, publish_date=version).one())
        data = None
    Form = make_form(db_session, schema, show_metadata=False)
    form = Form(request.POST, data=data)
    return render_form(form)
Esempio n. 6
0
def markup_ajax(context, request):
    """
    Returns the HTML markup of a form.

    This usually happens when a user has requested a different version
    of the form that they are trying to enter.
    """
    db_session = request.db_session
    version = request.GET.get('version')
    if not version:
        raise HTTPBadRequest()
    if version == context.schema.publish_date.isoformat():
        data = entity_data(context)
        schema = context.schema
    else:
        schema = (
            db_session.query(datastore.Schema)
            .filter_by(name=context.schema.name, publish_date=version)
            .one())
        data = None
    Form = make_form(db_session, schema, show_metadata=False)
    form = Form(request.POST, data=data)
    return render_form(form)
Esempio n. 7
0
def form(context, request):
    """
    XXX: Cannot merge into single view
        because of the way patient forms are handled
    """
    db_session = request.db_session

    patient = context.__parent__.__parent__
    schema = context.schema

    (is_phi, ) = (db_session.query(
        db_session.query(models.patient_schema_table).filter_by(
            schema_id=schema.id).exists()).one())

    if not is_phi:
        previous_url = request.current_route_path(
            _route_name='studies.patient_forms')
        show_metadata = True
        # We cannot determine which study this form will be applied to
        # so just use any version from active studies
        available_schemata = (db_session.query(datastore.Schema).join(
            models.study_schema_table).join(models.Study).filter(
                datastore.Schema.name == context.schema.name).filter(
                    datastore.Schema.publish_date != sa.null()).filter(
                        datastore.Schema.retract_date == sa.null()))
        allowed_versions = sorted(
            set(s.publish_date for s in available_schemata))
    else:
        previous_url = request.current_route_path(
            _route_name='studies.patient')
        show_metadata = False
        allowed_versions = None

    if request.has_permission('retract'):
        transition = modes.ALL
    elif request.has_permission('transition'):
        transition = modes.AVAILABLE
    else:
        transition = modes.AUTO

    Form = make_form(
        db_session,
        context.schema,
        entity=context,
        show_metadata=show_metadata,
        transition=transition,
        allowed_versions=allowed_versions,
    )

    form = Form(request.POST, data=entity_data(context))

    if request.method == 'POST':
        if not request.has_permission('edit', context):
            raise HTTPForbidden()
        if form.validate():
            upload_dir = request.registry.settings['studies.blob.dir']
            apply_data(db_session, context, form.data, upload_dir)
            db_session.flush()
            request.session.flash(
                _(u'Changes saved to: %s' % context.schema.title), 'success')
            return HTTPFound(location=previous_url)

    return {
        'phi':
        get_phi_entities(patient, request),
        'patient':
        view_json(patient, request),
        'form':
        render_form(form,
                    disabled=not request.has_permission('edit'),
                    cancel_url=previous_url,
                    attr={
                        'method': 'POST',
                        'action': request.current_route_path(),
                        'role': 'form'
                    }),
    }
Esempio n. 8
0
def terminate_ajax(context, request):
    db_session = request.db_session
    try:
        entity = (
            db_session.query(datastore.Entity)
            .join(datastore.Entity.schema)
            .filter(datastore.Schema.name.in_(
                # Only search for forms being used as temrination forms
                db_session.query(datastore.Schema.name)
                .join(models.Study.termination_schema)
                .subquery()))
            .join(datastore.Context)
            .filter_by(external='enrollment', key=context.id)
            .one())
    except orm.exc.MultipleResultsFound:
        raise Exception('Should only have one...')
    except orm.exc.NoResultFound:
        schema = context.study.termination_schema
        entity = datastore.Entity(schema=schema)
        # XXX: This is really bad form as we're applying
        # side-effects to a GET request, but there is no time
        # to make this look prety...
        # If you remove this line you will be creating random termination
        # entries...
        context.entities.add(entity)
    else:
        schema = entity.schema

    if not entity.state:
        entity.state = (
            db_session.query(datastore.State)
            .filter_by(name='pending-entry')
            .one())

    if 'termination_date' not in schema.attributes:
        msg = 'There is no "termination_date" configured on: {}'
        log.warn(msg.format(schema.name))

    if request.has_permission('retract'):
        transition = modes.ALL
    elif request.has_permission('transition'):
        transition = modes.AVAILABLE
    else:
        transition = modes.AUTO

    Form = make_form(
        db_session, schema,
        entity=entity, transition=transition, show_metadata=False)

    form = Form(request.POST, data=entity_data(entity))

    def validate_termination_date(form, field):
        if not (field.data >= context.latest_consent_date):
            raise wtforms.ValidationError(request.localizer.translate(
                _(u'Termination must be on or after latest consent (${date})'),
                mapping={'date': context.latest_consent_date}
            ))

    # Inject a validator into the termination form so that we
    # ensure that the termination date provided is valid
    form.termination_date.validators.append(validate_termination_date)

    if request.method == 'POST':
        check_csrf_token(request)
        if form.validate():
            if not entity.id:
                # changing termination version *should* not be
                # allowed, just assign the schema that's already being used
                context.entities.add(entity)
            upload_dir = request.registry.settings['studies.blob.dir']
            apply_data(db_session, entity, form.data, upload_dir)
            context.termination_date = form.termination_date.data
            db_session.flush()
            return HTTPOk(json=view_json(context, request))
        else:
            return HTTPBadRequest(json={'errors': wtferrors(form)})

    return render_form(
        form,
        cancel_url=request.current_route_path(_route_name='studies.patient'),
        attr={
            'method': 'POST',
            'action': request.current_route_path(),
            'role': 'form',
            'data-bind': 'formentry: {}, submit: $root.terminateEnrollment'
        }
    )
Esempio n. 9
0
def form(context, request):
    """
    XXX: Cannot merge into single view
        because of the way patient forms are handled
    """
    db_session = request.db_session

    patient = context.__parent__.__parent__
    schema = context.schema

    (is_phi,) = (
        db_session.query(
            db_session.query(models.patient_schema_table)
            .filter_by(schema_id=schema.id)
            .exists())
        .one())

    if not is_phi:
        previous_url = request.current_route_path(
            _route_name='studies.patient_forms')
        show_metadata = True
        # We cannot determine which study this form will be applied to
        # so just use any version from active studies
        available_schemata = (
            db_session.query(datastore.Schema)
            .join(models.study_schema_table)
            .join(models.Study)
            .filter(datastore.Schema.name == context.schema.name)
            .filter(datastore.Schema.publish_date != sa.null())
            .filter(datastore.Schema.retract_date == sa.null()))
        allowed_versions = sorted(set(
            s.publish_date for s in available_schemata))
    else:
        previous_url = request.current_route_path(
            _route_name='studies.patient')
        show_metadata = False
        allowed_versions = None

    if request.has_permission('retract'):
        transition = modes.ALL
    elif request.has_permission('transition'):
        transition = modes.AVAILABLE
    else:
        transition = modes.AUTO

    Form = make_form(
        db_session,
        context.schema,
        entity=context,
        show_metadata=show_metadata,
        transition=transition,
        allowed_versions=allowed_versions,
    )

    form = Form(request.POST, data=entity_data(context))

    if request.method == 'POST':
        if not request.has_permission('edit', context):
            raise HTTPForbidden()
        if form.validate():
            upload_dir = request.registry.settings['studies.blob.dir']
            apply_data(db_session, context, form.data, upload_dir)
            db_session.flush()
            request.session.flash(
                _(u'Changes saved to: %s' % context.schema.title), 'success')
            return HTTPFound(location=previous_url)

    return {
        'phi': get_phi_entities(patient, request),
        'patient': view_json(patient, request),
        'form': render_form(
            form,
            disabled=not request.has_permission('edit'),
            cancel_url=previous_url,
            attr={
                'method': 'POST',
                'action': request.current_route_path(),
                'role': 'form'
            }
        ),
    }
Esempio n. 10
0
def form(context, request):
    """
    XXX: Cannot merge into single view
        because of the way patient forms are handled
    """

    db_session = request.db_session
    visit = context.__parent__.__parent__
    allowed_schemata = (db_session.query(datastore.Schema).join(
        models.study_schema_table).join(models.Study).join(
            models.Cycle).filter(
                datastore.Schema.name == context.schema.name).filter(
                    models.Cycle.id.in_([cycle.id for cycle in visit.cycles])))
    allowed_versions = [s.publish_date for s in allowed_schemata]

    if request.has_permission('retract'):
        transition = modes.ALL
    elif request.has_permission('transition'):
        transition = modes.AVAILABLE
    else:
        transition = modes.AUTO

    Form = make_form(
        db_session,
        context.schema,
        entity=context,
        show_metadata=True,
        transition=transition,
        allowed_versions=allowed_versions,
    )

    form = Form(request.POST, data=entity_data(context))

    if request.method == 'POST':

        if not request.has_permission('edit', context):
            raise HTTPForbidden()

        if form.validate():
            upload_dir = request.registry.settings['studies.blob.dir']
            apply_data(db_session, context, form.data, upload_dir)
            db_session.flush()
            request.session.flash(
                _(u'Changes saved for: ${form}',
                  mapping={'form': context.schema.title}), 'success')
            return HTTPFound(location=request.current_route_path(
                _route_name='studies.visit'))

    return {
        'visit':
        view_json(visit, request),
        'form':
        render_form(
            form,
            disabled=not request.has_permission('edit'),
            cancel_url=request.current_route_path(_route_name='studies.visit'),
            attr={
                'method': 'POST',
                'action': request.current_route_path(),
                'role': 'form'
            }),
    }
Esempio n. 11
0
def terminate_ajax(context, request):
    db_session = request.db_session
    try:
        entity = (
            db_session.query(datastore.Entity).join(
                datastore.Entity.schema).filter(
                    datastore.Schema.name.in_(
                        # Only search for forms being used as temrination forms
                        db_session.query(datastore.Schema.name).join(
                            models.Study.termination_schema
                        ).subquery())).join(datastore.Context).filter_by(
                            external='enrollment', key=context.id).one())
    except orm.exc.MultipleResultsFound:
        raise Exception('Should only have one...')
    except orm.exc.NoResultFound:
        schema = context.study.termination_schema
        entity = datastore.Entity(schema=schema)
        # XXX: This is really bad form as we're applying
        # side-effects to a GET request, but there is no time
        # to make this look prety...
        # If you remove this line you will be creating random termination
        # entries...
        context.entities.add(entity)
        context.patient.entities.add(entity)
    else:
        schema = entity.schema

    if not entity.state:
        entity.state = (db_session.query(
            datastore.State).filter_by(name='pending-entry').one())

    if 'termination_date' not in schema.attributes:
        msg = 'There is no "termination_date" configured on: {}'
        log.warn(msg.format(schema.name))

    if request.has_permission('retract'):
        transition = modes.ALL
    elif request.has_permission('transition'):
        transition = modes.AVAILABLE
    else:
        transition = modes.AUTO

    Form = make_form(db_session,
                     schema,
                     entity=entity,
                     transition=transition,
                     show_metadata=False)

    form = Form(request.POST, data=entity_data(entity))

    def validate_termination_date(form, field):
        if not (field.data >= context.latest_consent_date):
            raise wtforms.ValidationError(
                request.localizer.translate(_(
                    u'Termination must be on or after latest consent (${date})'
                ),
                                            mapping={
                                                'date':
                                                context.latest_consent_date
                                            }))

    # Inject a validator into the termination form so that we
    # ensure that the termination date provided is valid
    form.termination_date.validators.append(validate_termination_date)

    if request.method == 'POST':
        check_csrf_token(request)
        if form.validate():
            if not entity.id:
                # changing termination version *should* not be
                # allowed, just assign the schema that's already being used
                context.entities.add(entity)
            upload_dir = request.registry.settings['studies.blob.dir']
            apply_data(db_session, entity, form.data, upload_dir)
            context.termination_date = form.termination_date.data
            db_session.flush()
            return HTTPOk(json=view_json(context, request))
        else:
            return HTTPBadRequest(json={'errors': wtferrors(form)})

    return render_form(
        form,
        cancel_url=request.current_route_path(_route_name='studies.patient'),
        attr={
            'method': 'POST',
            'action': request.current_route_path(),
            'role': 'form',
            'data-bind': 'formentry: {}, submit: $root.terminateEnrollment'
        })
Esempio n. 12
0
def form(context, request):
    """
    XXX: Cannot merge into single view
        because of the way patient forms are handled
    """

    db_session = request.db_session
    visit = context.__parent__.__parent__
    allowed_schemata = (
        db_session.query(datastore.Schema)
        .join(models.study_schema_table)
        .join(models.Study)
        .join(models.Cycle)
        .filter(models.Cycle.id.in_([cycle.id for cycle in visit.cycles])))
    allowed_versions = [s.publish_date for s in allowed_schemata]

    if request.has_permission('retract'):
        transition = modes.ALL
    elif request.has_permission('transition'):
        transition = modes.AVAILABLE
    else:
        transition = modes.AUTO

    Form = make_form(
        db_session,
        context.schema,
        entity=context,
        show_metadata=True,
        transition=transition,
        allowed_versions=allowed_versions,
    )

    form = Form(request.POST, data=entity_data(context))

    if request.method == 'POST':

        if not request.has_permission('edit', context):
            raise HTTPForbidden()

        if form.validate():
            upload_dir = request.registry.settings['studies.blob.dir']
            apply_data(db_session, context, form.data, upload_dir)
            db_session.flush()
            request.session.flash(
                _(u'Changes saved for: ${form}', mapping={
                    'form': context.schema.title}),
                'success')
            return HTTPFound(location=request.current_route_path(
                _route_name='studies.visit'))

    return {
        'visit': view_json(visit, request),
        'form': render_form(
            form,
            disabled=not request.has_permission('edit'),
            cancel_url=request.current_route_path(_route_name='studies.visit'),
            attr={
                'method': 'POST',
                'action': request.current_route_path(),
                'role': 'form'
            }
        ),
    }