Opened 8 years ago

Last modified 5 months ago

#4376 new enhancement

Show "remaining estimated hours" in the Roadmap

Reported by: k0s Owned by:
Priority: normal Component: TracHoursPlugin
Severity: normal Keywords:
Cc: julien.perville@…, fabien.catteau@… Trac Release: 0.11


I extended the Roadmap screen to display the "remaining estimated hours" per milestone on side of the existing 'estimated hours' and 'total hours'.

The "remaining estimated hours" is the sum of all (estimated times - total time) for each non-closed tickets in a milestone.

Example: imagine that we have a milestone with a total estimated of 20h, and we have worked for 4h so far; then the remaining estimated time is 16h. Now we close a ticket of that milestone that was previously estimated to 2h in only 1h, then the remaining estimated time should drop to 14h (and not to 15h since that ticket that was estimated to 2h has been closed even if we only put 1h of work in it).

Here is a patch over r20999 implements that new feature, feel free to include it into TracHours under same licence as TracHours.

Index: trachours/
--- trachours/	(revision 21074)
+++ trachours/	(working copy)
@@ -1009,7 +1009,8 @@
         hours = {}
         for milestone in data['milestones']:
             hours[] = dict(totalhours=0., 
-                                         estimatedhours=0.,)
+                                         estimatedhours=0.,
+                                         remaininghours=0.,)
             db = self.env.get_db_cnx()
             cursor = db.cursor()
@@ -1020,14 +1021,20 @@
                 hours[]['date'] = Ticket(self.env, tickets[0]).time_created
             for ticket in tickets:
                 ticket = Ticket(self.env, ticket)
-                for field in 'totalhours', 'estimatedhours':
-                    try:
-                        time = float(ticket[field])
-                    except (ValueError, TypeError):
-                        time = 0.
-                    hours[][field] += time
-                    if ticket.time_created < hours[]['date']:
-                        hours[]['date'] = ticket.time_created
+                try:
+                    total_time = float(ticket['totalhours'])
+                except (ValueError, TypeError):
+                    total_time = 0.
+                hours[]['totalhours'] += total_time
+                try:
+                    estimated_time = float(ticket['estimatedhours'])
+                except (ValueError, TypeError):
+                    estimated_time = 0.
+                hours[]['estimatedhours'] += estimated_time
+                if ticket['status'] != 'closed':
+                    hours[]['remaininghours'] += estimated_time - total_time
+                if ticket.time_created < hours[]['date']:
+                    hours[]['date'] = ticket.time_created
         class MilestoneMarkup(object): # TODO: move elsewhere
             def __init__(self, buffer, hours, href):
@@ -1039,19 +1046,23 @@
                 hours = self.hours[milestone]
                 estimatedhours = hours['estimatedhours']
                 totalhours = hours['totalhours']
-                if not (estimatedhours or totalhours):
+                remaininghours = hours['remaininghours']
+                if not (estimatedhours or totalhours or remaininghours):
                     return iter([])
                 items = []
                 if estimatedhours:
-                    items.append(tag.dt("Estimated Hours:"))
+                    items.append(tag.dt("Total Estimated Hours:"))
                 date = hours['date']
                 link = self.href("hours", milestone=milestone, 
-                items.append(tag.dt(tag.a("Total Hours:", href=link)))
+                items.append(tag.dt(tag.a("Total Worked Hours:", href=link)))
                 items.append(tag.dd(tag.a(str(totalhours), href=link)))
+                if remaininghours:
+                    items.append(tag.dt("Remaining Estimated Hours:"))
+                    items.append(tag.dd(str(remaininghours)))
                 return iter(tag.dl(*items))
         find_xpath = "//li[@class='milestone']//h2/a"

Attachments (0)

Change History (3)

comment:1 Changed 8 years ago by k0s

CCing original ticket author, julien.perville@...

comment:2 Changed 6 years ago by rjollos

  • Owner changed from k0s to rjollos

Reassigning ticket to new maintainer.

comment:3 Changed 5 months ago by rjollos

  • Owner rjollos deleted

Add Comment

Modify Ticket

as new The ticket will remain with no owner.

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.