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
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 }
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]}
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
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) }
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}
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] }
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]
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]) }
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]
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]) }
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)
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)