This commit is contained in:
2025-09-28 19:13:01 +02:00
parent 49edf780b5
commit 541ecb48f2
67 changed files with 5176 additions and 5008 deletions

View File

@@ -0,0 +1,29 @@
from datetime import datetime
from typing import Optional
# Pydantic v1/v2 Kompatibilität
try:
from pydantic import BaseModel, ConfigDict # v2
_V2 = True
except ImportError: # v1
from pydantic import BaseModel # type: ignore
_V2 = False
class AuditLogOut(BaseModel):
id: int
user_id: Optional[int] = None
timestamp: Optional[datetime] = None
# WICHTIG: frei als String, kein zu enges Enum -> verhindert ResponseValidationError
action: str
info: Optional[str] = None
old_balance_cents: Optional[int] = None
new_balance_cents: Optional[int] = None
if _V2:
# Pydantic v2
model_config = ConfigDict(from_attributes=True)
else:
# Pydantic v1
class Config:
orm_mode = True

View File

@@ -0,0 +1,19 @@
from pydantic import BaseModel
from datetime import datetime
class BookingBase(BaseModel):
user_id: int
product_id: int
amount: int
total_cents: int
comment: str | None = None
class BookingCreate(BookingBase):
pass
class BookingOut(BookingBase):
id: int
timestamp: datetime
class Config:
from_attributes = True # Pydantic V2

View File

@@ -0,0 +1,38 @@
from pydantic import BaseModel, ConfigDict
from datetime import date, datetime
from typing import Optional, List
# Bestehendes Einzeilen-Schema bleibt
class DeliveryBase(BaseModel):
product_id: int
amount: int
price_cents: int
delivered_at: Optional[date] = None
supplier: Optional[str] = None
invoice_number: Optional[str] = None
created_by: Optional[int] = None
note: str | None = None
deposit_return_cents: int = 0
model_config = ConfigDict(from_attributes=True) # statt orm_mode
class DeliveryCreate(DeliveryBase):
pass
class DeliveryOut(DeliveryBase):
id: int
class Config:
from_attributes = True
# 🆕 Für die neue Seite (Header + Items + Pfand)
class DeliveryItemIn(BaseModel):
product_id: int
quantity_units: int
unit_cost_cents: int
class DeliveryCreateBulk(BaseModel):
supplier: Optional[str] = None
date: Optional[date] = None
invoice_no: Optional[str] = None
note: Optional[str] = None
deposit_return_cents: int = 0 # Netto-Pfand (Cent, positiv)
items: List[DeliveryItemIn]

View File

@@ -0,0 +1,28 @@
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
class ProductBase(BaseModel):
name: str
price_cents: int # Verkaufspreis (falls genutzt)
purchase_price_cents: int = 0 # 🆕 EK je Einheit (Cent)
pack_size: int = 1 # 🆕 6, 12, 24 ...
supplier_number: Optional[str] = None
volume_ml: Optional[int] = None
category: Optional[str] = None
stock: int = 0 # Default sinnvoller
is_active: bool = True # Default sinnvoller
class ProductCreate(ProductBase):
pass
class ProductUpdate(ProductBase):
pass
class ProductOut(ProductBase):
id: int
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True

View File

@@ -0,0 +1,32 @@
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
from enum import Enum
class TopupStatus(str, Enum):
pending = "pending"
confirmed = "confirmed"
rejected = "rejected"
# Für Ausgaben und Admin-Create weiterhin kompatibel:
class TopupBase(BaseModel):
user_id: Optional[int] = None # <- optional gemacht
amount_cents: int
paypal_email: Optional[str] = None
note: Optional[str] = None
class TopupCreate(TopupBase):
# user_id kann für Admin-Aufrufe gesetzt werden, für User-Create weggelassen
pass
class TopupStatusUpdate(BaseModel):
status: TopupStatus
class TopupOut(TopupBase):
id: int
status: TopupStatus
created_at: datetime
confirmed_at: Optional[datetime] = None
class Config:
from_attributes = True # pydantic v2 (ersetzt orm_mode)

View File

@@ -0,0 +1,46 @@
from pydantic import BaseModel, EmailStr, constr
from typing import Optional, List
from enum import Enum
class UserRole(str, Enum):
user = "user"
manager = "manager"
admin = "admin"
class UserOut(BaseModel):
id: int
name: str
email: EmailStr
alias: Optional[str] = None
paypal_email: Optional[EmailStr] = None
role: UserRole
is_active: bool
balance_cents: int
favorites: List[int]
# NEU:
avatar_url: Optional[str] = None
public_stats: bool
class Config:
orm_mode = True
class UserCreate(BaseModel):
name: str
email: EmailStr
password: constr(min_length=8)
pin: constr(min_length=6, max_length=6)
alias: Optional[str] = None
paypal_email: Optional[EmailStr] = None
role: Optional[UserRole] = UserRole.user
class UserUpdate(BaseModel):
name: Optional[str] = None
email: Optional[EmailStr] = None
password: Optional[constr(min_length=8)] = None
pin: Optional[constr(min_length=6, max_length=6)] = None
alias: Optional[str] = None
paypal_email: Optional[EmailStr] = None
role: Optional[UserRole] = None
is_active: Optional[bool] = None
balance_cents: Optional[int] = None
favorites: Optional[List[int]] = None