2020-07-28 04:39:19 +00:00
|
|
|
import datetime
|
2020-07-31 03:03:11 +00:00
|
|
|
import enum
|
2020-07-28 04:39:19 +00:00
|
|
|
import json
|
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
import marshmallow
|
|
|
|
from marshmallow import INCLUDE, fields
|
2019-12-31 21:32:47 +00:00
|
|
|
from marshmallow_enum import EnumField
|
2020-03-16 17:37:31 +00:00
|
|
|
from sqlalchemy import func
|
2019-12-31 21:32:47 +00:00
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
from crc import db, ma
|
2021-02-09 22:37:55 +00:00
|
|
|
from crc.api.common import ApiErrorSchema, ApiError
|
2020-06-01 01:15:40 +00:00
|
|
|
from crc.models.file import FileModel, SimpleFileSchema, FileSchema
|
2021-09-22 17:16:25 +00:00
|
|
|
from crc.models.ldap import LdapModel, LdapSchema
|
2020-03-26 16:51:53 +00:00
|
|
|
from crc.models.protocol_builder import ProtocolBuilderStatus, ProtocolBuilderStudy
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
from crc.models.workflow import WorkflowSpecCategoryModel, WorkflowState, WorkflowStatus, WorkflowSpecModel, \
|
|
|
|
WorkflowModel
|
2021-02-10 16:58:19 +00:00
|
|
|
from crc.services.file_service import FileService
|
2020-08-12 14:13:23 +00:00
|
|
|
from crc.services.user_service import UserService
|
2019-12-31 21:32:47 +00:00
|
|
|
|
|
|
|
|
2020-07-31 03:03:11 +00:00
|
|
|
class StudyStatus(enum.Enum):
|
2020-07-31 17:19:50 +00:00
|
|
|
in_progress = 'in_progress'
|
2020-07-31 03:03:11 +00:00
|
|
|
hold = 'hold'
|
2020-07-31 17:19:50 +00:00
|
|
|
open_for_enrollment = 'open_for_enrollment'
|
2020-07-31 03:03:11 +00:00
|
|
|
abandoned = 'abandoned'
|
|
|
|
|
|
|
|
|
|
|
|
class IrbStatus(enum.Enum):
|
|
|
|
incomplete_in_protocol_builder = 'incomplete in protocol builder'
|
|
|
|
completed_in_protocol_builder = 'completed in protocol builder'
|
|
|
|
|
|
|
|
|
2020-08-06 02:29:05 +00:00
|
|
|
class StudyEventType(enum.Enum):
|
|
|
|
user = 'user'
|
|
|
|
automatic = 'automatic'
|
|
|
|
|
|
|
|
|
2021-02-24 17:05:06 +00:00
|
|
|
|
2019-12-31 21:32:47 +00:00
|
|
|
class StudyModel(db.Model):
|
|
|
|
__tablename__ = 'study'
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
|
|
title = db.Column(db.String)
|
2021-03-02 15:03:53 +00:00
|
|
|
short_title = db.Column(db.String, nullable=True)
|
2021-05-14 16:28:50 +00:00
|
|
|
last_updated = db.Column(db.DateTime(timezone=True), server_default=func.now())
|
2020-07-31 03:03:11 +00:00
|
|
|
status = db.Column(db.Enum(StudyStatus))
|
|
|
|
irb_status = db.Column(db.Enum(IrbStatus))
|
2020-02-28 16:14:30 +00:00
|
|
|
primary_investigator_id = db.Column(db.String, nullable=True)
|
|
|
|
sponsor = db.Column(db.String, nullable=True)
|
|
|
|
ind_number = db.Column(db.String, nullable=True)
|
|
|
|
user_uid = db.Column(db.String, db.ForeignKey('user.uid'), nullable=False)
|
|
|
|
investigator_uids = db.Column(db.ARRAY(db.String), nullable=True)
|
|
|
|
requirements = db.Column(db.ARRAY(db.Integer), nullable=True)
|
2020-04-21 21:13:30 +00:00
|
|
|
on_hold = db.Column(db.Boolean, default=False)
|
2020-07-22 13:35:08 +00:00
|
|
|
enrollment_date = db.Column(db.DateTime(timezone=True), nullable=True)
|
2021-02-24 17:05:06 +00:00
|
|
|
#events = db.relationship("TaskEventModel")
|
2020-08-12 14:13:23 +00:00
|
|
|
events_history = db.relationship("StudyEvent", cascade="all, delete, delete-orphan")
|
2021-09-17 15:53:45 +00:00
|
|
|
short_name = db.Column(db.String, nullable=True)
|
|
|
|
proposal_name = db.Column(db.String, nullable=True)
|
2020-03-26 16:51:53 +00:00
|
|
|
|
|
|
|
def update_from_protocol_builder(self, pbs: ProtocolBuilderStudy):
|
|
|
|
self.title = pbs.TITLE
|
|
|
|
self.user_uid = pbs.NETBADGEID
|
|
|
|
self.last_updated = pbs.DATE_MODIFIED
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
|
2020-07-31 03:03:11 +00:00
|
|
|
self.irb_status = IrbStatus.incomplete_in_protocol_builder
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
|
|
|
|
|
2021-02-24 17:05:06 +00:00
|
|
|
class StudyAssociated(db.Model):
|
|
|
|
"""
|
|
|
|
This model allows us to associate people with a study, and optionally
|
|
|
|
give them edit access. This allows us to create a table with PI, D_CH, etc.
|
|
|
|
and give access to people other than the study owner.
|
|
|
|
Task_Events will still work as they have previously
|
|
|
|
"""
|
|
|
|
__tablename__ = 'study_associated_user'
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
|
|
study_id = db.Column(db.Integer, db.ForeignKey(StudyModel.id), nullable=False)
|
|
|
|
uid = db.Column(db.String, db.ForeignKey('ldap_model.uid'), nullable=False)
|
|
|
|
role = db.Column(db.String, nullable=True)
|
|
|
|
send_email = db.Column(db.Boolean, nullable=True)
|
|
|
|
access = db.Column(db.Boolean, nullable=True)
|
2021-09-22 17:16:25 +00:00
|
|
|
ldap_info = db.relationship(LdapModel)
|
2021-08-10 20:16:08 +00:00
|
|
|
|
|
|
|
|
2021-03-22 21:30:49 +00:00
|
|
|
class StudyAssociatedSchema(ma.Schema):
|
|
|
|
class Meta:
|
2021-09-22 17:16:25 +00:00
|
|
|
fields=['uid', 'role', 'send_email', 'access', 'ldap_info']
|
2021-03-22 21:30:49 +00:00
|
|
|
model = StudyAssociated
|
|
|
|
unknown = INCLUDE
|
2021-09-22 17:16:25 +00:00
|
|
|
ldap_info = fields.Nested(LdapSchema, dump_only=True)
|
|
|
|
|
|
|
|
|
2021-02-24 17:05:06 +00:00
|
|
|
|
2020-08-06 02:29:05 +00:00
|
|
|
class StudyEvent(db.Model):
|
|
|
|
__tablename__ = 'study_event'
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
|
|
study_id = db.Column(db.Integer, db.ForeignKey(StudyModel.id), nullable=False)
|
2020-08-09 00:25:01 +00:00
|
|
|
study = db.relationship(StudyModel, back_populates='events_history')
|
2021-05-14 16:28:50 +00:00
|
|
|
create_date = db.Column(db.DateTime(timezone=True), server_default=func.now())
|
2020-08-06 02:29:05 +00:00
|
|
|
status = db.Column(db.Enum(StudyStatus))
|
|
|
|
comment = db.Column(db.String, default='')
|
|
|
|
event_type = db.Column(db.Enum(StudyEventType))
|
2020-08-12 14:13:23 +00:00
|
|
|
user_uid = db.Column(db.String, db.ForeignKey('user.uid'), nullable=True)
|
2020-08-06 02:29:05 +00:00
|
|
|
|
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
class WorkflowMetadata(object):
|
2021-10-05 18:17:41 +00:00
|
|
|
def __init__(self, id, display_name = None, description = None, spec_version = None,
|
2020-07-27 21:05:01 +00:00
|
|
|
category_id = None, category_display_name = None, state: WorkflowState = None,
|
|
|
|
status: WorkflowStatus = None, total_tasks = None, completed_tasks = None,
|
2021-10-07 14:02:13 +00:00
|
|
|
is_review=None,display_order = None, state_message = None, workflow_spec_id=None):
|
2020-03-30 18:01:57 +00:00
|
|
|
self.id = id
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.display_name = display_name
|
|
|
|
self.description = description
|
2020-03-30 18:01:57 +00:00
|
|
|
self.spec_version = spec_version
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.category_id = category_id
|
2020-07-21 19:18:08 +00:00
|
|
|
self.category_display_name = category_display_name
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.state = state
|
2021-03-26 23:47:31 +00:00
|
|
|
self.state_message = state_message
|
2020-03-27 18:55:53 +00:00
|
|
|
self.status = status
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.total_tasks = total_tasks
|
|
|
|
self.completed_tasks = completed_tasks
|
2021-02-10 16:58:19 +00:00
|
|
|
self.is_review = is_review
|
2020-04-09 18:25:14 +00:00
|
|
|
self.display_order = display_order
|
2021-10-07 14:02:13 +00:00
|
|
|
self.workflow_spec_id = workflow_spec_id
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
|
2020-03-27 18:55:53 +00:00
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
@classmethod
|
|
|
|
def from_workflow(cls, workflow: WorkflowModel):
|
2021-02-10 16:58:19 +00:00
|
|
|
is_review = FileService.is_workflow_review(workflow.workflow_spec_id)
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
instance = cls(
|
2021-10-06 18:33:09 +00:00
|
|
|
id=workflow.id,
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
display_name=workflow.workflow_spec.display_name,
|
|
|
|
description=workflow.workflow_spec.description,
|
2020-05-29 00:03:50 +00:00
|
|
|
spec_version=workflow.spec_version(),
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
category_id=workflow.workflow_spec.category_id,
|
2020-07-21 19:18:08 +00:00
|
|
|
category_display_name=workflow.workflow_spec.category.display_name,
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
state=WorkflowState.optional,
|
|
|
|
status=workflow.status,
|
|
|
|
total_tasks=workflow.total_tasks,
|
2020-04-09 18:25:14 +00:00
|
|
|
completed_tasks=workflow.completed_tasks,
|
2021-02-10 16:58:19 +00:00
|
|
|
is_review=is_review,
|
2021-10-07 14:02:13 +00:00
|
|
|
display_order=workflow.workflow_spec.display_order,
|
|
|
|
workflow_spec_id=workflow.workflow_spec_id
|
2020-04-09 18:25:14 +00:00
|
|
|
)
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
return instance
|
2020-03-27 18:55:53 +00:00
|
|
|
|
2019-12-31 21:32:47 +00:00
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
class WorkflowMetadataSchema(ma.Schema):
|
|
|
|
state = EnumField(WorkflowState)
|
|
|
|
status = EnumField(WorkflowStatus)
|
2019-12-31 21:32:47 +00:00
|
|
|
class Meta:
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
model = WorkflowMetadata
|
2021-10-05 18:17:41 +00:00
|
|
|
additional = ["id", "display_name", "description",
|
2020-07-21 19:18:08 +00:00
|
|
|
"total_tasks", "completed_tasks", "display_order",
|
2021-03-26 23:47:31 +00:00
|
|
|
"category_id", "is_review", "category_display_name", "state_message"]
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
unknown = INCLUDE
|
|
|
|
|
|
|
|
|
|
|
|
class Category(object):
|
|
|
|
def __init__(self, model: WorkflowSpecCategoryModel):
|
|
|
|
self.id = model.id
|
|
|
|
self.display_name = model.display_name
|
|
|
|
self.display_order = model.display_order
|
2021-09-29 20:53:59 +00:00
|
|
|
self.admin = model.admin
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
class CategorySchema(ma.Schema):
|
|
|
|
workflows = fields.List(fields.Nested(WorkflowMetadataSchema), dump_only=True)
|
|
|
|
class Meta:
|
|
|
|
model = Category
|
2021-10-05 18:17:41 +00:00
|
|
|
additional = ["id", "display_name", "display_order", "admin"]
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
unknown = INCLUDE
|
|
|
|
|
2019-12-31 21:32:47 +00:00
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
class Study(object):
|
|
|
|
|
2021-03-02 15:03:53 +00:00
|
|
|
def __init__(self, title, short_title, last_updated, primary_investigator_id, user_uid,
|
2021-09-17 15:53:45 +00:00
|
|
|
id=None, status=None, irb_status=None, short_name=None, proposal_name=None, comment="",
|
2021-08-16 16:50:09 +00:00
|
|
|
sponsor="", ind_number="", categories=[],
|
2021-02-10 16:58:19 +00:00
|
|
|
files=[], approvals=[], enrollment_date=None, events_history=[],
|
|
|
|
last_activity_user="",last_activity_date =None,create_user_display="", **argsv):
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.id = id
|
|
|
|
self.user_uid = user_uid
|
2021-02-10 16:58:19 +00:00
|
|
|
self.create_user_display = create_user_display
|
|
|
|
self.last_activity_date = last_activity_date
|
|
|
|
self.last_activity_user = last_activity_user
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.title = title
|
2021-03-02 15:03:53 +00:00
|
|
|
self.short_title = short_title
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.last_updated = last_updated
|
2020-07-31 03:03:11 +00:00
|
|
|
self.status = status
|
|
|
|
self.irb_status = irb_status
|
2020-08-06 02:29:05 +00:00
|
|
|
self.comment = comment
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.primary_investigator_id = primary_investigator_id
|
|
|
|
self.sponsor = sponsor
|
|
|
|
self.ind_number = ind_number
|
|
|
|
self.categories = categories
|
2020-06-01 02:46:17 +00:00
|
|
|
self.approvals = approvals
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
self.warnings = []
|
2020-06-01 01:15:40 +00:00
|
|
|
self.files = files
|
2020-07-22 13:35:08 +00:00
|
|
|
self.enrollment_date = enrollment_date
|
2020-08-09 00:25:01 +00:00
|
|
|
self.events_history = events_history
|
2021-09-17 15:53:45 +00:00
|
|
|
self.short_name = short_name
|
|
|
|
self.proposal_name = proposal_name
|
2020-04-22 19:37:02 +00:00
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
@classmethod
|
|
|
|
def from_model(cls, study_model: StudyModel):
|
2021-02-09 22:37:55 +00:00
|
|
|
if study_model is not None and len(study_model.__dict__.items()) > 0:
|
|
|
|
args = dict((k, v) for k, v in study_model.__dict__.items() if not k.startswith('_'))
|
|
|
|
args['events_history'] = study_model.events_history # For some reason this attribute is not picked up
|
|
|
|
instance = cls(**args)
|
|
|
|
return instance
|
|
|
|
else:
|
|
|
|
raise ApiError(code='empty_study_model',
|
|
|
|
message='There was a problem retrieving your study. StudyModel is empty.')
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
|
|
|
|
def model_args(self):
|
|
|
|
"""Arguments that can be passed into the Study Model to update it."""
|
|
|
|
self_dict = self.__dict__.copy()
|
|
|
|
del self_dict["categories"]
|
|
|
|
del self_dict["warnings"]
|
|
|
|
return self_dict
|
|
|
|
|
|
|
|
|
2020-07-28 04:39:19 +00:00
|
|
|
class StudyForUpdateSchema(ma.Schema):
|
|
|
|
|
|
|
|
id = fields.Integer(required=False, allow_none=True)
|
2020-07-31 03:03:11 +00:00
|
|
|
status = EnumField(StudyStatus, by_value=True)
|
2020-07-28 04:39:19 +00:00
|
|
|
sponsor = fields.String(allow_none=True)
|
|
|
|
ind_number = fields.String(allow_none=True)
|
|
|
|
enrollment_date = fields.DateTime(allow_none=True)
|
|
|
|
comment = fields.String(allow_none=True)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
model = Study
|
|
|
|
unknown = INCLUDE
|
|
|
|
|
|
|
|
@marshmallow.post_load
|
|
|
|
def make_study(self, data, **kwargs):
|
|
|
|
"""Can load the basic study data for updates to the database, but categories are write only"""
|
|
|
|
return Study(**data)
|
|
|
|
|
|
|
|
|
2020-08-09 00:25:01 +00:00
|
|
|
class StudyEventSchema(ma.Schema):
|
|
|
|
|
|
|
|
id = fields.Integer(required=False)
|
|
|
|
create_date = fields.DateTime()
|
|
|
|
status = EnumField(StudyStatus, by_value=True)
|
|
|
|
comment = fields.String(allow_none=True)
|
|
|
|
event_type = EnumField(StudyEvent, by_value=True)
|
|
|
|
|
|
|
|
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
class StudySchema(ma.Schema):
|
|
|
|
|
2020-05-25 16:29:05 +00:00
|
|
|
id = fields.Integer(required=False, allow_none=True)
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
categories = fields.List(fields.Nested(CategorySchema), dump_only=True)
|
|
|
|
warnings = fields.List(fields.Nested(ApiErrorSchema), dump_only=True)
|
2020-07-31 03:03:11 +00:00
|
|
|
protocol_builder_status = EnumField(StudyStatus, by_value=True)
|
|
|
|
status = EnumField(StudyStatus, by_value=True)
|
2021-03-02 15:03:53 +00:00
|
|
|
short_title = fields.String(allow_none=True)
|
2020-05-25 16:29:05 +00:00
|
|
|
sponsor = fields.String(allow_none=True)
|
|
|
|
ind_number = fields.String(allow_none=True)
|
2020-06-01 04:00:52 +00:00
|
|
|
files = fields.List(fields.Nested(FileSchema), dump_only=True)
|
2020-07-22 13:35:08 +00:00
|
|
|
enrollment_date = fields.Date(allow_none=True)
|
2020-08-09 00:25:01 +00:00
|
|
|
events_history = fields.List(fields.Nested('StudyEventSchema'), dump_only=True)
|
2021-09-17 15:53:45 +00:00
|
|
|
short_name = fields.String(allow_none=True)
|
|
|
|
proposal_name = fields.String(allow_none=True)
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
model = Study
|
2021-03-02 15:03:53 +00:00
|
|
|
additional = ["id", "title", "short_title", "last_updated", "primary_investigator_id", "user_uid",
|
2021-02-16 14:05:29 +00:00
|
|
|
"sponsor", "ind_number", "files", "enrollment_date",
|
2021-09-17 15:53:45 +00:00
|
|
|
"create_user_display", "last_activity_date", "last_activity_user",
|
|
|
|
"events_history", "short_name", "proposal_name"]
|
Created a "StudyService" and moved all complex logic around study manipulation out of the study api, and this service, as things were getting complicated. The Workflow Processor no longer creates the WorkflowModel, the study object handles that, and only passes the model into the workflow processor when it is ready to start the workflow.
Created a Study object (seperate from the StudyModel) that can cronstructed on request, and contains a different data structure than we store in the DB. This allows us to return underlying Categories and Workflows in a clean way.
Added a new status to workflows called "not_started", meaning we have not yet instantiated a processor or created a BPMN, they have no version yet and no stored data, just the possiblity of being started.
The Top Level Workflow or "Master" workflow is now a part of the sample data, and loaded at all times.
Removed the ability to "add a workflow to a study" and "remove a workflow from a study", a study contains all possible workflows by definition.
Example data no longer creates users or studies, it just creates the specs.
2020-03-30 12:00:16 +00:00
|
|
|
unknown = INCLUDE
|
|
|
|
|
|
|
|
@marshmallow.post_load
|
|
|
|
def make_study(self, data, **kwargs):
|
|
|
|
"""Can load the basic study data for updates to the database, but categories are write only"""
|
2020-04-09 18:25:14 +00:00
|
|
|
return Study(**data)
|
2020-05-20 21:10:22 +00:00
|
|
|
|