Louis Mazin d424689e12 big maj
2026-09-24 19:35:37 +02:00

121 lines
2.7 KiB
Python

from datetime import datetime
from django.conf import settings
from django.db import models
class TimeEntry(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='time_entries',
)
# Même group_id = même pointage logique réparti sur plusieurs jours.
# NULL pour les pointages classiques sur une seule journée.
group_id = models.UUIDField(
null=True,
blank=True,
db_index=True,
)
start_date = models.DateField()
start_time = models.TimeField()
# Chaque ligne représente une seule journée.
# Pour une entrée classique :
# start_date = end_date
#
# Pour un pointage multi-jours :
# une ligne par jour, toutes liées par group_id.
end_date = models.DateField()
end_time = models.TimeField(
null=True,
blank=True,
)
created_at = models.DateTimeField(
auto_now_add=True,
)
updated_at = models.DateTimeField(
auto_now=True,
)
class Meta:
ordering = ['-start_date', '-start_time']
constraints = [
models.UniqueConstraint(
fields=[
'user',
'start_date',
'start_time',
],
name='unique_time_entry_start',
),
]
def __str__(self):
if self.end_time:
return (
f"{self.user.username} - "
f"{self.start_date} "
f"({self.start_time} → {self.end_time})"
)
return (
f"{self.user.username} - "
f"{self.start_date} "
f"({self.start_time} → en cours)"
)
@property
def duration(self):
"""
Durée de CETTE ligne.
Chaque TimeEntry représente une seule journée.
Les différentes journées d'un même pointage sont reliées
par group_id.
"""
if not self.start_time or not self.end_time:
return None
end_date = self.end_date or self.start_date
start = datetime.combine(
self.start_date,
self.start_time,
)
end = datetime.combine(
end_date,
self.end_time,
)
seconds = (
end - start
).total_seconds()
if seconds < 0:
return None
return seconds / 3600
@property
def day_of_week(self):
return self.start_date.strftime('%A')
@property
def is_complete(self):
return bool(
self.start_time
and self.end_time
)
@property
def is_incomplete(self):
return not self.is_complete