Skip to content

Commit

Permalink
Merge pull request #1609 from 18F/utilization-detail-view
Browse files Browse the repository at this point in the history
Utilization detail view
  • Loading branch information
cantsin authored May 18, 2023
2 parents d158bc9 + f62ece2 commit 196ca38
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 22 deletions.
43 changes: 25 additions & 18 deletions tock/hours/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from decimal import Decimal

import hours.models
import projects.models
from api.tests import client
from api.views import ProjectSerializer, UserDataSerializer
from django.conf import settings
Expand All @@ -17,6 +16,7 @@
from hours.views import (GeneralSnippetsTimecardSerializer, ReportsList,
TimecardView)
from organizations.models import Organization, Unit
from projects.models import AccountingCode, Project

User = get_user_model()

Expand Down Expand Up @@ -71,7 +71,7 @@ def test_project_csv(self):

def test_general_snippets(self):
"""Test that snippets are returned in correct CSV format."""
project = projects.models.Project.objects.get_or_create(
project = Project.objects.get_or_create(
name='General'
)[0]
tco = hours.models.TimecardObject.objects.first()
Expand Down Expand Up @@ -212,12 +212,14 @@ def setUp(self):
self.nonbillable_project = hours.models.Project.objects.filter(
accounting_code__billable=False
)[0]
self.billable_project = projects.models.Project.objects.filter(
self.billable_project = Project.objects.filter(
accounting_code__billable=True
)[0]
self.excluded_project = projects.models.Project.objects.filter(
self.excluded_project = Project.objects.filter(
exclude_from_billability=True
)[0]
self.weekly_billable_project = Project.objects.get(name="Weekly Billing")

self.timecard_obj_0 = hours.models.TimecardObject.objects.create(
timecard=self.timecard,
project=self.nonbillable_project,
Expand All @@ -226,13 +228,18 @@ def setUp(self):
self.timecard_obj_1 = hours.models.TimecardObject.objects.create(
timecard=self.timecard,
project=self.billable_project,
hours_spent=27
hours_spent=10
)
self.timecard_obj_2 = hours.models.TimecardObject.objects.create(
timecard=self.timecard,
project=self.excluded_project,
hours_spent=2
)
self.timecard_obj_3 = hours.models.TimecardObject.objects.create(
timecard=self.timecard,
project=self.weekly_billable_project,
project_allocation=0.5
)
self.timecard.save()

def test_user_reporting_period_report(self):
Expand All @@ -241,12 +248,13 @@ def test_user_reporting_period_report(self):
'reports:ReportingPeriodUserDetailView',
kwargs={'reporting_period':'1999-12-31', 'username':'aaron.snow'}
))
self.assertEqual(response.context['user_utilization'], Decimal('0.90'))
self.assertEqual(response.context['user_utilization'], Decimal('0.83'))
self.assertEqual(response.context['user_target_hours'], 30.00)
self.assertEqual(response.context['user_billable_hours'], 27)
self.assertEqual(response.context['user_billable_hours'], 10)
self.assertEqual(response.context['user_non_billable_hours'], 11)
self.assertEqual(response.context['user_weekly_allocation'], Decimal('0.5'))
self.assertEqual(response.context['user_excluded_hours'], 2)
self.assertContains(response, '90%')
self.assertContains(response, '83%')

@override_settings(STARTING_FY_FOR_REPORTS_PAGE=2015)
class ReportTests(WebTest):
Expand All @@ -268,9 +276,8 @@ def setUp(self):
user=self.user,
submitted=True,
reporting_period=self.reporting_period)
self.project_1 = projects.models.Project.objects.get(name="openFEC")
self.project_2 = projects.models.Project.objects.get(
name="Peace Corps")
self.project_1 = Project.objects.get(name="openFEC")
self.project_2 = Project.objects.get(name="Peace Corps")
self.timecard_object_1 = hours.models.TimecardObject.objects.create(
timecard=self.timecard,
project=self.project_1,
Expand Down Expand Up @@ -498,23 +505,23 @@ def test_project_choice_filtering(self):
org_coe = Organization.objects.create(name='CoE')
org_coe.save()

accounting_code = projects.models.AccountingCode.objects.get(pk=1)
accounting_code = AccountingCode.objects.get(pk=1)

project_18f = projects.models.Project.objects.create(
project_18f = Project.objects.create(
name='an 18f project',
accounting_code=accounting_code,
organization=org_18f
)
project_18f.save()

project_coe = projects.models.Project.objects.create(
project_coe = Project.objects.create(
name='a coe project',
accounting_code=accounting_code,
organization=org_coe
)
project_coe.save()

project_none = projects.models.Project.objects.create(
project_none = Project.objects.create(
name='a project with no org assignment',
accounting_code=accounting_code,
)
Expand Down Expand Up @@ -687,7 +694,7 @@ def test_do_not_prefill_timecard(self):
submitted=False,
reporting_period=new_period
)
new_project = projects.models.Project.objects.get(name="Midas")
new_project = Project.objects.get(name="Midas")
new_tco = hours.models.TimecardObject.objects.create(
timecard=new_timecard,
project=new_project,
Expand Down Expand Up @@ -1013,9 +1020,9 @@ def setUp(self):
user=self.user
)

self.project_1 = projects.models.Project.objects.first()
self.project_1 = Project.objects.first()
self.project_1.save()
self.project_2 = projects.models.Project.objects.last()
self.project_2 = Project.objects.last()
self.project_2.save()

self.pfd1 = hours.models.TimecardPrefillData.objects.create(
Expand Down
1 change: 1 addition & 0 deletions tock/hours/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,7 @@ def get_context_data(self, **kwargs):
context = super(
ReportingPeriodUserDetailView, self).get_context_data(**kwargs)
context['user_billable_hours'] = timecard.billable_hours
context['user_weekly_allocation'] = timecard.total_weekly_allocation
context['user_non_billable_hours'] = timecard.non_billable_hours
context['user_excluded_hours'] = timecard.excluded_hours
context['user_target_hours'] = timecard.target_hours
Expand Down
14 changes: 11 additions & 3 deletions tock/tock/templates/employees/user_recent_tocks.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,30 @@ <h2>Recent Tocks</h2>
<tfoot>
<tr><th scope="row"><b>Totals</b></th></tr>
<tr>
<th scope="row"><b>Billable</b></th>
<th scope="row"><b>Billable Hours</b></th>
{% for i in recent_timecards %}
{% with recent_timecards|index:forloop.counter0 as tc %}
<td>{{tc.billable_hours}}</td>
{% endwith %}
{% endfor %}
</tr>
<tr>
<th scope="row"><b>Non-Billable</b></th>
<tr>
<th scope="row"><b>Billable Allocation</b></th>
{% for i in recent_timecards %}
{% with recent_timecards|index:forloop.counter0 as tc %}
<td>{{tc.non_billable_hours}}</td>
<td>{% widthratio tc.total_weekly_allocation 1 100 %}%</td>
{% endwith %}
{% endfor %}
</tr>
<tr>
<th scope="row"><b>Non-Billable Hours</b></th>
{% for i in recent_timecards %}
{% with recent_timecards|index:forloop.counter0 as tc %}
<td>{{tc.non_billable_hours}}</td>
{% endwith %}
{% endfor %}
</tr>
<th scope="row"><b>Excluded from Utilization</b></th>
{% for i in recent_timecards %}
{% with recent_timecards|index:forloop.counter0 as tc %}
Expand Down
5 changes: 4 additions & 1 deletion tock/tock/templates/hours/reporting_period_user_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ <h1>{{ object.user }}'s time from {{ object.reporting_period.start_date }} to {{
{% endif %}
</td>
<td data-title="Hours spent">{{ entry.hours_spent }}</td>
<td data-title="Project Allocation">{{ entry.project_allocation }}</td>
<td data-title="Project Allocation">{% widthratio entry.project_allocation 1 100 %}%
</td>
<td data-title="Notes">
{% for note in entry.notes_list %}
<p>{{ note }}</p>
Expand Down Expand Up @@ -58,6 +59,7 @@ <h3>Reporting Period Summary</h3>
<thead>
<tr>
<th>Billable Hours</th>
<th>Billable Allocation</th>
<th>Non-Billable Hours</th>
<th>Excluded Hours</th>
<th>Target Hours</th>
Expand All @@ -67,6 +69,7 @@ <h3>Reporting Period Summary</h3>
<tbody>
<tr>
<td data-title="Billable hours"> {{ user_billable_hours }} </td>
<td data-title="Billable allocation">{% widthratio user_weekly_allocation 1 100 %}% </td>
<td data-title="Non-Billable hours"> {{ user_non_billable_hours }} </td>
<td data-title="Excluded hours"> {{ user_excluded_hours }} </td>
<td data-title="Target hours"> {{ user_target_hours }} </td>
Expand Down

0 comments on commit 196ca38

Please sign in to comment.