2022-01-19 08:40:02 +08:00
|
|
|
import io
|
|
|
|
import logging
|
2022-04-22 03:33:54 +08:00
|
|
|
from typing import Optional
|
|
|
|
|
2022-01-19 08:40:02 +08:00
|
|
|
import strawberry # noqa
|
|
|
|
import pandas as pd
|
|
|
|
from felicity.apps.analysis.models.analysis import Sample
|
|
|
|
from felicity.apps.analysis.models.results import AnalysisResult
|
|
|
|
from felicity.apps.worksheet.models import WorkSheet
|
|
|
|
from felicity.apps.user.models import User
|
|
|
|
from felicity.apps.setup.models import Instrument
|
2022-03-24 14:59:39 +08:00
|
|
|
from felicity.apps.analytics import SampleAnalyticsInit
|
2022-01-19 08:40:02 +08:00
|
|
|
from felicity.api.gql.analytics import types
|
|
|
|
from felicity.utils import has_value_or_is_truthy
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
def group_exists(val):
|
|
|
|
if has_value_or_is_truthy(val):
|
|
|
|
return str(val)
|
|
|
|
return 'unknown'
|
|
|
|
|
|
|
|
|
|
|
|
async def get_username(val):
|
|
|
|
if val == 'unknown':
|
|
|
|
return val
|
|
|
|
user = await User.get(uid=int(val))
|
|
|
|
return user.auth.user_name
|
|
|
|
|
|
|
|
|
|
|
|
async def get_instrument(val):
|
|
|
|
if val == 'unknown':
|
|
|
|
return val
|
|
|
|
instrument = await Instrument.get(uid=int(val))
|
|
|
|
return instrument.name
|
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
|
|
|
async def test_stuff(info) -> types.Nothing:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(Sample)
|
2022-01-19 08:40:02 +08:00
|
|
|
columns, lines = await analytics.get_line_listing()
|
|
|
|
|
|
|
|
# line = await analytics.get_line_listing_2()
|
|
|
|
|
|
|
|
data_list = [line for line in lines]
|
|
|
|
|
|
|
|
df = pd.DataFrame(data_list, columns=columns)
|
|
|
|
|
|
|
|
df.to_csv("data.csv", index=False)
|
|
|
|
s_buffer = io.StringIO()
|
|
|
|
df.to_csv(s_buffer, index=False)
|
|
|
|
in_memory_file = s_buffer.seek(0)
|
|
|
|
|
|
|
|
# json.dumps([(dict(row.items())) for row in rs]) to json
|
|
|
|
|
|
|
|
return types.Nothing(data="")
|
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
|
|
|
async def count_sample_group_by_status(info) -> types.GroupedCounts:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(Sample)
|
2022-04-22 03:33:54 +08:00
|
|
|
results = await analytics.get_counts_group_by('status', ("", ""), ("", ""))
|
2022-01-19 08:40:02 +08:00
|
|
|
|
|
|
|
stats = []
|
|
|
|
for row in results:
|
|
|
|
stats.append(types.GroupCount(group=group_exists(row[0]), count=row[1]))
|
|
|
|
|
|
|
|
return types.GroupedCounts(data=stats)
|
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
2022-01-23 07:15:53 +08:00
|
|
|
async def count_analyte_group_by_status(info) -> types.GroupedCounts:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(AnalysisResult)
|
2022-04-22 03:33:54 +08:00
|
|
|
results = await analytics.get_counts_group_by('status', ("", ""), ("", ""))
|
2022-01-19 08:40:02 +08:00
|
|
|
|
|
|
|
stats = []
|
2022-01-23 07:15:53 +08:00
|
|
|
for row in results:
|
|
|
|
stats.append(types.GroupCount(group=group_exists(row[0]), count=row[1]))
|
2022-01-19 08:40:02 +08:00
|
|
|
|
2022-01-23 07:15:53 +08:00
|
|
|
return types.GroupedCounts(data=stats)
|
2022-01-19 08:40:02 +08:00
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
2022-01-23 07:15:53 +08:00
|
|
|
async def count_worksheet_group_by_status(info) -> types.GroupedCounts:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(WorkSheet)
|
2022-04-22 03:33:54 +08:00
|
|
|
results = await analytics.get_counts_group_by('state', ("", ""), ("", ""))
|
2022-01-19 08:40:02 +08:00
|
|
|
|
|
|
|
stats = []
|
|
|
|
for row in results:
|
|
|
|
stats.append(types.GroupCount(group=group_exists(row[0]), count=row[1]))
|
|
|
|
|
|
|
|
return types.GroupedCounts(data=stats)
|
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
2022-04-22 03:33:54 +08:00
|
|
|
async def count_analyte_group_by_instrument(
|
|
|
|
info,
|
|
|
|
start_date: Optional[str] = None,
|
|
|
|
end_date: Optional[str] = None
|
|
|
|
) -> types.GroupedCounts:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(AnalysisResult)
|
2022-04-22 03:33:54 +08:00
|
|
|
results = await analytics.get_counts_group_by(
|
|
|
|
'instrument_uid',
|
|
|
|
("date_submitted", start_date),
|
|
|
|
("date_submitted", end_date)
|
|
|
|
)
|
2022-01-19 08:40:02 +08:00
|
|
|
|
|
|
|
stats = []
|
|
|
|
for row in results:
|
|
|
|
stats.append(types.GroupCount(group=get_instrument(group_exists(row[0])), count=row[1]))
|
|
|
|
|
|
|
|
return types.GroupedCounts(data=stats)
|
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
2022-04-22 03:33:54 +08:00
|
|
|
async def count_sample_group_by_action(
|
|
|
|
info,
|
|
|
|
start_date: Optional[str] = None,
|
|
|
|
end_date: Optional[str] = None
|
|
|
|
) -> types.GroupedData:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(Sample)
|
2022-04-22 03:33:54 +08:00
|
|
|
created = await analytics.get_counts_group_by(
|
|
|
|
'created_by_uid',
|
|
|
|
('created_at', start_date),
|
|
|
|
('created_at', end_date)
|
|
|
|
)
|
|
|
|
submitted = await analytics.get_counts_group_by(
|
|
|
|
'submitted_by_uid',
|
|
|
|
('date_submitted', start_date),
|
|
|
|
('date_submitted', end_date)
|
|
|
|
)
|
|
|
|
verified = await analytics.get_counts_group_by(
|
|
|
|
'verified_by_uid',
|
|
|
|
('date_verified', start_date),
|
|
|
|
('date_verified', end_date)
|
|
|
|
)
|
|
|
|
published = await analytics.get_counts_group_by(
|
|
|
|
'published_by_uid',
|
|
|
|
('date_published', start_date),
|
|
|
|
('date_published', end_date)
|
|
|
|
)
|
2022-01-19 08:40:02 +08:00
|
|
|
|
|
|
|
stats = []
|
2022-01-23 07:15:53 +08:00
|
|
|
registration = types.GroupData(group="registration", counts=[])
|
|
|
|
for row in created:
|
|
|
|
registration.counts.append(types.GroupCount(group=get_username(group_exists(row[0])), count=row[1]))
|
|
|
|
stats.append(registration)
|
2022-01-19 08:40:02 +08:00
|
|
|
|
2022-01-23 07:15:53 +08:00
|
|
|
submission = types.GroupData(group="submission", counts=[])
|
|
|
|
for row in submitted:
|
|
|
|
submission.counts.append(types.GroupCount(group=get_username(group_exists(row[0])), count=row[1]))
|
|
|
|
stats.append(submission)
|
|
|
|
|
|
|
|
verification = types.GroupData(group="verification", counts=[])
|
|
|
|
for row in verified:
|
|
|
|
verification.counts.append(types.GroupCount(group=get_username(group_exists(row[0])), count=row[1]))
|
|
|
|
stats.append(verification)
|
|
|
|
|
|
|
|
publication = types.GroupData(group="publication", counts=[])
|
|
|
|
for row in published:
|
|
|
|
publication.counts.append(types.GroupCount(group=get_username(group_exists(row[0])), count=row[1]))
|
|
|
|
stats.append(publication)
|
|
|
|
|
|
|
|
return types.GroupedData(data=stats)
|
2022-01-19 08:40:02 +08:00
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
|
|
|
async def sample_process_performance(info, start_date: str, end_date: str) -> types.ProcessStatistics:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(Sample)
|
2022-01-19 08:40:02 +08:00
|
|
|
received_to_published = await analytics.get_sample_process_performance(
|
|
|
|
start=('date_received', start_date),
|
|
|
|
end=('date_published', end_date)
|
|
|
|
)
|
|
|
|
received_to_submitted = await analytics.get_sample_process_performance(
|
|
|
|
start=('date_received', start_date),
|
|
|
|
end=('date_submitted', end_date)
|
|
|
|
)
|
|
|
|
submitted_to_verified = await analytics.get_sample_process_performance(
|
|
|
|
start=('date_submitted', start_date),
|
|
|
|
end=('date_verified', end_date)
|
|
|
|
)
|
|
|
|
verified_to_published = await analytics.get_sample_process_performance(
|
|
|
|
start=('date_verified', start_date),
|
|
|
|
end=('date_published', end_date)
|
|
|
|
)
|
|
|
|
|
|
|
|
final_data = []
|
|
|
|
|
|
|
|
rtp_process = types.ProcessData(process="received_to_published", counts=None, groups=[])
|
|
|
|
for row in received_to_published:
|
|
|
|
rtp_process.counts = types.ProcessCounts(
|
|
|
|
total_samples=row[0],
|
|
|
|
total_late=row[1],
|
|
|
|
total_not_late=row[2],
|
|
|
|
process_average=row[3],
|
|
|
|
avg_extra_days=row[4]
|
|
|
|
)
|
|
|
|
final_data.append(rtp_process)
|
|
|
|
|
|
|
|
rts_process = types.ProcessData(process="received_to_submitted", counts=None, groups=[])
|
|
|
|
for row in received_to_submitted:
|
|
|
|
rts_process.counts = types.ProcessCounts(
|
|
|
|
total_samples=row[0],
|
|
|
|
total_late=row[1],
|
|
|
|
total_not_late=row[2],
|
|
|
|
process_average=row[3],
|
|
|
|
avg_extra_days=row[4]
|
|
|
|
)
|
|
|
|
final_data.append(rts_process)
|
|
|
|
|
|
|
|
stv_process = types.ProcessData(process="submitted_to_verified", counts=None, groups=[])
|
|
|
|
for row in submitted_to_verified:
|
|
|
|
stv_process.counts = types.ProcessCounts(
|
|
|
|
total_samples=row[0],
|
|
|
|
total_late=row[1],
|
|
|
|
total_not_late=row[2],
|
|
|
|
process_average=row[3],
|
|
|
|
avg_extra_days=row[4]
|
|
|
|
)
|
|
|
|
final_data.append(stv_process)
|
|
|
|
|
|
|
|
stp_process = types.ProcessData(process="verified_to_published", counts=None, groups=[])
|
|
|
|
for row in verified_to_published:
|
|
|
|
stp_process.counts = types.ProcessCounts(
|
|
|
|
total_samples=row[0],
|
|
|
|
total_late=row[1],
|
|
|
|
total_not_late=row[2],
|
|
|
|
process_average=row[3],
|
|
|
|
avg_extra_days=row[4]
|
|
|
|
)
|
|
|
|
final_data.append(stp_process)
|
|
|
|
|
|
|
|
return types.ProcessStatistics(data=final_data)
|
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
|
|
|
async def analysis_process_performance(info, process: str, start_date: str, end_date: str) -> types.ProcessStatistics:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(Sample)
|
2022-01-19 08:40:02 +08:00
|
|
|
processes = [
|
|
|
|
'received_to_published',
|
|
|
|
'received_to_submitted',
|
|
|
|
'submitted_to_verified',
|
|
|
|
'verified_to_published'
|
|
|
|
]
|
|
|
|
if process not in processes:
|
|
|
|
logger.warning(f"invalid process {process}")
|
|
|
|
raise Exception(f"invalid process {process}")
|
|
|
|
|
|
|
|
performance = []
|
|
|
|
if process == 'received_to_published':
|
|
|
|
performance = await analytics.get_analysis_process_performance(
|
|
|
|
start=('date_received', start_date),
|
|
|
|
end=('date_published', end_date)
|
|
|
|
)
|
|
|
|
if process == 'received_to_submitted':
|
|
|
|
performance = await analytics.get_analysis_process_performance(
|
|
|
|
start=('date_received', start_date),
|
|
|
|
end=('date_submitted', end_date)
|
|
|
|
)
|
|
|
|
if process == 'submitted_to_verified':
|
|
|
|
performance = await analytics.get_analysis_process_performance(
|
|
|
|
start=('date_submitted', start_date),
|
|
|
|
end=('date_verified', end_date)
|
|
|
|
)
|
|
|
|
if process == 'verified_to_published':
|
|
|
|
performance = await analytics.get_analysis_process_performance(
|
|
|
|
start=('date_verified', start_date),
|
|
|
|
end=('date_published', end_date)
|
|
|
|
)
|
|
|
|
|
|
|
|
final_data = []
|
|
|
|
|
|
|
|
rtp_process = types.ProcessData(process=process, counts=None, groups=[])
|
|
|
|
|
|
|
|
for row in performance:
|
|
|
|
rtp_process.groups.append(types.ProcessCounts(
|
|
|
|
service=row[0],
|
|
|
|
total_samples=row[1],
|
|
|
|
total_late=row[2],
|
|
|
|
total_not_late=row[3],
|
|
|
|
process_average=row[4],
|
|
|
|
avg_extra_days=row[5]
|
|
|
|
))
|
|
|
|
final_data.append(rtp_process)
|
|
|
|
|
|
|
|
return types.ProcessStatistics(data=final_data)
|
|
|
|
|
|
|
|
|
|
|
|
@strawberry.field
|
|
|
|
async def sample_laggards(info) -> types.LaggardStatistics:
|
2022-03-24 14:59:39 +08:00
|
|
|
analytics = SampleAnalyticsInit(Sample)
|
2022-01-19 08:40:02 +08:00
|
|
|
not_complete, complete = await analytics.get_laggards()
|
|
|
|
|
|
|
|
final_data = []
|
|
|
|
|
|
|
|
complete_laggards = types.LaggardData(category="authorised_already_delayed", counts=[])
|
|
|
|
for row in complete:
|
|
|
|
complete_laggards.counts = types.LaggardCounts(
|
|
|
|
total_delayed=row[0],
|
|
|
|
lessThanTen=row[1],
|
|
|
|
tenToTwenty=row[2],
|
|
|
|
twentyToThirty=row[3],
|
|
|
|
graterThanThirty=row[4]
|
|
|
|
)
|
|
|
|
final_data.append(complete_laggards)
|
|
|
|
|
|
|
|
in_complete_laggards = types.LaggardData(category="delayed_and_incomplete", counts=[])
|
|
|
|
for row in not_complete:
|
|
|
|
in_complete_laggards.counts = types.LaggardCounts(
|
|
|
|
total_incomplete=row[0],
|
|
|
|
total_delayed=row[1],
|
|
|
|
total_not_delayed=row[2],
|
|
|
|
lessThanTen=row[3],
|
|
|
|
tenToTwenty=row[4],
|
|
|
|
twentyToThirty=row[5],
|
|
|
|
graterThanThirty=row[6]
|
|
|
|
)
|
|
|
|
final_data.append(in_complete_laggards)
|
|
|
|
|
|
|
|
return types.LaggardStatistics(data=final_data)
|