launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #08054
[Merge] lp:~dooferlad/launchpad/postponed-is-done into lp:launchpad
James Tunnicliffe has proposed merging lp:~dooferlad/launchpad/postponed-is-done into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1002257 in Launchpad itself: "postponed done upcomingwork"
https://bugs.launchpad.net/launchpad/+bug/1002257
For more details, see:
https://code.launchpad.net/~dooferlad/launchpad/postponed-is-done/+merge/106611
Summary
Feature request: Work Items in the POSTPONED state should be treated as DONE for purposes of calculating completeness on the upcomingwork view.
Proposed fix
Modify the % complete calculation to match the requested change.
Pre-implementation notes
None.
Implementation details
Added a property to WorkItemContainer: postponed_items. This is used, as well as done_items to calculate the % of work items that don’t need to be worked on anymore.
LOC Rationale
Added a few lines because of new functionality. These will be more than offset by:
https://code.launchpad.net/~danilo/launchpad/kill-feedback-requests/+merge/106119
Tests
bin/test -cvt test_person_upcomingwork
Demo and Q/A
1. In a dev instance run http://paste.ubuntu.com/992291/ to generate some work items
2. Visit https://launchpad.dev/~hwdb-team/+upcomingwork and pick a blueprint. Set set all items as DONE. Upcoming work view should show 100% complete for that blueprint. Modifiy some work items to be POSTPONED. Upcoming work view should still show 100% complete for that blueprint.
Lint
None.
--
https://code.launchpad.net/~dooferlad/launchpad/postponed-is-done/+merge/106611
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~dooferlad/launchpad/postponed-is-done into lp:launchpad.
=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py 2012-05-07 16:43:13 +0000
+++ lib/lp/registry/browser/person.py 2012-05-21 11:32:19 +0000
@@ -4451,12 +4451,14 @@
for date, containers in self.work_item_containers:
total_items = 0
total_done = 0
+ total_postponed = 0
milestones = set()
self.bugtask_counts[date] = 0
self.workitem_counts[date] = 0
for container in containers:
total_items += len(container.items)
total_done += len(container.done_items)
+ total_postponed += len(container.postponed_items)
if isinstance(container, AggregatedBugsContainer):
self.bugtask_counts[date] += len(container.items)
else:
@@ -4465,8 +4467,12 @@
milestones.add(item.milestone)
self.milestones_per_date[date] = sorted(
milestones, key=attrgetter('displayname'))
- self.progress_per_date[date] = '{0:.0f}'.format(
- 100.0 * total_done / float(total_items))
+
+ percent_done = 0
+ if total_items > 0:
+ done_or_postponed = total_done + total_postponed
+ percent_done = 100.0 * done_or_postponed / float(total_items)
+ self.progress_per_date[date] = '{0:.0f}'.format(percent_done)
@property
def label(self):
@@ -4516,9 +4522,19 @@
return [item for item in self._items if item.is_complete]
@property
- def percent_done(self):
- return '{0:.0f}'.format(
- 100.0 * len(self.done_items) / len(self._items))
+ def postponed_items(self):
+ return [item for item in self._items
+ if item.status == SpecificationWorkItemStatus.POSTPONED]
+
+ @property
+ def percent_done_or_postponed(self):
+ """Returns % of work items to be worked on."""
+ percent_done = 0
+ if len(self._items) > 0:
+ done_or_postponed = (len(self.done_items) +
+ len(self.postponed_items))
+ percent_done = 100.0 * done_or_postponed / float(len(self._items))
+ return '{0:.0f}'.format(percent_done)
def append(self, item):
self._items.append(item)
=== modified file 'lib/lp/registry/browser/tests/test_person_upcomingwork.py'
--- lib/lp/registry/browser/tests/test_person_upcomingwork.py 2012-04-05 13:49:54 +0000
+++ lib/lp/registry/browser/tests/test_person_upcomingwork.py 2012-05-21 11:32:19 +0000
@@ -163,15 +163,20 @@
class MockWorkItem:
- def __init__(self, is_complete):
+ def __init__(self, is_complete, is_postponed):
self.is_complete = is_complete
- def test_percent_done(self):
+ if is_postponed:
+ self.status = SpecificationWorkItemStatus.POSTPONED
+ else:
+ self.status = None
+
+ def test_percent_done_or_postponed(self):
container = WorkItemContainer()
- container.append(self.MockWorkItem(True))
- container.append(self.MockWorkItem(False))
- container.append(self.MockWorkItem(True))
- self.assertEqual('67', container.percent_done)
+ container.append(self.MockWorkItem(True, False))
+ container.append(self.MockWorkItem(False, False))
+ container.append(self.MockWorkItem(False, True))
+ self.assertEqual('67', container.percent_done_or_postponed)
class TestPersonUpcomingWork(BrowserTestCase):
@@ -270,6 +275,9 @@
spec2 = self.factory.makeSpecification(
product=self.today_milestone.product,
priority=SpecificationPriority.LOW)
+ spec3 = self.factory.makeSpecification(
+ product=self.today_milestone.product,
+ priority=SpecificationPriority.LOW)
self.factory.makeSpecificationWorkItem(
specification=spec1, assignee=self.team.teamowner,
milestone=self.today_milestone,
@@ -278,6 +286,10 @@
specification=spec2, assignee=self.team.teamowner,
milestone=self.today_milestone,
status=SpecificationWorkItemStatus.INPROGRESS)
+ self.factory.makeSpecificationWorkItem(
+ specification=spec3, assignee=self.team.teamowner,
+ milestone=self.today_milestone,
+ status=SpecificationWorkItemStatus.POSTPONED)
browser = self.getViewBrowser(
self.team, view_name='+upcomingwork', no_login=True)
@@ -289,8 +301,11 @@
browser.contents, 'container_progressbar_0')
container2_progressbar = find_tag_by_id(
browser.contents, 'container_progressbar_1')
+ container3_progressbar = find_tag_by_id(
+ browser.contents, 'container_progressbar_2')
self.assertEqual('100%', container1_progressbar.get('width'))
self.assertEqual('0%', container2_progressbar.get('width'))
+ self.assertEqual('100%', container3_progressbar.get('width'))
def test_basic_for_person(self):
"""Check that the page shows the bugs/work items assigned to a person.
=== modified file 'lib/lp/registry/templates/person-upcomingwork.pt'
--- lib/lp/registry/templates/person-upcomingwork.pt 2012-04-05 13:45:31 +0000
+++ lib/lp/registry/templates/person-upcomingwork.pt 2012-05-21 11:32:19 +0000
@@ -44,11 +44,11 @@
<div>
<div style="float: left">Overall completion: </div>
- <div tal:define="percent_done python: view.progress_per_date[date]"
- tal:attributes="title string:${percent_done}% of items completed;"
+ <div tal:define="percent_done_or_postponed python: view.progress_per_date[date]"
+ tal:attributes="title string:${percent_done_or_postponed}% of items completed;"
style="border: 1px solid gray; width: 300px; float:left">
<img tal:attributes="id string:progressbar_${repeat/pair/index};
- width string:${percent_done}%"
+ width string:${percent_done_or_postponed}%"
style="display: block"
src="/@@/green-bar"
height="15"/>
@@ -96,11 +96,11 @@
<td tal:content="structure container/assignee_link" />
<td tal:content="container/priority_title" />
<td>
- <div tal:attributes="title string:${container/percent_done}% of items completed;"
+ <div tal:attributes="title string:${container/percent_done_or_postponed}% of items completed;"
style="border: 1px solid gray; width: 60px">
<img tal:attributes="
id string:container_progressbar_${repeat/container/index};
- width string:${container/percent_done}%"
+ width string:${container/percent_done_or_postponed}%"
style="display: block"
src="/@@/green-bar"
height="10"/>
Follow ups