Refactoring shared code
This commit is contained in:
parent
e5541e4950
commit
dc5ffd29d0
|
@ -90,8 +90,8 @@ def get_approvals_for_study(study_id=None):
|
|||
return results
|
||||
|
||||
|
||||
def get_health_attesting_csv(all_approvals=True):
|
||||
records = ApprovalService.get_health_attesting_records(all_approvals)
|
||||
def get_health_attesting_csv():
|
||||
records = ApprovalService.get_health_attesting_records()
|
||||
si = io.StringIO()
|
||||
cw = csv.writer(si)
|
||||
cw.writerows(records)
|
||||
|
@ -105,67 +105,10 @@ def get_health_attesting_csv(all_approvals=True):
|
|||
def get_csv():
|
||||
"""A damn lie, it's a json file. A huge bit of a one-off for RRT, but 3 weeks of midnight work can convince a
|
||||
man to do just about anything"""
|
||||
approvals = ApprovalService.get_all_approvals(include_cancelled=False)
|
||||
output = []
|
||||
errors = []
|
||||
for approval in approvals:
|
||||
try:
|
||||
if approval.status != ApprovalStatus.APPROVED.value:
|
||||
continue
|
||||
for related_approval in approval.related_approvals:
|
||||
if related_approval.status != ApprovalStatus.APPROVED.value:
|
||||
continue
|
||||
workflow = db.session.query(WorkflowModel).filter(WorkflowModel.id == approval.workflow_id).first()
|
||||
data = json.loads(workflow.bpmn_workflow_json)
|
||||
last_task = find_task(data['last_task']['__uuid__'], data['task_tree'])
|
||||
personnel = extract_value(last_task, 'personnel')
|
||||
training_val = extract_value(last_task, 'RequiredTraining')
|
||||
pi_supervisor = extract_value(last_task, 'PISupervisor')['value']
|
||||
review_complete = 'AllRequiredTraining' in training_val
|
||||
pi_uid = workflow.study.primary_investigator_id
|
||||
pi_details = LdapService.user_info(pi_uid)
|
||||
details = []
|
||||
details.append(pi_details)
|
||||
for person in personnel:
|
||||
uid = person['PersonnelComputingID']['value']
|
||||
details.append(LdapService.user_info(uid))
|
||||
content = ApprovalService.get_not_really_csv_content()
|
||||
|
||||
for person in details:
|
||||
record = {
|
||||
"study_id": approval.study_id,
|
||||
"pi_uid": pi_details.uid,
|
||||
"pi": pi_details.display_name,
|
||||
"name": person.display_name,
|
||||
"uid": person.uid,
|
||||
"email": person.email_address,
|
||||
"supervisor": "",
|
||||
"review_complete": review_complete,
|
||||
}
|
||||
# We only know the PI's supervisor.
|
||||
if person.uid == pi_details.uid:
|
||||
record["supervisor"] = pi_supervisor
|
||||
return content
|
||||
|
||||
output.append(record)
|
||||
|
||||
except Exception as e:
|
||||
errors.append("Error pulling data for workflow #%i: %s" % (approval.workflow_id, str(e)))
|
||||
return {"results": output, "errors": errors }
|
||||
|
||||
|
||||
def extract_value(task, key):
|
||||
if key in task['data']:
|
||||
return pickle.loads(b64decode(task['data'][key]['__bytes__']))
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def find_task(uuid, task):
|
||||
if task['id']['__uuid__'] == uuid:
|
||||
return task
|
||||
for child in task['children']:
|
||||
task = find_task(uuid, child)
|
||||
if task:
|
||||
return task
|
||||
# ----- come back to the world of the living ---- #
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import json
|
||||
import pickle
|
||||
from base64 import b64decode
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from sqlalchemy import desc, func
|
||||
|
@ -110,19 +113,51 @@ class ApprovalService(object):
|
|||
return [Approval.from_model(approval_model) for approval_model in db_approvals]
|
||||
|
||||
@staticmethod
|
||||
def get_health_attesting_records(all_approvals=True):
|
||||
"""Return a list with prepared information related to all approvals
|
||||
approved or filtered by today """
|
||||
if all_approvals:
|
||||
approvals = session.query(ApprovalModel).filter(
|
||||
ApprovalModel.status==ApprovalStatus.APPROVED.value
|
||||
)
|
||||
else:
|
||||
today = datetime.now().date()
|
||||
approvals = session.query(ApprovalModel).filter(
|
||||
func.date(ApprovalModel.date_created)==today,
|
||||
ApprovalModel.status==ApprovalStatus.APPROVED.value
|
||||
)
|
||||
def get_approval_details(approval):
|
||||
"""Returns a list of packed approval details, obtained from
|
||||
the task data sent during the workflow """
|
||||
def extract_value(task, key):
|
||||
if key in task['data']:
|
||||
return pickle.loads(b64decode(task['data'][key]['__bytes__']))
|
||||
else:
|
||||
return ""
|
||||
|
||||
def find_task(uuid, task):
|
||||
if task['id']['__uuid__'] == uuid:
|
||||
return task
|
||||
for child in task['children']:
|
||||
task = find_task(uuid, child)
|
||||
if task:
|
||||
return task
|
||||
|
||||
if approval.status != ApprovalStatus.APPROVED.value:
|
||||
return {}
|
||||
for related_approval in approval.related_approvals:
|
||||
if related_approval.status != ApprovalStatus.APPROVED.value:
|
||||
continue
|
||||
workflow = db.session.query(WorkflowModel).filter(WorkflowModel.id == approval.workflow_id).first()
|
||||
data = json.loads(workflow.bpmn_workflow_json)
|
||||
last_task = find_task(data['last_task']['__uuid__'], data['task_tree'])
|
||||
personnel = extract_value(last_task, 'personnel')
|
||||
training_val = extract_value(last_task, 'RequiredTraining')
|
||||
pi_supervisor = extract_value(last_task, 'PISupervisor')['value']
|
||||
review_complete = 'AllRequiredTraining' in training_val
|
||||
pi_uid = workflow.study.primary_investigator_id
|
||||
pi_details = LdapService.user_info(pi_uid)
|
||||
details = {'Supervisor': pi_supervisor}
|
||||
details['person_details'] = []
|
||||
details['person_details'].append(pi_details)
|
||||
for person in personnel:
|
||||
uid = person['PersonnelComputingID']['value']
|
||||
details['person_details'].append(LdapService.user_info(uid))
|
||||
|
||||
return details
|
||||
|
||||
@staticmethod
|
||||
def get_health_attesting_records():
|
||||
"""Return a list with prepared information related to all approvals """
|
||||
|
||||
approvals = ApprovalService.get_all_approvals(include_cancelled=False)
|
||||
|
||||
health_attesting_rows = [
|
||||
['university_computing_id',
|
||||
|
@ -132,22 +167,60 @@ class ApprovalService(object):
|
|||
'job_title',
|
||||
'supervisor_university_computing_id']
|
||||
]
|
||||
|
||||
for approval in approvals:
|
||||
pi_info = LdapService.user_info(approval.study.primary_investigator_id)
|
||||
approver_info = LdapService.user_info(approval.approver_uid)
|
||||
first_name = pi_info.given_name
|
||||
last_name = pi_info.display_name.replace(first_name, '').strip()
|
||||
health_attesting_rows.append([
|
||||
pi_info.uid,
|
||||
last_name,
|
||||
first_name,
|
||||
'',
|
||||
'Academic Researcher',
|
||||
approver_info.uid
|
||||
])
|
||||
try:
|
||||
details = ApprovalService.get_approval_details(approval)
|
||||
if not details:
|
||||
continue
|
||||
|
||||
for person in details['person_details']:
|
||||
first_name = person.given_name
|
||||
last_name = person.display_name.replace(first_name, '').strip()
|
||||
record = [
|
||||
person.uid,
|
||||
last_name,
|
||||
first_name,
|
||||
'',
|
||||
'Academic Researcher',
|
||||
details['Supervisor'] if person.uid == details['person_details'][0].uid else 'askresearch'
|
||||
]
|
||||
|
||||
if record not in health_attesting_rows:
|
||||
health_attesting_rows.append(record)
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error("Error pulling data for workflow #%i: %s" % (approval.workflow_id, str(e)))
|
||||
|
||||
return health_attesting_rows
|
||||
|
||||
@staticmethod
|
||||
def get_not_really_csv_content():
|
||||
approvals = ApprovalService.get_all_approvals(include_cancelled=False)
|
||||
output = []
|
||||
errors = []
|
||||
for approval in approvals:
|
||||
try:
|
||||
details = ApprovalService.get_approval_details(approval)
|
||||
|
||||
for person in details['person_details']:
|
||||
record = {
|
||||
"study_id": approval.study_id,
|
||||
"pi_uid": pi_details.uid,
|
||||
"pi": pi_details.display_name,
|
||||
"name": person.display_name,
|
||||
"uid": person.uid,
|
||||
"email": person.email_address,
|
||||
"supervisor": details['Supervisor'] if person.uid == details['person_details'][0].uid else "",
|
||||
"review_complete": review_complete,
|
||||
}
|
||||
|
||||
output.append(record)
|
||||
|
||||
except Exception as e:
|
||||
errors.append("Error pulling data for workflow #%i: %s" % (approval.workflow_id, str(e)))
|
||||
return {"results": output, "errors": errors }
|
||||
|
||||
@staticmethod
|
||||
def update_approval(approval_id, approver_uid):
|
||||
"""Update a specific approval
|
||||
|
|
|
@ -57,6 +57,32 @@ class TestApprovalsService(BaseTest):
|
|||
self.assertEqual(1, models[0].version)
|
||||
self.assertEqual(2, models[1].version)
|
||||
|
||||
def test_get_health_attesting_records(self):
|
||||
self.load_example_data()
|
||||
self.create_reference_document()
|
||||
workflow = self.create_workflow('empty_workflow')
|
||||
FileService.add_workflow_file(workflow_id=workflow.id,
|
||||
name="anything.png", content_type="text",
|
||||
binary_data=b'5678', irb_doc_code="AD_CoCAppr")
|
||||
|
||||
ApprovalService.add_approval(study_id=workflow.study_id, workflow_id=workflow.id, approver_uid="dhf8r")
|
||||
records = ApprovalService.get_health_attesting_records()
|
||||
|
||||
self.assertEqual(len(records), 1)
|
||||
|
||||
def test_get_not_really_csv_content(self):
|
||||
self.load_example_data()
|
||||
self.create_reference_document()
|
||||
workflow = self.create_workflow('empty_workflow')
|
||||
FileService.add_workflow_file(workflow_id=workflow.id,
|
||||
name="anything.png", content_type="text",
|
||||
binary_data=b'5678', irb_doc_code="AD_CoCAppr")
|
||||
|
||||
ApprovalService.add_approval(study_id=workflow.study_id, workflow_id=workflow.id, approver_uid="dhf8r")
|
||||
records = ApprovalService.get_not_really_csv_content()
|
||||
|
||||
self.assertEqual(len(records), 1)
|
||||
|
||||
def test_new_approval_sends_proper_emails(self):
|
||||
self.assertEqual(1, 1)
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class TestTasksApi(BaseTest):
|
|||
# The total number of tasks may change over time, as users move through gateways
|
||||
# branches may be pruned. As we hit parallel Multi-Instance new tasks may be created...
|
||||
self.assertIsNotNone(workflow.total_tasks)
|
||||
self.assertEquals(prev_completed_task_count + 1, workflow.completed_tasks)
|
||||
self.assertEqual(prev_completed_task_count + 1, workflow.completed_tasks)
|
||||
# Assure a record exists in the Task Events
|
||||
task_events = session.query(TaskEventModel) \
|
||||
.filter_by(workflow_id=workflow.id) \
|
||||
|
@ -56,25 +56,25 @@ class TestTasksApi(BaseTest):
|
|||
self.assertGreater(len(task_events), 0)
|
||||
event = task_events[0]
|
||||
self.assertIsNotNone(event.study_id)
|
||||
self.assertEquals("dhf8r", event.user_uid)
|
||||
self.assertEquals(workflow.id, event.workflow_id)
|
||||
self.assertEquals(workflow.workflow_spec_id, event.workflow_spec_id)
|
||||
self.assertEquals(workflow.spec_version, event.spec_version)
|
||||
self.assertEquals(WorkflowService.TASK_ACTION_COMPLETE, event.action)
|
||||
self.assertEquals(task_in.id, task_id)
|
||||
self.assertEquals(task_in.name, event.task_name)
|
||||
self.assertEquals(task_in.title, event.task_title)
|
||||
self.assertEquals(task_in.type, event.task_type)
|
||||
self.assertEquals("COMPLETED", event.task_state)
|
||||
self.assertEqual("dhf8r", event.user_uid)
|
||||
self.assertEqual(workflow.id, event.workflow_id)
|
||||
self.assertEqual(workflow.workflow_spec_id, event.workflow_spec_id)
|
||||
self.assertEqual(workflow.spec_version, event.spec_version)
|
||||
self.assertEqual(WorkflowService.TASK_ACTION_COMPLETE, event.action)
|
||||
self.assertEqual(task_in.id, task_id)
|
||||
self.assertEqual(task_in.name, event.task_name)
|
||||
self.assertEqual(task_in.title, event.task_title)
|
||||
self.assertEqual(task_in.type, event.task_type)
|
||||
self.assertEqual("COMPLETED", event.task_state)
|
||||
# Not sure what vodoo is happening inside of marshmallow to get me in this state.
|
||||
if isinstance(task_in.multi_instance_type, MultiInstanceType):
|
||||
self.assertEquals(task_in.multi_instance_type.value, event.mi_type)
|
||||
self.assertEqual(task_in.multi_instance_type.value, event.mi_type)
|
||||
else:
|
||||
self.assertEquals(task_in.multi_instance_type, event.mi_type)
|
||||
self.assertEqual(task_in.multi_instance_type, event.mi_type)
|
||||
|
||||
self.assertEquals(task_in.multi_instance_count, event.mi_count)
|
||||
self.assertEquals(task_in.multi_instance_index, event.mi_index)
|
||||
self.assertEquals(task_in.process_name, event.process_name)
|
||||
self.assertEqual(task_in.multi_instance_count, event.mi_count)
|
||||
self.assertEqual(task_in.multi_instance_index, event.mi_index)
|
||||
self.assertEqual(task_in.process_name, event.process_name)
|
||||
self.assertIsNotNone(event.date)
|
||||
|
||||
# Assure that there is data in the form_data
|
||||
|
|
Loading…
Reference in New Issue