Add short_title to study, change update_study task to use kw arguments and add the short_title to the update_study script
This commit is contained in:
parent
3e0541fa15
commit
06dedd8a32
|
@ -40,6 +40,7 @@ class StudyModel(db.Model):
|
|||
__tablename__ = 'study'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
title = db.Column(db.String)
|
||||
short_title = db.Column(db.String, nullable=True)
|
||||
last_updated = db.Column(db.DateTime(timezone=True), default=func.now())
|
||||
status = db.Column(db.Enum(StudyStatus))
|
||||
irb_status = db.Column(db.Enum(IrbStatus))
|
||||
|
@ -161,7 +162,7 @@ class CategorySchema(ma.Schema):
|
|||
|
||||
class Study(object):
|
||||
|
||||
def __init__(self, title, last_updated, primary_investigator_id, user_uid,
|
||||
def __init__(self, title, short_title, last_updated, primary_investigator_id, user_uid,
|
||||
id=None, status=None, irb_status=None, comment="",
|
||||
sponsor="", hsr_number="", ind_number="", categories=[],
|
||||
files=[], approvals=[], enrollment_date=None, events_history=[],
|
||||
|
@ -172,6 +173,7 @@ class Study(object):
|
|||
self.last_activity_date = last_activity_date
|
||||
self.last_activity_user = last_activity_user
|
||||
self.title = title
|
||||
self.short_title = short_title
|
||||
self.last_updated = last_updated
|
||||
self.status = status
|
||||
self.irb_status = irb_status
|
||||
|
@ -243,6 +245,7 @@ class StudySchema(ma.Schema):
|
|||
protocol_builder_status = EnumField(StudyStatus, by_value=True)
|
||||
status = EnumField(StudyStatus, by_value=True)
|
||||
hsr_number = fields.String(allow_none=True)
|
||||
short_title = fields.String(allow_none=True)
|
||||
sponsor = fields.String(allow_none=True)
|
||||
ind_number = fields.String(allow_none=True)
|
||||
files = fields.List(fields.Nested(FileSchema), dump_only=True)
|
||||
|
@ -251,7 +254,7 @@ class StudySchema(ma.Schema):
|
|||
|
||||
class Meta:
|
||||
model = Study
|
||||
additional = ["id", "title", "last_updated", "primary_investigator_id", "user_uid",
|
||||
additional = ["id", "title", "short_title", "last_updated", "primary_investigator_id", "user_uid",
|
||||
"sponsor", "ind_number", "files", "enrollment_date",
|
||||
"create_user_display", "last_activity_date","last_activity_user",
|
||||
"events_history"]
|
||||
|
|
|
@ -186,6 +186,7 @@ Returns information specific to the protocol.
|
|||
"info": {
|
||||
"id": 12,
|
||||
"title": "test",
|
||||
"short_title": "tst",
|
||||
"primary_investigator_id":21,
|
||||
"user_uid": "dif84",
|
||||
"sponsor": "sponsor",
|
||||
|
|
|
@ -15,44 +15,37 @@ class mock_study:
|
|||
class UpdateStudy(Script):
|
||||
|
||||
argument_error_message = "You must supply at least one argument to the " \
|
||||
"update_study task, in the form [study_field]:[value]",
|
||||
"update_study task, in the form [study_field]=[value]",
|
||||
|
||||
def get_description(self):
|
||||
return """
|
||||
Allows you to set specific attributes on the Study model by mapping them to
|
||||
values in the task data. Should be called with the value to set (either title, or pi)
|
||||
followed by a ":" and then the value to use in dot notation.
|
||||
values in the task data. Should be called with the value to set (either title, short_title, or pi)
|
||||
|
||||
Example:
|
||||
UpdateStudy title:PIComputingID.label pi:PIComputingID.value
|
||||
update_study(title=PIComputingID.label, short_title="Really Short Name")
|
||||
"""
|
||||
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
|
||||
study = mock_study
|
||||
self.__update_study(task, study, *args)
|
||||
self.__update_study(task, study, *args, **kwargs)
|
||||
|
||||
def do_task(self, task, study_id, workflow_id, *args, **kwargs):
|
||||
study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first()
|
||||
self.__update_study(task, study, *args)
|
||||
self.__update_study(task, study, *args, **kwargs)
|
||||
db.session.add(study)
|
||||
|
||||
def __update_study(self, task, study, *args):
|
||||
if len(args) < 1:
|
||||
def __update_study(self, task, study, *args, **kwargs):
|
||||
if len(kwargs.keys()) < 1:
|
||||
raise ApiError.from_task("missing_argument", self.argument_error_message,
|
||||
task=task)
|
||||
|
||||
for arg in args:
|
||||
try:
|
||||
field, value_lookup = arg.split(':')
|
||||
except:
|
||||
raise ApiError.from_task("invalid_argument", self.argument_error_message,
|
||||
task=task)
|
||||
|
||||
value = task.workflow.script_engine.evaluate_expression(task, value_lookup)
|
||||
|
||||
if field.lower() == "title":
|
||||
study.title = value
|
||||
elif field.lower() == "pi":
|
||||
study.primary_investigator_id = value
|
||||
for arg in kwargs.keys():
|
||||
if arg.lower() == "title":
|
||||
study.title = kwargs[arg]
|
||||
elif arg.lower() == "short_title":
|
||||
study.short_title = kwargs[arg]
|
||||
elif arg.lower() == "pi":
|
||||
study.primary_investigator_id = kwargs[arg]
|
||||
else:
|
||||
raise ApiError.from_task("invalid_argument", self.argument_error_message,
|
||||
task=task)
|
||||
|
|
|
@ -36,7 +36,7 @@ class StudyService(object):
|
|||
|
||||
studies = []
|
||||
for study_model in db_studies:
|
||||
studies.append(StudyService.get_study(study_model.id, study_model))
|
||||
studies.append(StudyService.get_study(study_model.id, study_model,do_status=False))
|
||||
return studies
|
||||
|
||||
@staticmethod
|
||||
|
@ -51,7 +51,7 @@ class StudyService(object):
|
|||
return studies
|
||||
|
||||
@staticmethod
|
||||
def get_study(study_id, study_model: StudyModel = None):
|
||||
def get_study(study_id, study_model: StudyModel = None, do_status=True):
|
||||
"""Returns a study model that contains all the workflows organized by category.
|
||||
IMPORTANT: This is intended to be a lightweight call, it should never involve
|
||||
loading up and executing all the workflows in a study to calculate information."""
|
||||
|
@ -81,8 +81,9 @@ class StudyService(object):
|
|||
if study.status != StudyStatus.abandoned:
|
||||
# this line is taking 99% of the time that is used in get_study.
|
||||
# see ticket #196
|
||||
status = StudyService.__get_study_status(study_model)
|
||||
study.warnings = StudyService.__update_status_of_workflow_meta(workflow_metas, status)
|
||||
if do_status:
|
||||
status = StudyService.__get_study_status(study_model)
|
||||
study.warnings = StudyService.__update_status_of_workflow_meta(workflow_metas, status)
|
||||
|
||||
# Group the workflows into their categories.
|
||||
for category in study.categories:
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: f28ee3722c49
|
||||
Revises: cb892916166a
|
||||
Create Date: 2021-03-02 08:30:22.879266
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'f28ee3722c49'
|
||||
down_revision = 'cb892916166a'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('study', sa.Column('short_title', sa.String(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('study', 'short_title')
|
||||
# ### end Alembic commands ###
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0a9entn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.3">
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0a9entn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
||||
<bpmn:process id="Process_1dagb7t" name="TestMessage" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1" name="Start">
|
||||
<bpmn:outgoing>Flow_0xym55y</bpmn:outgoing>
|
||||
|
@ -7,7 +7,7 @@
|
|||
<bpmn:sequenceFlow id="Flow_16q1uec" name="TestMessageFlow" sourceRef="Event_TokenReset" targetRef="Activity_TestMessage" />
|
||||
<bpmn:scriptTask id="Activity_TestMessage" name="Test Message" camunda:resultVariable="test_message">
|
||||
<bpmn:incoming>Flow_16q1uec</bpmn:incoming>
|
||||
<bpmn:script>update_study("title:'New Title'")
|
||||
<bpmn:script>update_study(title='New Title')
|
||||
print('New Title')</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:userTask id="Activity_GetData" name="GetData" camunda:formKey="FirstTaskForm">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0a9entn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0a9entn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
||||
<bpmn:process id="Process_1dagb7t" name="TestMessage" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1" name="Start">
|
||||
<bpmn:outgoing>Flow_0xym55y</bpmn:outgoing>
|
||||
|
@ -7,7 +7,7 @@
|
|||
<bpmn:sequenceFlow id="Flow_16q1uec" name="TestMessageFlow" sourceRef="Event_TokenReset" targetRef="Activity_TestMessage" />
|
||||
<bpmn:scriptTask id="Activity_TestMessage" name="Test Message" camunda:resultVariable="test_message">
|
||||
<bpmn:incoming>Flow_16q1uec</bpmn:incoming>
|
||||
<bpmn:script>update_study("title:'New Title'")
|
||||
<bpmn:script>update_study(title='New Title')
|
||||
print('New Title')</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:sequenceFlow id="Flow_0xym55y" sourceRef="StartEvent_1" targetRef="Activity_Hello" />
|
||||
|
@ -58,7 +58,7 @@ print('New Title')</bpmn:script>
|
|||
<bpmn:scriptTask id="Activity_CancelMessage" name="Cancel Message" camunda:resultVariable="cancel_message">
|
||||
<bpmn:documentation><H1>Cancel Message</H1></bpmn:documentation>
|
||||
<bpmn:incoming>Flow_13xidv2</bpmn:incoming>
|
||||
<bpmn:script>update_study("title:'Second Title'")
|
||||
<bpmn:script>update_study(title='Second Title')
|
||||
print('Second Title')</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
</bpmn:process>
|
||||
|
|
|
@ -2,7 +2,7 @@ from tests.base_test import BaseTest
|
|||
|
||||
from crc.scripts.update_study import UpdateStudy
|
||||
from crc.services.workflow_processor import WorkflowProcessor
|
||||
|
||||
from box import Box
|
||||
|
||||
class TestUpdateStudyScript(BaseTest):
|
||||
|
||||
|
@ -12,12 +12,22 @@ class TestUpdateStudyScript(BaseTest):
|
|||
workflow = self.create_workflow('empty_workflow')
|
||||
processor = WorkflowProcessor(workflow)
|
||||
task = processor.next_task()
|
||||
task.data = {"details": {
|
||||
details = Box({
|
||||
"label": "My New Title",
|
||||
"value": "dhf8r"}
|
||||
}
|
||||
"short": "My New Short Title",
|
||||
"value": "dhf8r"})
|
||||
|
||||
|
||||
script = UpdateStudy()
|
||||
script.do_task(task, workflow.study_id, workflow.id, "title:details.label", "pi:details.value")
|
||||
# note that we changed where the argument gets evaluated
|
||||
# previsously, it took the arguments and then evaluated them within the script
|
||||
# now, it evaluates the arugments in the context of the main script so they get
|
||||
# evaluated before they are passed to the script -
|
||||
# this allows us to do a lot more things like strings, functions, etc.
|
||||
# and it makes the arguments less confusing to use.
|
||||
script.do_task(task, workflow.study_id, workflow.id, title = details.label,
|
||||
short_title = details.short,
|
||||
pi = details.value)
|
||||
self.assertEqual("My New Title", workflow.study.title)
|
||||
self.assertEqual("My New Short Title", workflow.study.short_title)
|
||||
self.assertEqual("dhf8r", workflow.study.primary_investigator_id)
|
||||
|
|
|
@ -26,7 +26,7 @@ class TestMessageEvent(BaseTest):
|
|||
headers=self.logged_in_headers(),
|
||||
content_type="application/json")
|
||||
|
||||
# set_current_task should call the interupt (signal) task
|
||||
# set_current_task should call the interrupt (signal) task
|
||||
# which should run the script in our task
|
||||
#
|
||||
# test to see if our changes made it to the DB
|
||||
|
|
Loading…
Reference in New Issue