GeriLife/caregiving

View on GitHub
work/views.py

Summary

Maintainability
A
0 mins
Test Coverage
F
39%
File not formatted according to black style guide
from typing import Any
File not formatted according to black style guide
 
File not formatted according to black style guide
from django.db import connection
File not formatted according to black style guide
from django.db.models import Sum
File not formatted according to black style guide
from django.utils.translation import gettext as _
File not formatted according to black style guide
from django.views.generic import TemplateView
File not formatted according to black style guide
from django.views.generic.edit import FormView
File not formatted according to black style guide
 
File not formatted according to black style guide
import plotly.express as px
File not formatted according to black style guide
 
File not formatted according to black style guide
from core.constants import DAY_MILLISECONDS
File not formatted according to black style guide
 
File not formatted according to black style guide
from .forms import WorkForm
File not formatted according to black style guide
from .models import Work
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def dictfetchall(cursor):
File not formatted according to black style guide
"""Return a list of dictionaries containing all rows from a database
File not formatted according to black style guide
cursor."""
File not formatted according to black style guide
columns = [col[0] for col in cursor.description]
File not formatted according to black style guide
return [dict(zip(columns, row)) for row in cursor.fetchall()]
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def get_daily_total_hours_by_role_and_work_type_with_percent():
File not formatted according to black style guide
query = """
File not formatted according to black style guide
with daily_work_totals_by_type as (
File not formatted according to black style guide
select
File not formatted according to black style guide
date,
File not formatted according to black style guide
caregiver_role.name as role_name,
File not formatted according to black style guide
work_type.name as work_type,
File not formatted according to black style guide
sum(duration_hours) as daily_total_hours
File not formatted according to black style guide
from work
File not formatted according to black style guide
left join work_type on type_id = work_type.id
File not formatted according to black style guide
left join caregiver_role on caregiver_role_id = caregiver_role.id
File not formatted according to black style guide
group by date, role_name, work_type
File not formatted according to black style guide
),
File not formatted according to black style guide
daily_work_totals_by_type_with_role_total_hours as (
File not formatted according to black style guide
select
File not formatted according to black style guide
*,
File not formatted according to black style guide
sum(daily_total_hours) over (partition by date, role_name) as daily_role_total_hours
File not formatted according to black style guide
from daily_work_totals_by_type
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
select
File not formatted according to black style guide
*,
File not formatted according to black style guide
CAST(daily_total_hours as float) / CAST(daily_role_total_hours as float) as percent_of_daily_role_total_hours
File not formatted according to black style guide
from daily_work_totals_by_type_with_role_total_hours;
File not formatted according to black style guide
"""
File not formatted according to black style guide
 
File not formatted according to black style guide
with connection.cursor() as cursor:
File not formatted according to black style guide
cursor.execute(query)
File not formatted according to black style guide
 
File not formatted according to black style guide
result = dictfetchall(cursor)
File not formatted according to black style guide
 
File not formatted according to black style guide
return result
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def get_total_hours_by_role_and_work_type_with_percent():
File not formatted according to black style guide
query = """
File not formatted according to black style guide
with work_totals_by_type as (
File not formatted according to black style guide
select
File not formatted according to black style guide
caregiver_role.name as role_name,
File not formatted according to black style guide
work_type.name as work_type,
File not formatted according to black style guide
sum(duration_hours) as total_hours
File not formatted according to black style guide
from work
File not formatted according to black style guide
left join work_type on type_id = work_type.id
File not formatted according to black style guide
left join caregiver_role on caregiver_role_id = caregiver_role.id
File not formatted according to black style guide
group by role_name, work_type
File not formatted according to black style guide
),
File not formatted according to black style guide
work_totals_by_type_with_role_total_hours as (
File not formatted according to black style guide
select
File not formatted according to black style guide
*,
File not formatted according to black style guide
sum(total_hours) over (partition by role_name) as role_total_hours
File not formatted according to black style guide
from work_totals_by_type
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
select
File not formatted according to black style guide
*,
File not formatted according to black style guide
CAST(total_hours as float) / CAST(role_total_hours as float) as percent_of_role_total_hours
File not formatted according to black style guide
from work_totals_by_type_with_role_total_hours;
File not formatted according to black style guide
"""
File not formatted according to black style guide
 
File not formatted according to black style guide
with connection.cursor() as cursor:
File not formatted according to black style guide
cursor.execute(query)
File not formatted according to black style guide
 
File not formatted according to black style guide
result = dictfetchall(cursor)
File not formatted according to black style guide
 
File not formatted according to black style guide
return result
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def get_work_by_type_data():
File not formatted according to black style guide
work_by_type = (
File not formatted according to black style guide
Work.objects.values("type__name")
File not formatted according to black style guide
.order_by("type__name")
File not formatted according to black style guide
.annotate(total_hours=Sum("duration_hours"))
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
return list(work_by_type)
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def prepare_work_by_type_chart(data):
File not formatted according to black style guide
work_by_type_chart = px.bar(
File not formatted according to black style guide
data,
File not formatted according to black style guide
x="type__name",
File not formatted according to black style guide
y="total_hours",
File not formatted according to black style guide
title=_("Work hours by work type"),
File not formatted according to black style guide
labels={
File not formatted according to black style guide
"type__name": _("Type of work"),
File not formatted according to black style guide
"total_hours": _("Total hours"),
File not formatted according to black style guide
},
File not formatted according to black style guide
).to_html()
File not formatted according to black style guide
 
File not formatted according to black style guide
return work_by_type_chart
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def get_work_by_caregiver_role_data():
File not formatted according to black style guide
work_by_caregiver_role_data = (
File not formatted according to black style guide
Work.objects.values("caregiver_role__name")
File not formatted according to black style guide
.order_by("caregiver_role__name")
File not formatted according to black style guide
.annotate(total_hours=Sum("duration_hours"))
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
return list(work_by_caregiver_role_data)
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def prepare_work_by_caregiver_role_chart(data):
File not formatted according to black style guide
work_by_caregiver_role_chart = px.bar(
File not formatted according to black style guide
data,
File not formatted according to black style guide
x="caregiver_role__name",
File not formatted according to black style guide
y="total_hours",
File not formatted according to black style guide
title=_("Work hours by caregiver role"),
File not formatted according to black style guide
labels={
File not formatted according to black style guide
"caregiver_role__name": _("Caregiver role"),
File not formatted according to black style guide
"total_hours": _("Total hours"),
File not formatted according to black style guide
},
File not formatted according to black style guide
).to_html()
File not formatted according to black style guide
 
File not formatted according to black style guide
return work_by_caregiver_role_chart
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def prepare_daily_work_percent_by_caregiver_role_and_type_chart(data):
File not formatted according to black style guide
daily_work_percent_by_caregiver_role_and_type_chart = px.bar(
File not formatted according to black style guide
data,
File not formatted according to black style guide
x="date",
File not formatted according to black style guide
y="percent_of_daily_role_total_hours",
File not formatted according to black style guide
facet_row="role_name",
File not formatted according to black style guide
color="work_type",
File not formatted according to black style guide
title=_("Daily work percent by caregiver role and work type"),
File not formatted according to black style guide
labels={
File not formatted according to black style guide
"role_name": _("Caregiver role"),
File not formatted according to black style guide
"percent_of_daily_role_total_hours": _("Work percent"),
File not formatted according to black style guide
"work_type": _("Type of work"),
File not formatted according to black style guide
},
File not formatted according to black style guide
# Add numeric text on bars
File not formatted according to black style guide
text_auto=True,
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
# Format y-axis as percentages
File not formatted according to black style guide
daily_work_percent_by_caregiver_role_and_type_chart.update_yaxes(tickformat=",.0%")
File not formatted according to black style guide
 
File not formatted according to black style guide
# Remove facet prefix from facet row labels
File not formatted according to black style guide
daily_work_percent_by_caregiver_role_and_type_chart.for_each_annotation(
File not formatted according to black style guide
lambda a: a.update(text=a.text.split("=")[-1]),
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
# Ensure that all bar widths are one day (where units are in milliseconds)
File not formatted according to black style guide
daily_work_percent_by_caregiver_role_and_type_chart.update_traces(
File not formatted according to black style guide
width=DAY_MILLISECONDS,
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
return daily_work_percent_by_caregiver_role_and_type_chart.to_html()
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def prepare_work_percent_by_caregiver_role_and_type_chart(data):
File not formatted according to black style guide
work_percent_by_caregiver_role_and_type_chart = px.bar(
File not formatted according to black style guide
data,
File not formatted according to black style guide
x="role_name",
File not formatted according to black style guide
y="percent_of_role_total_hours",
File not formatted according to black style guide
color="work_type",
File not formatted according to black style guide
title=_("Work percent by caregiver role and work type"),
File not formatted according to black style guide
labels={
File not formatted according to black style guide
"role_name": _("Caregiver role"),
File not formatted according to black style guide
"percent_of_role_total_hours": _("Work percent"),
File not formatted according to black style guide
"work_type": _("Type of work"),
File not formatted according to black style guide
},
File not formatted according to black style guide
text_auto=True,
File not formatted according to black style guide
)
File not formatted according to black style guide
work_percent_by_caregiver_role_and_type_chart.layout.yaxis.tickformat = ",.0%"
File not formatted according to black style guide
 
File not formatted according to black style guide
return work_percent_by_caregiver_role_and_type_chart.to_html()
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
def prepare_work_by_caregiver_role_and_type_chart(data):
File not formatted according to black style guide
work_by_caregiver_role_and_type_chart = px.bar(
File not formatted according to black style guide
data,
File not formatted according to black style guide
x="role_name",
File not formatted according to black style guide
y="total_hours",
File not formatted according to black style guide
color="work_type",
File not formatted according to black style guide
title=_("Work hours by caregiver role and work type"),
File not formatted according to black style guide
labels={
File not formatted according to black style guide
"role_name": _("Caregiver role"),
File not formatted according to black style guide
"total_hours": _("Total hours"),
File not formatted according to black style guide
"work_type": _("Type of work"),
File not formatted according to black style guide
},
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
return work_by_caregiver_role_and_type_chart.to_html()
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
class WorkReportView(TemplateView):
File not formatted according to black style guide
template_name = "work/report.html"
File not formatted according to black style guide
 
File not formatted according to black style guide
def prepare_charts(self, context):
File not formatted according to black style guide
"""Prepare data/charts and add them to the template context."""
File not formatted according to black style guide
context["work_by_type_chart"] = prepare_work_by_type_chart(
File not formatted according to black style guide
get_work_by_type_data(),
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
context["work_by_caregiver_role_chart"] = prepare_work_by_caregiver_role_chart(
File not formatted according to black style guide
get_work_by_caregiver_role_data(),
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
context["daily_work_percent_by_caregiver_role_and_type_chart"] = (
File not formatted according to black style guide
prepare_daily_work_percent_by_caregiver_role_and_type_chart(
File not formatted according to black style guide
get_daily_total_hours_by_role_and_work_type_with_percent(),
File not formatted according to black style guide
)
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
work_by_caregiver_role_and_type_with_percent = (
File not formatted according to black style guide
get_total_hours_by_role_and_work_type_with_percent()
File not formatted according to black style guide
)
File not formatted according to black style guide
context["work_percent_by_caregiver_role_and_type_chart"] = (
File not formatted according to black style guide
prepare_work_percent_by_caregiver_role_and_type_chart(
File not formatted according to black style guide
work_by_caregiver_role_and_type_with_percent,
File not formatted according to black style guide
)
File not formatted according to black style guide
)
File not formatted according to black style guide
context["work_by_caregiver_role_and_type_chart"] = (
File not formatted according to black style guide
prepare_work_by_caregiver_role_and_type_chart(
File not formatted according to black style guide
work_by_caregiver_role_and_type_with_percent,
File not formatted according to black style guide
)
File not formatted according to black style guide
)
File not formatted according to black style guide
 
File not formatted according to black style guide
return context
File not formatted according to black style guide
 
File not formatted according to black style guide
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
File not formatted according to black style guide
context = super().get_context_data(**kwargs)
File not formatted according to black style guide
 
File not formatted according to black style guide
# Check if work has been recorded
File not formatted according to black style guide
# by selecting one record
File not formatted according to black style guide
context["work_has_been_recorded"] = Work.objects.all()[:1].exists()
File not formatted according to black style guide
 
File not formatted according to black style guide
# Only prepare charts if work has been recorded
File not formatted according to black style guide
if context["work_has_been_recorded"]:
File not formatted according to black style guide
context = self.prepare_charts(context)
File not formatted according to black style guide
 
File not formatted according to black style guide
return context
File not formatted according to black style guide
 
File not formatted according to black style guide
 
File not formatted according to black style guide
class WorkFormView(FormView):
File not formatted according to black style guide
template_name = "work/form.html"
File not formatted according to black style guide
form_class = WorkForm
File not formatted according to black style guide
success_url = "/"
File not formatted according to black style guide
 
File not formatted according to black style guide
def form_valid(self, form):
File not formatted according to black style guide
# save the form before redirecting to success URL
File not formatted according to black style guide
# Note: this may be unnecessary,
File not formatted according to black style guide
# but the form wasn't saving previously
File not formatted according to black style guide
form.save()
File not formatted according to black style guide
 
File not formatted according to black style guide
return super().form_valid(form)