6 changed files with 115 additions and 5 deletions
@ -0,0 +1,40 @@
|
||||
# Generated manually because the container image has no write access to the workspace. |
||||
|
||||
import django.db.models.deletion |
||||
import uuid |
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [("finance", "0003_reconciliationcheckpoint")] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name="Tag", |
||||
fields=[ |
||||
("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), |
||||
("created_at", models.DateTimeField(auto_now_add=True)), |
||||
("updated_at", models.DateTimeField(auto_now=True)), |
||||
("name", models.CharField(max_length=255, unique=True)), |
||||
("archived", models.BooleanField(default=False)), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name="CategoryGroup", |
||||
fields=[ |
||||
("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), |
||||
("created_at", models.DateTimeField(auto_now_add=True)), |
||||
("updated_at", models.DateTimeField(auto_now=True)), |
||||
("name", models.CharField(max_length=255, unique=True)), |
||||
("archived", models.BooleanField(default=False)), |
||||
], |
||||
), |
||||
migrations.AlterField(model_name="category", name="name", field=models.CharField(max_length=255)), |
||||
migrations.AddField(model_name="category", name="group", field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name="categories", to="finance.categorygroup")), |
||||
migrations.AddConstraint(model_name="categorygroup", constraint=models.CheckConstraint(condition=models.Q(("name__regex", "\\S")), name="category_group_nonblank_name")), |
||||
migrations.AddConstraint(model_name="tag", constraint=models.CheckConstraint(condition=models.Q(("name__regex", "\\S")), name="tag_nonblank_name")), |
||||
migrations.AddConstraint(model_name="category", constraint=models.UniqueConstraint(fields=("group", "name"), name="category_group_name_unique")), |
||||
migrations.AddConstraint(model_name="category", constraint=models.UniqueConstraint(condition=models.Q(("group__isnull", True)), fields=("name",), name="category_ungrouped_name_unique")), |
||||
migrations.AddField(model_name="transaction", name="tags", field=models.ManyToManyField(blank=True, related_name="transactions", to="finance.tag")), |
||||
] |
||||
@ -1,9 +1,9 @@
|
||||
from .ledger import CardStatement, InstallmentPlan, Transaction, Transfer |
||||
from .provenance import AuditEvent, SourceRecord |
||||
from .reconciliation import ReconciliationCheckpoint |
||||
from .reference import Account, Category, Payee |
||||
from .reference import Account, Category, CategoryGroup, Payee, Tag |
||||
|
||||
__all__ = [ |
||||
"Account", "AuditEvent", "CardStatement", "Category", "InstallmentPlan", |
||||
"Payee", "ReconciliationCheckpoint", "SourceRecord", "Transaction", "Transfer", |
||||
"Account", "AuditEvent", "CardStatement", "Category", "CategoryGroup", "InstallmentPlan", |
||||
"Payee", "ReconciliationCheckpoint", "SourceRecord", "Tag", "Transaction", "Transfer", |
||||
] |
||||
|
||||
@ -0,0 +1,41 @@
|
||||
from datetime import date |
||||
from decimal import Decimal |
||||
|
||||
import pytest |
||||
|
||||
from finance.models import Account, Category, Tag, Transaction |
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db |
||||
|
||||
|
||||
def test_ungrouped_categories_and_transaction_links_remain_valid(): |
||||
account = Account.objects.create(name="Synthetic bank", kind="BANK") |
||||
category = Category.objects.create(name="Synthetic Food", kind="EXPENSE") |
||||
transaction = Transaction.objects.create( |
||||
account=account, |
||||
amount=Decimal("-10.00"), |
||||
posting_date=date(2026, 9, 14), |
||||
kind="EXPENSE", |
||||
category=category, |
||||
) |
||||
|
||||
category.refresh_from_db() |
||||
|
||||
assert category.group_id is None |
||||
assert transaction.category_id == category.pk |
||||
|
||||
|
||||
def test_tags_can_be_attached_without_changing_category(): |
||||
account = Account.objects.create(name="Synthetic bank", kind="BANK") |
||||
transaction = Transaction.objects.create( |
||||
account=account, |
||||
amount=Decimal("-10.00"), |
||||
posting_date=date(2026, 9, 14), |
||||
kind="EXPENSE", |
||||
) |
||||
tag = Tag.objects.create(name="Synthetic Tax") |
||||
|
||||
transaction.tags.add(tag) |
||||
|
||||
assert list(transaction.tags.all()) == [tag] |
||||
Loading…
Reference in new issue