Vorrat: Mindestbestand, Sortierung nach Laden, Rezeptsammlung mit Vorschlägen
- Mindestbestand pro Liste/Produkt/Einheit (Tabelle stock_minimums): fällt der Vorrat darunter, füllt der Server die Einkaufsliste genau bis zur fehlenden Menge auf (nach Ändern, Aufgebraucht, Löschen, Setzen) - Laden-Kategorien (kategorien.py): automatische Zuordnung über Stichwörter (längstes Stichwort gewinnt), änderbar in der Zeile und im Vorschläge-Dialog; Einkaufsliste "A–Z" oder "Nach Laden" gruppiert; Reihenfolge der Abteilungen pro Liste - Rezeptsammlung (Tabelle recipes): "☆ Merken" beim Abgleich, "Was kann ich kochen?" sortiert gemerkte Rezepte nach vorhandenen Zutaten (Salz & Co. zählen nicht, nur sichtbare Produkte), vollständiger Abgleich per Klick - Migration Schritt 3 (Kategorien für bestehende Produkte); _add_column für Tabellen, die SCHEMA in alten Datenbanken schon neu angelegt hat - Tests in test_vorrat_extras.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9df0e38f52
commit
9835f5e69e
15 files changed
+879
-40
No files matched your search
@@ -4,6 +4,8 @@ SCHEMA in db.py beschreibt immer den neuesten Stand. Bei einer Änderung am Sche
|
||||
1. SCHEMA in db.py anpassen – neue Datenbanken entstehen direkt so und bekommen die höchste Nummer.
|
||||
2. Unten an STEPS eine Funktion anhängen, die eine bestehende Datenbank vom vorigen Stand dorthin bringt.
|
||||
Jeder Schritt läuft genau einmal, in einer Transaktion mit dem Hochzählen der Nummer.
|
||||
Achtung: Eine Tabelle, die es in einer alten Datenbank noch gar nicht gab, legt SCHEMA schon in der
|
||||
neuesten Form an. Spalten deshalb mit _add_column() ergänzen (fügt nur hinzu, was fehlt).
|
||||
Tests: tests/test_migrationen.py (alte Stände nachbauen und umstellen).
|
||||
"""
|
||||
import logging
|
||||
@@ -14,6 +16,7 @@ from .common import ValidationError, now_iso
|
||||
from .config import DATA_DIR
|
||||
from .db import HOUSEHOLD_TABLE, KANBAN_PROJECTS_TABLE, KANBAN_TASKS_TABLE
|
||||
from .htmlclean import sanitize
|
||||
from .kategorien import guess
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -32,6 +35,12 @@ def upgrade(conn) -> None:
|
||||
conn.execute(f"PRAGMA user_version = {number}")
|
||||
|
||||
|
||||
def _add_column(conn, table: str, column: str, definition: str) -> None:
|
||||
"""Spalte ergänzen, falls sie fehlt (table/column/definition stammen nur aus diesem Modul)."""
|
||||
if column not in {r["name"] for r in conn.execute(f"PRAGMA table_info({table})")}:
|
||||
conn.execute(f"ALTER TABLE {table} ADD COLUMN {column} {definition}")
|
||||
|
||||
|
||||
def _rebuild(conn, table: str, definition: str, columns: str, select: str, params=()) -> None:
|
||||
"""Tabelle neu aufbauen: neue Tabelle unter Zwischennamen anlegen, Daten kopieren, alte löschen, umbenennen.
|
||||
|
||||
@@ -229,8 +238,20 @@ def _v2_datenschutz(conn) -> None:
|
||||
log.warning("Bild %s konnte nicht bereinigt werden: %s", f.name, e)
|
||||
|
||||
|
||||
# ---------- Schritt 3: Laden-Kategorien ----------
|
||||
|
||||
|
||||
def _v3_kategorien(conn) -> None:
|
||||
"""Produkte bekommen eine Laden-Kategorie (geraten), Listen eine eigene Kategorie-Reihenfolge."""
|
||||
_add_column(conn, "products", "category", "TEXT")
|
||||
_add_column(conn, "shopping_lists", "category_order", "TEXT")
|
||||
for row in conn.execute("SELECT key, name FROM products").fetchall():
|
||||
conn.execute("UPDATE products SET category = ? WHERE key = ?", (guess(row["name"]), row["key"]))
|
||||
|
||||
|
||||
# Reihenfolge = Versionsnummer (Index + 1). Nur anhängen, nie umsortieren oder entfernen.
|
||||
STEPS = [
|
||||
_v1_altbestand,
|
||||
_v2_datenschutz,
|
||||
_v3_kategorien,
|
||||
]
|
||||
Reference in new issue
Block a user