start the django

This commit is contained in:
Ross
2025-12-09 10:01:04 +00:00
parent a230c9d94c
commit 4927697621
14 changed files with 511 additions and 7 deletions
+113 -1
View File
@@ -1,3 +1,115 @@
from django.db import models
from django.utils import timezone
# Create your models here.
class RotaSchedule(models.Model):
"""Represents a named rota (collection of shifts over a date range).
This is the top-level object that groups workers and runs.
"""
name = models.CharField(max_length=200, unique=True)
start_date = models.DateField()
end_date = models.DateField()
description = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Worker(models.Model):
"""Worker / staff member that can be assigned to one or more rotas."""
name = models.CharField(max_length=200)
email = models.EmailField(blank=True)
site = models.CharField(max_length=100, blank=True)
grade = models.IntegerField(null=True, blank=True)
fte = models.FloatField(default=1.0)
active = models.BooleanField(default=True)
rotas = models.ManyToManyField(RotaSchedule, through="Assignment", related_name="workers")
def __str__(self):
return self.name
class Assignment(models.Model):
"""Join model assigning a worker to a rota (can hold role / metadata)."""
worker = models.ForeignKey(Worker, on_delete=models.CASCADE)
rota = models.ForeignKey(RotaSchedule, on_delete=models.CASCADE)
role = models.CharField(max_length=100, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ("worker", "rota")
def __str__(self):
return f"{self.worker} -> {self.rota}"
class Leave(models.Model):
"""Leave record for a worker. Stored as inclusive start/end dates."""
worker = models.ForeignKey(Worker, on_delete=models.CASCADE, related_name="leaves")
start_date = models.DateField()
end_date = models.DateField()
reason = models.CharField(max_length=255, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ("-start_date",)
def __str__(self):
return f"{self.worker}: {self.start_date}{self.end_date}"
class RotaRun(models.Model):
"""Represents an execution of the scheduler for a RotaSchedule.
The run stores status and (optionally) JSON results. A background
runner or management command can update this record as the job progresses.
"""
STATUS_PENDING = "pending"
STATUS_RUNNING = "running"
STATUS_SUCCESS = "success"
STATUS_FAILED = "failed"
STATUS_CHOICES = [
(STATUS_PENDING, "Pending"),
(STATUS_RUNNING, "Running"),
(STATUS_SUCCESS, "Success"),
(STATUS_FAILED, "Failed"),
]
rota = models.ForeignKey(RotaSchedule, on_delete=models.CASCADE, related_name="runs")
created_at = models.DateTimeField(auto_now_add=True)
started_at = models.DateTimeField(null=True, blank=True)
finished_at = models.DateTimeField(null=True, blank=True)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_PENDING)
result = models.JSONField(null=True, blank=True)
log = models.TextField(blank=True)
def mark_running(self):
self.status = self.STATUS_RUNNING
self.started_at = timezone.now()
self.save(update_fields=["status", "started_at"])
def mark_finished(self, result=None):
self.status = self.STATUS_SUCCESS
self.finished_at = timezone.now()
if result is not None:
self.result = result
self.save(update_fields=["status", "finished_at", "result"])
def mark_failed(self, message=""):
self.status = self.STATUS_FAILED
self.finished_at = timezone.now()
self.log = (self.log or "") + "\n" + message
self.save(update_fields=["status", "finished_at", "log"])
def __str__(self):
return f"RotaRun({self.rota.name} - {self.status} @ {self.created_at.isoformat()})"