Bisher war die Auswahl eine fest im Frontend verdrahtete Liste und es gab nur eine Form: ueberall stand "3 Glas". Neu unter Verwaltung > Gebinde: anlegen, umbenennen, loeschen, jeweils mit Einzahl und Mehrzahl. Die eingebauten Gebinde lassen sich in der Schreibweise aendern, aber nicht loeschen; ein Gebinde, das ein Artikel verwendet, ebenfalls nicht. Der Artikel speichert weiterhin nur die Einzahl als Text - so bleiben vorhandene Artikel, Sicherungen und CSV-Dateien gueltig, und eine unbekannte Bezeichnung faellt schlicht auf die Einzahl zurueck. Deshalb zieht ein Umbenennen die Artikel mit; sonst zeigten sie auf eine Bezeichnung, die es nicht mehr gibt. Die Mehrzahl greift jetzt in Artikelliste, Artikelseite (Chargen und Gebinde- Auswahl), Auslagern und in allen Ablauf- und Einkaufslisten samt Startseite. Einheiten wie Gramm oder Liter bleiben unveraendert - die haben im Deutschen keine Mehrzahl. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
111 lines
3.6 KiB
Python
111 lines
3.6 KiB
Python
"""Startup-Seeds: erster Admin-Benutzer und die eingebauten Einheiten."""
|
||
|
||
from sqlalchemy.orm import Session
|
||
|
||
from .config import get_settings
|
||
from .models import Category, PackageType, Role, Unit, UnitKind, User
|
||
from .security import hash_password
|
||
|
||
# (Name, Art, Faktor zur kanonischen Basiseinheit)
|
||
BUILTIN_UNITS: list[tuple[str, UnitKind, float]] = [
|
||
("Stück", UnitKind.count, 1.0),
|
||
("Gramm", UnitKind.weight, 1.0),
|
||
("Kilogramm", UnitKind.weight, 1000.0),
|
||
("Milliliter", UnitKind.volume, 1.0),
|
||
("Liter", UnitKind.volume, 1000.0),
|
||
]
|
||
|
||
|
||
# Gebinde in Einzahl und Mehrzahl. Bewusst nur die gaengigen - eigene legt man
|
||
# unter Verwaltung > Gebinde an. Wo Einzahl und Mehrzahl gleich lauten
|
||
# ("2 Becher"), steht das hier ausdruecklich, damit es niemand fuer vergessen
|
||
# haelt und "Bechers" daraus macht.
|
||
BUILTIN_PACKAGE_TYPES: list[tuple[str, str]] = [
|
||
("Packung", "Packungen"),
|
||
("Glas", "Gläser"),
|
||
("Flasche", "Flaschen"),
|
||
("Dose", "Dosen"),
|
||
("Tüte", "Tüten"),
|
||
("Beutel", "Beutel"),
|
||
("Becher", "Becher"),
|
||
("Tube", "Tuben"),
|
||
("Karton", "Kartons"),
|
||
("Riegel", "Riegel"),
|
||
("Rolle", "Rollen"),
|
||
("Sack", "Säcke"),
|
||
("Kiste", "Kisten"),
|
||
("Bund", "Bund"),
|
||
("Stück", "Stück"),
|
||
]
|
||
|
||
|
||
def ensure_builtin_package_types(db: Session) -> None:
|
||
changed = False
|
||
for singular, plural in BUILTIN_PACKAGE_TYPES:
|
||
if not db.query(PackageType).filter(PackageType.singular == singular).first():
|
||
db.add(PackageType(singular=singular, plural=plural, is_builtin=True))
|
||
changed = True
|
||
if changed:
|
||
db.commit()
|
||
|
||
|
||
def ensure_builtin_units(db: Session) -> None:
|
||
changed = False
|
||
for name, kind, factor in BUILTIN_UNITS:
|
||
if not db.query(Unit).filter(Unit.name == name).first():
|
||
db.add(Unit(name=name, kind=kind, factor=factor, is_builtin=True))
|
||
changed = True
|
||
if changed:
|
||
db.commit()
|
||
|
||
|
||
# Startliste für den Überblick über den Vorrat. Zweistufig, damit die
|
||
# Verschachtelung von Anfang an sichtbar ist. Alles frei änderbar –
|
||
# umbenennen, löschen und eigene ergänzen ist ausdrücklich vorgesehen.
|
||
BUILTIN_CATEGORIES: list[tuple[str, list[str]]] = [
|
||
("Obst & Gemüse", []),
|
||
("Molkereiprodukte", ["Käse", "Joghurt & Quark"]),
|
||
("Fleisch & Fisch", []),
|
||
("Brot & Backwaren", []),
|
||
("Trockenwaren & Teigwaren", ["Mehl & Zucker", "Nudeln & Reis"]),
|
||
("Konserven & Gläser", []),
|
||
("Tiefkühl", []),
|
||
("Süßwaren & Snacks", ["Schokolade", "Chips & Salziges"]),
|
||
("Getränke", ["Kaffee & Tee"]),
|
||
("Gewürze & Saucen", []),
|
||
("Frühstück", []),
|
||
("Haushalt & Hygiene", []),
|
||
]
|
||
|
||
|
||
def ensure_builtin_categories(db: Session) -> None:
|
||
"""Legt nur an, was fehlt – gelöschte Kategorien kommen nicht zurück.
|
||
|
||
Anders als bei den Einheiten prüfen wir zusätzlich, ob überhaupt schon
|
||
Kategorien existieren: Wer die Startliste bewusst leergeräumt hat, soll sie
|
||
beim nächsten Start nicht wiederfinden.
|
||
"""
|
||
if db.query(Category).first() is not None:
|
||
return
|
||
for name, children in BUILTIN_CATEGORIES:
|
||
parent = Category(name=name, is_builtin=True)
|
||
db.add(parent)
|
||
db.flush()
|
||
for child in children:
|
||
db.add(Category(name=child, parent_id=parent.id, is_builtin=True))
|
||
db.commit()
|
||
|
||
|
||
def ensure_first_admin(db: Session) -> None:
|
||
settings = get_settings()
|
||
has_users = db.query(User).first() is not None
|
||
if has_users:
|
||
return
|
||
admin = User(
|
||
username=settings.admin_username,
|
||
password_hash=hash_password(settings.admin_password),
|
||
role=Role.admin,
|
||
)
|
||
db.add(admin)
|
||
db.commit()
|