mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-01-06 03:30:25 -06:00
feat(tasks): show Billable Hours in Task Time Tracking
Add Task.total_billable_hours aggregating billable TimeEntry.duration_seconds (rounded to 2 decimals) Expose total_billable_hours via Task.to_dict Update tasks/view.html to display “Billable Hours” when > 0 No schema change; uses existing billable flag and durations
This commit is contained in:
@@ -81,6 +81,22 @@ class Task(db.Model):
|
||||
return round(total_seconds / 3600, 2)
|
||||
except Exception:
|
||||
return 0.0
|
||||
|
||||
@property
|
||||
def total_billable_hours(self):
|
||||
"""Calculate total billable hours spent on this task"""
|
||||
try:
|
||||
from .time_entry import TimeEntry
|
||||
total_seconds = db.session.query(
|
||||
db.func.sum(TimeEntry.duration_seconds)
|
||||
).filter(
|
||||
TimeEntry.task_id == self.id,
|
||||
TimeEntry.end_time.isnot(None),
|
||||
TimeEntry.billable == True
|
||||
).scalar() or 0
|
||||
return round(total_seconds / 3600, 2)
|
||||
except Exception:
|
||||
return 0.0
|
||||
|
||||
@property
|
||||
def progress_percentage(self):
|
||||
@@ -220,6 +236,7 @@ class Task(db.Model):
|
||||
'started_at': self.started_at.isoformat() if self.started_at else None,
|
||||
'completed_at': self.completed_at.isoformat() if self.completed_at else None,
|
||||
'total_hours': self.total_hours,
|
||||
'total_billable_hours': self.total_billable_hours,
|
||||
'progress_percentage': self.progress_percentage,
|
||||
'is_active': self.is_active,
|
||||
'is_overdue': self.is_overdue
|
||||
|
||||
@@ -141,6 +141,15 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.total_billable_hours > 0 %}
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="text-center">
|
||||
<div class="h4 text-success mb-1">{{ task.total_billable_hours }}</div>
|
||||
<small class="text-muted">{{ _('Billable Hours') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.estimated_hours and task.total_hours > 0 %}
|
||||
<div class="col-6 col-md-3">
|
||||
|
||||
Reference in New Issue
Block a user