Files

72 lines
2.5 KiB
Python
Raw Permalink Normal View History

2026-03-05 12:13:22 -06:00
from .extensions import db
2026-03-12 10:23:22 -05:00
from datetime import datetime, date, timezone
2026-03-05 12:13:22 -06:00
2026-03-06 00:03:06 -06:00
2026-03-05 12:13:22 -06:00
class Project(db.Model):
__tablename__ = 'projects'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(200), nullable=False)
color = db.Column(db.String(7), nullable=False, default='#C9A84C')
description = db.Column(db.Text)
2026-03-05 13:28:07 -06:00
drive_url = db.Column(db.String(500))
2026-03-06 00:03:06 -06:00
archived_at = db.Column(db.DateTime, nullable=True)
2026-03-12 10:23:22 -05:00
created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
2026-03-05 12:13:22 -06:00
deliverables = db.relationship(
2026-03-06 00:03:06 -06:00
'Deliverable',
backref='project',
cascade='all, delete-orphan',
lazy=True,
2026-03-05 12:13:22 -06:00
)
def to_dict(self, include_deliverables=True):
data = {
'id': self.id,
'name': self.name,
'color': self.color,
'description': self.description,
2026-03-05 13:28:07 -06:00
'drive_url': self.drive_url,
2026-03-06 00:03:06 -06:00
'archived_at': self.archived_at.isoformat() if self.archived_at else None,
2026-03-05 12:13:22 -06:00
'created_at': self.created_at.isoformat() if self.created_at else None,
}
if include_deliverables:
data['deliverables'] = [
d.to_dict() for d in sorted(self.deliverables, key=lambda x: x.due_date)
]
return data
class Deliverable(db.Model):
__tablename__ = 'deliverables'
id = db.Column(db.Integer, primary_key=True)
2026-03-06 00:03:06 -06:00
project_id = db.Column(
db.Integer,
db.ForeignKey('projects.id', ondelete='CASCADE'),
nullable=False,
)
2026-03-05 12:13:22 -06:00
title = db.Column(db.String(300), nullable=False)
due_date = db.Column(db.Date, nullable=False)
status = db.Column(db.String(20), nullable=False, default='upcoming')
2026-03-12 10:23:22 -05:00
created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
2026-03-05 12:13:22 -06:00
2026-03-05 16:58:36 -06:00
def effective_status(self):
"""
2026-03-06 00:03:06 -06:00
Returns 'overdue' if the due date has passed and the deliverable has not been
marked completed. Completed deliverables are never auto-downgraded.
2026-03-05 16:58:36 -06:00
"""
if self.status != 'completed' and self.due_date < date.today():
return 'overdue'
return self.status
2026-03-05 12:13:22 -06:00
def to_dict(self):
return {
'id': self.id,
'project_id': self.project_id,
'title': self.title,
'due_date': self.due_date.isoformat() if self.due_date else None,
2026-03-05 16:58:36 -06:00
'status': self.effective_status(),
2026-03-05 12:13:22 -06:00
'created_at': self.created_at.isoformat() if self.created_at else None,
}