139 lines
4.9 KiB
Python
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")
|