feat: Zahlungen finden ihren Vertrag von selbst – Preisaenderungen werden gemeldet
Ein Abo stand bisher unverbunden neben seinen Zahlungen. Wer wissen wollte, ob Netflix diesen Monat abgebucht wurde, musste es in der Buchungsliste suchen. Jetzt verknuepft Certain Buchung und Vertrag beim Import selbst. Drei Stufen, bewusst unterschiedlich mutig: - sicher (Betrag und Text passen, Datum im Fenster): wird zugeordnet. - Vorschlag: Betrag passt, Text nicht – oder der Text passt und der Betrag weicht ab. Der zweite Fall ist die Preiserhoehung. - nichts: im Zweifel lieber schweigen. Eine Preiserhoehung wird nie stillschweigend uebernommen. Sie ist eine Nachricht an den Nutzer, kein Wartungsvorgang – er entscheidet, ob der neue Preis der richtige ist. Die Zuordnung ist ein Etikett, keine Umbuchung: die Buchung selbst bleibt unangetastet, und ein geloeschter Vertrag nimmt sie nicht mit. Beim Backup wandern Vertraege nun vor die Buchungen, sonst haenge eine Rueckspielung Zahlungen an die falschen Vertraege. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
41db67f53e
commit
152483707e
@@ -0,0 +1,40 @@
|
||||
"""Welche Buchung zu welchem Vertrag gehoert.
|
||||
|
||||
Bisher wurde der Erkennungstext am Vertrag nur erfasst und lag ungenutzt. Jetzt
|
||||
bekommt die Buchung ein Etikett, das sagt, welcher Vertrag sie ist.
|
||||
|
||||
Ein Etikett, keine Umbuchung: An der Buchung aendert sich nichts. Sie behaelt
|
||||
Betrag, Konto und Kategorie – hier steht nur, dass die beiden zusammengehoeren.
|
||||
Genau wie bei den Uebertrags-Verknuepfungen, und aus demselben Grund: Faellt
|
||||
die Zuordnung falsch aus, zieht man ein Etikett ab und hat keine Buchung
|
||||
verbogen.
|
||||
|
||||
Revision ID: 0034
|
||||
Revises: 0033
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision = "0034"
|
||||
down_revision = "0033"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Ohne batch_alter_table: Eine Spalte anhaengen kann SQLite direkt, und der
|
||||
# Tabellen-Umbau risse ueber ON DELETE CASCADE die Uebertrags-
|
||||
# Verknuepfungen und abgelehnten Vorschlaege mit (tests/test_migrations.py).
|
||||
# Der Fremdschluessel laesst sich so nicht mitschreiben; SQLite prueft ihn
|
||||
# fuer diese Spalte dann nicht. Zu verschmerzen: Die API prueft den Vertrag
|
||||
# ohnehin, und ein verwaister Verweis waere ein Etikett ohne Wirkung, kein
|
||||
# Datenschaden. Die Zuordnung raeumt ihn beim naechsten Lauf weg.
|
||||
op.execute(sa.text("ALTER TABLE transactions ADD COLUMN subscription_id INTEGER"))
|
||||
op.create_index("ix_transactions_subscription_id", "transactions",
|
||||
["subscription_id"])
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index("ix_transactions_subscription_id", table_name="transactions")
|
||||
op.execute(sa.text("ALTER TABLE transactions DROP COLUMN subscription_id"))
|
||||
Reference in New Issue
Block a user