92 lines
3.1 KiB
Python
92 lines
3.1 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from pydantic import BaseModel, ConfigDict
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.auth import require_auth
|
|
from app.db import get_session
|
|
from app.models.tables import Category, CategoryRule
|
|
|
|
router = APIRouter(prefix="/api", tags=["categories"],
|
|
dependencies=[Depends(require_auth)])
|
|
|
|
|
|
class CategoryIn(BaseModel):
|
|
name: str
|
|
|
|
|
|
class CategoryOut(CategoryIn):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
id: int
|
|
|
|
|
|
class CategoryRuleIn(BaseModel):
|
|
pattern: str
|
|
category_id: int
|
|
priority: int = 100
|
|
|
|
|
|
class CategoryRuleOut(CategoryRuleIn):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
id: int
|
|
|
|
|
|
@router.get("/categories", response_model=list[CategoryOut])
|
|
def list_categories(session: Session = Depends(get_session)):
|
|
return [CategoryOut.model_validate(c)
|
|
for c in session.execute(select(Category)).scalars()]
|
|
|
|
|
|
@router.post("/categories", response_model=CategoryOut, status_code=201)
|
|
def create_category(data: CategoryIn, session: Session = Depends(get_session)):
|
|
if session.execute(select(Category).where(Category.name == data.name)).scalar():
|
|
raise HTTPException(409, "Kategorie existiert bereits")
|
|
cat = Category(**data.model_dump())
|
|
session.add(cat)
|
|
session.commit()
|
|
session.refresh(cat)
|
|
return CategoryOut.model_validate(cat)
|
|
|
|
|
|
@router.patch("/categories/{category_id}", response_model=CategoryOut)
|
|
def patch_category(category_id: int, data: CategoryIn,
|
|
session: Session = Depends(get_session)):
|
|
cat = session.get(Category, category_id)
|
|
if cat is None:
|
|
raise HTTPException(404, "Kategorie nicht gefunden")
|
|
clash = session.execute(
|
|
select(Category).where(Category.name == data.name)).scalar()
|
|
if clash is not None and clash.id != category_id:
|
|
raise HTTPException(409, "Kategorie existiert bereits")
|
|
cat.name = data.name
|
|
session.commit()
|
|
session.refresh(cat)
|
|
return CategoryOut.model_validate(cat)
|
|
|
|
|
|
@router.get("/category-rules", response_model=list[CategoryRuleOut])
|
|
def list_category_rules(session: Session = Depends(get_session)):
|
|
rules = session.execute(
|
|
select(CategoryRule).order_by(CategoryRule.priority)).scalars()
|
|
return [CategoryRuleOut.model_validate(r) for r in rules]
|
|
|
|
|
|
@router.post("/category-rules", response_model=CategoryRuleOut, status_code=201)
|
|
def create_category_rule(data: CategoryRuleIn, session: Session = Depends(get_session)):
|
|
if session.get(Category, data.category_id) is None:
|
|
raise HTTPException(404, "Kategorie nicht gefunden")
|
|
rule = CategoryRule(**data.model_dump())
|
|
session.add(rule)
|
|
session.commit()
|
|
session.refresh(rule)
|
|
return CategoryRuleOut.model_validate(rule)
|
|
|
|
|
|
@router.delete("/category-rules/{rule_id}", status_code=204)
|
|
def delete_category_rule(rule_id: int, session: Session = Depends(get_session)):
|
|
rule = session.get(CategoryRule, rule_id)
|
|
if rule is None:
|
|
raise HTTPException(404, "Regel nicht gefunden")
|
|
session.delete(rule)
|
|
session.commit()
|