Skip to content

Commit

Permalink
Merge pull request #850 from caktus/TM-845
Browse files Browse the repository at this point in the history
Tm 845
  • Loading branch information
Rob Lineberger committed Dec 30, 2015
2 parents b056282 + e2b3dc6 commit 90d8f4d
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 2 deletions.
4 changes: 4 additions & 0 deletions timepiece/contracts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ def get_context_data(self, *args, **kwargs):
[0.0] + [c.fraction_hours for c in self.queryset.all()])
kwargs['max_schedule_fraction'] = max(
[0.0] + [c.fraction_schedule for c in self.queryset.all()])
kwargs['projects_pending'] = ProjectContract.objects.filter(
status=ProjectContract.STATUS_UPCOMING).order_by('name')
kwargs['projects_complete'] = ProjectContract.objects.filter(
status=ProjectContract.STATUS_COMPLETE).order_by('name')
return super(ContractList, self).get_context_data(*args, **kwargs)


Expand Down
3 changes: 2 additions & 1 deletion timepiece/entries/lookups.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def get_query(self, request, term):
results = super(ActivityLookup, self).get_query(request, term)
project = Project.objects.get(pk=request.GET.get('project', ''))
if project:
results = project.activity_group.activities.all()
if project.activity_group:
return project.activity_group.activities.all()
return results

def get_item_label(self, item):
Expand Down
13 changes: 12 additions & 1 deletion timepiece/entries/tests/test_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def test_no_other_active_entries(self):
self.assertEqual(len(response.context['others_active_entries']), 0)

def test_clock_in_form_activity_lookup(self):
"""Create an ActivityGroup that includes the Activity, and accosiate it with the project.
"""Create an ActivityGroup that includes the Activity, and associate it with the project.
Add a second Activity that is not included. Ensure that the ActivityLookup disallows
the second Activity. """
factory = RequestFactory()
Expand All @@ -163,6 +163,17 @@ def test_clock_in_form_activity_lookup(self):
self.assertEqual(1, len(data))
self.assertEqual(self.activity.pk, data[0]['id'])

def test_clock_in_form_activity_without_project_activity_group(self):
"""Ensure that the ActivityLookup provides all Activities if Project does not have an
activity group. """
factory = RequestFactory()
lookup = ActivityLookup()
factories.Activity()
request = factory.get("/entry/clock_in/", {'project': self.project.pk})
response = lookup.results(request)
data = json.loads(response.content.decode("utf-8"))['data']
self.assertEqual(2, len(data))


class ProcessProgressTestCase(TestCase):
"""Tests for process_progress."""
Expand Down
121 changes: 121 additions & 0 deletions timepiece/templates/timepiece/contract/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
{% block content %}
<div class="row-fluid">
<div class="span12">

<ul class="nav nav-tabs">
<li role="presentation" class="active"><a href="#current" data-toggle="tab">Current Contracts</a></li>
<li role="presentation"><a href="#pending" data-toggle="tab">Pending Contracts</a></li>
<li role="presentation"><a href="#completed" data-toggle="tab">Completed Contracts</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in active" id="current">
<h2 class="page-title">Current Contracts</h2>
<table class="table table-bordered table-striped table-condensed contracts">
<thead>
Expand Down Expand Up @@ -71,5 +79,118 @@ <h2 class="page-title">Current Contracts</h2>
</tbody>
</table>
</div>
<div class="tab-pane fade" id="pending">
<h2 class="page-title">Pending Contracts</h2>
<table class="table table-bordered table-striped table-condensed contracts">
<thead>
<tr>
<th rowspan="2">Name</th>
<th rowspan="2">Start Date</th>
<th rowspan="2">End Date</th>
<th rowspan="2">Contract Hours</th>
<th colspan="2">Hours Worked</th>
<th rowspan="2" class="hidden-phone">Progress: days elapsed/hours worked</th>
<th rowspan="2">Contract Type</th>
</tr>
<tr>
<th>Billable</th>
<th>Non-billable</th>
</tr>
</thead>
<tbody>
{% for contract in projects_pending %}
{% if contract.end_date < today %}
<tr class="expired" title="This contract has expired.">
{% elif contract.end_date < warning_date %}
<tr class="expiring-soon" title="This contract will expire in less than 2 weeks.">
{% else %}
<tr>
{% endif %}
<td><a href="{% url 'view_contract' contract.id %}">{{ contract.name }}</a></td>
<td class="nowrap">{{ contract.start_date|date:'M j, Y' }}</td>
<td class="nowrap{% if contract.end_date < today %} past{% endif %}">
{{ contract.end_date|date:'M j, Y' }}
{% if contract.end_date >= today and contract.end_date < warning_date %}
<i class="icon-warning-sign"></i>
{% endif %}
</td>
<td class="nowrap hours">
{{ contract.contracted_hours|floatformat:2 }}
{% if contract.pending_hours %}
<span class="pending_hours">(+{{ contract.pending_hours|floatformat:2 }})</span>
{% endif %}
</td>
<td class="nowrap hours">{{ contract.hours_worked|floatformat:2 }} ({% widthratio contract.hours_worked contract.contracted_hours 100 %}%)</td>
<td class="nowrap hours">{{ contract.nonbillable_hours_worked|floatformat:2 }}</td>
<td class="hidden-phone">
<div class="project-bar" style="width: 100%"
data-fraction="{{ contract.fraction_schedule }}"></div>
<div class="project-bar" style="width: 100%"
data-fraction="{{ contract.fraction_hours }}"></div>
</td>
<td class="nowrap">{{ contract.get_type_display }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="tab-pane fade" id="completed">
<h2 class="page-title">Completed Contracts</h2>
<table class="table table-bordered table-striped table-condensed contracts">
<thead>
<tr>
<th rowspan="2">Name</th>
<th rowspan="2">Start Date</th>
<th rowspan="2">End Date</th>
<th rowspan="2">Contract Hours</th>
<th colspan="2">Hours Worked</th>
<th rowspan="2" class="hidden-phone">Progress: days elapsed/hours worked</th>
<th rowspan="2">Contract Type</th>
</tr>
<tr>
<th>Billable</th>
<th>Non-billable</th>
</tr>
</thead>
<tbody>
{% for contract in projects_complete %}
{% if contract.end_date < today %}
<tr class="expired" title="This contract has expired.">
{% elif contract.end_date < warning_date %}
<tr class="expiring-soon" title="This contract will expire in less than 2 weeks.">
{% else %}
<tr>
{% endif %}
<td><a href="{% url 'view_contract' contract.id %}">{{ contract.name }}</a></td>
<td class="nowrap">{{ contract.start_date|date:'M j, Y' }}</td>
<td class="nowrap{% if contract.end_date < today %} past{% endif %}">
{{ contract.end_date|date:'M j, Y' }}
{% if contract.end_date >= today and contract.end_date < warning_date %}
<i class="icon-warning-sign"></i>
{% endif %}
</td>
<td class="nowrap hours">
{{ contract.contracted_hours|floatformat:2 }}
{% if contract.pending_hours %}
<span class="pending_hours">(+{{ contract.pending_hours|floatformat:2 }})</span>
{% endif %}
</td>
<td class="nowrap hours">{{ contract.hours_worked|floatformat:2 }} ({% widthratio contract.hours_worked contract.contracted_hours 100 %}%)</td>
<td class="nowrap hours">{{ contract.nonbillable_hours_worked|floatformat:2 }}</td>
<td class="hidden-phone">
<div class="project-bar" style="width: 100%"
data-fraction="{{ contract.fraction_schedule }}"></div>
<div class="project-bar" style="width: 100%"
data-fraction="{{ contract.fraction_hours }}"></div>
</td>
<td class="nowrap">{{ contract.get_type_display }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>

</div>
</div>
{% endblock content %}

0 comments on commit 90d8f4d

Please sign in to comment.