Files
kakebo/app/monthly/models.py
Andros Fenollosa 051a69cf7d Add Month end section with weekly breakdown and self-assessment
- Weekly expenses table (Week #1-5 + Total)
- Budget result: initial budget - expenses = savings
- Category breakdown by week
- Self-assessment: goals, promises, savings (radio Yes/No/Almost)
- Reflection textarea with auto-save
- Assessment auto-saves on change via LiveView
2026-03-18 15:23:03 +01:00

84 lines
2.1 KiB
Python

from django.db import models
class Income(models.Model):
date = models.DateField()
concept = models.CharField(max_length=255)
amount = models.DecimalField(max_digits=10, decimal_places=2)
class Meta:
ordering = ["date"]
def __str__(self):
return f"{self.concept} - {self.amount}"
class MonthlyFixedExpense(models.Model):
year = models.PositiveIntegerField()
month = models.PositiveSmallIntegerField()
concept = models.ForeignKey(
"expenses.FixedExpenseConcept",
on_delete=models.CASCADE,
related_name="monthly_entries",
)
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
class Meta:
unique_together = ["year", "month", "concept"]
ordering = ["concept__order"]
def __str__(self):
return f"{self.concept.name} - {self.amount}"
class MonthlyGoal(models.Model):
GOAL = "goal"
PROMISE = "promise"
TYPE_CHOICES = [
(GOAL, "Goal"),
(PROMISE, "Promise"),
]
year = models.PositiveIntegerField()
month = models.PositiveSmallIntegerField()
text = models.CharField(max_length=500)
kind = models.CharField(max_length=10, choices=TYPE_CHOICES)
done = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["created_at"]
def __str__(self):
return f"{self.text} ({'done' if self.done else 'pending'})"
class MonthlyNote(models.Model):
ASSESSMENT_CHOICES = [
("", "---"),
("yes", "Yes"),
("no", "No"),
("almost", "Almost"),
]
year = models.PositiveIntegerField()
month = models.PositiveSmallIntegerField()
text = models.TextField(blank=True, default="")
savings_target = models.DecimalField(max_digits=10, decimal_places=2, default=0)
goals_achieved = models.CharField(
max_length=10, blank=True, default="", choices=ASSESSMENT_CHOICES
)
promises_kept = models.CharField(
max_length=10, blank=True, default="", choices=ASSESSMENT_CHOICES
)
savings_kept = models.CharField(
max_length=10, blank=True, default="", choices=ASSESSMENT_CHOICES
)
reflection = models.TextField(blank=True, default="")
class Meta:
unique_together = ["year", "month"]
def __str__(self):
return f"{self.year}/{self.month:02d}"