Files
service-finder/backend/app/schemas/commission.py
2026-07-24 09:56:21 +00:00

139 lines
4.9 KiB
Python

# /opt/docker/dev/service_finder/backend/app/schemas/commission.py
"""
Pydantic schemas for CommissionRule CRUD operations.
THOUGHT PROCESS:
- CommissionRuleCreate: All fields required for creating a new rule.
Uses Optional for type-specific fields (L1 vs L2).
- CommissionRuleUpdate: All fields optional for partial updates.
- CommissionRuleResponse: Full read model with from_attributes=True
for ORM compatibility.
- CommissionRuleListResponse: Paginated wrapper for admin listing.
"""
from pydantic import BaseModel, Field
from datetime import date, datetime
from typing import Optional, List
from enum import Enum
class CommissionRuleTypeEnum(str, Enum):
"""Jutalék típus: L1 = egyéni jutalom, L2 = céges jutalék."""
L1_REWARD = "L1_REWARD"
L2_COMMISSION = "L2_COMMISSION"
class CommissionTierEnum(str, Enum):
"""Jutalék szintek."""
STANDARD = "STANDARD"
VIP = "VIP"
PLATINUM = "PLATINUM"
ENTERPRISE = "ENTERPRISE"
CONTRACTED = "CONTRACTED"
class CommissionRuleCreate(BaseModel):
"""Schema új jutalék szabály létrehozásához."""
rule_type: CommissionRuleTypeEnum
tier: CommissionTierEnum = CommissionTierEnum.STANDARD
region_code: str = "GLOBAL"
xp_reward: Optional[int] = None
credit_reward: Optional[int] = None
commission_percent: Optional[float] = None
upline_commission_percent: Optional[float] = None
renewal_commission_percent: Optional[float] = None
commission_max_amount: Optional[float] = None
is_campaign: bool = False
start_date: Optional[date] = None
end_date: Optional[date] = None
name: str
description: Optional[str] = None
is_active: bool = True
class CommissionRuleUpdate(BaseModel):
"""Schema meglévő jutalék szabály módosításához (minden mező opcionális)."""
rule_type: Optional[CommissionRuleTypeEnum] = None
tier: Optional[CommissionTierEnum] = None
region_code: Optional[str] = None
xp_reward: Optional[int] = None
credit_reward: Optional[int] = None
commission_percent: Optional[float] = None
upline_commission_percent: Optional[float] = None
renewal_commission_percent: Optional[float] = None
commission_max_amount: Optional[float] = None
is_campaign: Optional[bool] = None
start_date: Optional[date] = None
end_date: Optional[date] = None
name: Optional[str] = None
description: Optional[str] = None
is_active: Optional[bool] = None
class CommissionRuleResponse(BaseModel):
"""Schema jutalék szabály adatainak lekéréséhez."""
id: int
rule_type: CommissionRuleTypeEnum
tier: CommissionTierEnum
region_code: str
xp_reward: Optional[int] = None
credit_reward: Optional[int] = None
commission_percent: Optional[float] = None
upline_commission_percent: Optional[float] = None
renewal_commission_percent: Optional[float] = None
commission_max_amount: Optional[float] = None
is_campaign: bool
start_date: Optional[date] = None
end_date: Optional[date] = None
name: str
description: Optional[str] = None
is_active: bool
created_by: Optional[int] = None
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
class CommissionRuleListResponse(BaseModel):
"""Paginated list response for admin commission rules."""
items: List[CommissionRuleResponse]
total: int
page: int
page_size: int
class CommissionDistributionRequest(BaseModel):
"""
Request schema for the 2-level MLM commission distribution engine.
When a referred company makes a purchase, this request triggers the
distribution logic:
- Gen1 (direct referrer) receives commission_percent
- Gen2 (upline / Gen1's referrer) receives upline_commission_percent
"""
buyer_user_id: int = Field(..., description="The user ID who made the purchase")
transaction_amount: float = Field(..., gt=0, description="The purchase/subscription amount")
transaction_date: date = Field(..., description="Date of the transaction")
region_code: str = Field("GLOBAL", max_length=10, description="Region code for rule matching")
class CommissionDistributionItem(BaseModel):
"""Single commission payout item for one level."""
level: int = Field(..., description="1 = Gen1 (direct referrer), 2 = Gen2 (upline)")
user_id: int = Field(..., description="The user ID receiving the commission")
commission_percent: float = Field(..., description="The applied commission percentage")
commission_amount: float = Field(..., description="The calculated commission amount")
rule_id: int = Field(..., description="The CommissionRule ID that was applied")
class CommissionDistributionResponse(BaseModel):
"""
Response schema for the 2-level MLM commission distribution.
Contains the payout breakdown for both Gen1 and Gen2 levels.
"""
transaction_amount: float
items: List[CommissionDistributionItem]
total_commission: float = Field(..., description="Sum of all commission payouts")