2424from django .db import models
2525from django .utils import timezone
2626
27-
2827HEX_COLOR_VALIDATOR = RegexValidator (
2928 regex = r"^#(?:[0-9a-fA-F]{3}){1,2}$" ,
3029 message = "Color must be a hex value like #0d6efd or #abc." ,
@@ -75,10 +74,11 @@ def total_hours(self, since=None, until=None) -> Decimal:
7574 def total_cost (self , since = None , until = None ) -> Decimal | None :
7675 if self .hourly_rate is None :
7776 return None
78- return (self .total_hours (since = since , until = until ) * self .hourly_rate ).quantize (Decimal ("0.01" ))
77+ total = self .total_hours (since = since , until = until ) * self .hourly_rate
78+ return total .quantize (Decimal ("0.01" ))
7979
8080 @property
81- def active_timer (self ) -> " TimeEntry | None" :
81+ def active_timer (self ) -> TimeEntry | None :
8282 """Return the currently-running timer for this project, if any."""
8383 return self .entries .filter (end_time__isnull = True ).order_by ("-start_time" ).first ()
8484
@@ -104,6 +104,15 @@ class Meta:
104104 def __str__ (self ) -> str :
105105 return f"{ self .project .name } · { self .date } · { self .duration_display } "
106106
107+ def save (self , * args , ** kwargs ):
108+ # Auto-compute duration when both timestamps are set
109+ if self .start_time and self .end_time :
110+ delta : timedelta = self .end_time - self .start_time
111+ self .duration_minutes = max (0 , int (delta .total_seconds () // 60 ))
112+ if not self .date :
113+ self .date = timezone .localdate (self .start_time )
114+ super ().save (* args , ** kwargs )
115+
107116 @property
108117 def is_running (self ) -> bool :
109118 return self .start_time is not None and self .end_time is None
@@ -124,12 +133,3 @@ def current_duration_minutes(self) -> int:
124133 def clean (self ):
125134 if self .start_time and self .end_time and self .end_time < self .start_time :
126135 raise ValidationError ("End time must be after start time." )
127-
128- def save (self , * args , ** kwargs ):
129- # Auto-compute duration when both timestamps are set
130- if self .start_time and self .end_time :
131- delta : timedelta = self .end_time - self .start_time
132- self .duration_minutes = max (0 , int (delta .total_seconds () // 60 ))
133- if not self .date :
134- self .date = timezone .localdate (self .start_time )
135- super ().save (* args , ** kwargs )
0 commit comments