Add savings account flag and budget block model
This commit is contained in:
parent
40b0c7ed7b
commit
e64421b3df
@ -0,0 +1,34 @@
|
||||
# Generated by Django 5.2.10 on 2026-10-18 14:51
|
||||
|
||||
import django.core.validators
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('expenses', '0018_category_expense_type'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='account',
|
||||
name='is_savings',
|
||||
field=models.BooleanField(default=False, help_text='Márcala si es una cuenta donde guardas dinero: los traspasos que entran en ella cuentan como ahorro en el reparto por bloques.', verbose_name='Cuenta de ahorro'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BudgetBlock',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('block', models.CharField(choices=[('fixed_essential', 'Fijo esencial'), ('fixed_discretionary', 'Fijo prescindible'), ('variable_essential', 'Variable esencial'), ('variable_discretionary', 'Variable prescindible'), ('saving', 'Ahorro')], max_length=30)),
|
||||
('percentage', models.DecimalField(decimal_places=2, default=0, max_digits=5, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
|
||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='budget_blocks', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('owner', 'block')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -1,6 +1,7 @@
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
from django.db import models, transaction
|
||||
from django.conf import settings
|
||||
from django.db.models import Q, Sum
|
||||
@ -114,6 +115,14 @@ class Account(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
initial_balance = models.DecimalField(max_digits=12, decimal_places=2, default=0)
|
||||
active = models.BooleanField(default=True)
|
||||
is_savings = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="Cuenta de ahorro",
|
||||
help_text=(
|
||||
"Márcala si es una cuenta donde guardas dinero: los traspasos que "
|
||||
"entran en ella cuentan como ahorro en el reparto por bloques."
|
||||
),
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
@ -823,3 +832,35 @@ class Goal(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class BudgetBlock(models.Model):
|
||||
"""Qué porcentaje del ingreso debería ir a un bloque.
|
||||
|
||||
Los bloques son los cuatro tipos de gasto de Category más el ahorro: lo que
|
||||
el usuario clasificó en sus categorías es lo que ve aquí, sin un tercer eje.
|
||||
|
||||
Un único reparto por usuario, sin versionar por fecha: un histórico obliga
|
||||
a decidir qué reparto aplica a cada mes, y eso se añade el día que haga
|
||||
falta. Un bloque sin fila vale 0.
|
||||
"""
|
||||
|
||||
BLOCK_SAVING = "saving"
|
||||
BLOCK_CHOICES = Category.EXPENSE_TYPE_CHOICES + [(BLOCK_SAVING, "Ahorro")]
|
||||
|
||||
owner = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="budget_blocks"
|
||||
)
|
||||
block = models.CharField(max_length=30, choices=BLOCK_CHOICES)
|
||||
percentage = models.DecimalField(
|
||||
max_digits=5,
|
||||
decimal_places=2,
|
||||
default=0,
|
||||
validators=[MinValueValidator(0), MaxValueValidator(100)],
|
||||
)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("owner", "block")
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.get_block_display()}: {self.percentage} %"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user