admin_nyelvi_javítas
This commit is contained in:
@@ -43,12 +43,18 @@ class CommissionRuleCreate(BaseModel):
|
||||
upline_commission_percent: Optional[float] = None
|
||||
renewal_commission_percent: Optional[float] = None
|
||||
commission_max_amount: Optional[float] = None
|
||||
# Phase 2: Szintenkénti plafonok (NULL/0 = korlátlan, fallback: commission_max_amount)
|
||||
gen1_max_amount: Optional[float] = None
|
||||
gen2_max_amount: Optional[float] = None
|
||||
gen2_renewal_percent: 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
|
||||
# Phase 3: Conflict override — admin acknowledges overlapping rule
|
||||
force_override: bool = False
|
||||
|
||||
|
||||
class CommissionRuleUpdate(BaseModel):
|
||||
@@ -62,12 +68,18 @@ class CommissionRuleUpdate(BaseModel):
|
||||
upline_commission_percent: Optional[float] = None
|
||||
renewal_commission_percent: Optional[float] = None
|
||||
commission_max_amount: Optional[float] = None
|
||||
# Phase 2: Szintenkénti plafonok
|
||||
gen1_max_amount: Optional[float] = None
|
||||
gen2_max_amount: Optional[float] = None
|
||||
gen2_renewal_percent: 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
|
||||
# Phase 3: Conflict override — admin acknowledges overlapping rule
|
||||
force_override: bool = False
|
||||
|
||||
|
||||
class CommissionRuleResponse(BaseModel):
|
||||
@@ -82,6 +94,10 @@ class CommissionRuleResponse(BaseModel):
|
||||
upline_commission_percent: Optional[float] = None
|
||||
renewal_commission_percent: Optional[float] = None
|
||||
commission_max_amount: Optional[float] = None
|
||||
# Phase 2: Szintenkénti plafonok
|
||||
gen1_max_amount: Optional[float] = None
|
||||
gen2_max_amount: Optional[float] = None
|
||||
gen2_renewal_percent: Optional[float] = None
|
||||
is_campaign: bool
|
||||
start_date: Optional[date] = None
|
||||
end_date: Optional[date] = None
|
||||
@@ -116,6 +132,8 @@ class CommissionDistributionRequest(BaseModel):
|
||||
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")
|
||||
# Phase 2: Renewal flag - TRUE = renewal transaction, FALSE = first-time purchase
|
||||
is_renewal: bool = Field(False, description="TRUE = renewal transaction, FALSE = first-time purchase")
|
||||
|
||||
|
||||
class CommissionDistributionItem(BaseModel):
|
||||
@@ -136,3 +154,23 @@ class CommissionDistributionResponse(BaseModel):
|
||||
transaction_amount: float
|
||||
items: List[CommissionDistributionItem]
|
||||
total_commission: float = Field(..., description="Sum of all commission payouts")
|
||||
|
||||
|
||||
class ConflictingRuleInfo(BaseModel):
|
||||
"""Information about a conflicting rule returned in a 409 response."""
|
||||
id: int
|
||||
name: str
|
||||
rule_type: CommissionRuleTypeEnum
|
||||
tier: CommissionTierEnum
|
||||
region_code: str
|
||||
is_campaign: bool
|
||||
is_active: bool
|
||||
|
||||
|
||||
class ConflictResponse(BaseModel):
|
||||
"""
|
||||
Response schema returned when a conflicting active rule is detected
|
||||
and force_override was not set.
|
||||
"""
|
||||
detail: str = "A conflicting active rule already exists for this combination."
|
||||
conflicting_rule: ConflictingRuleInfo
|
||||
|
||||
70
backend/app/schemas/financial_manager.py
Normal file
70
backend/app/schemas/financial_manager.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/financial_manager.py
|
||||
"""
|
||||
Pydantic schemas for the FinancialManager API endpoints.
|
||||
|
||||
THOUGHT PROCESS:
|
||||
- PurchaseRequest: Input schema for the package purchase endpoint.
|
||||
- PurchaseResponse: Output schema with full purchase receipt details.
|
||||
- CommissionInfo: Nested schema for commission distribution results.
|
||||
- Separated from commission.py to avoid circular imports and maintain clean boundaries.
|
||||
"""
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List, Any, Dict
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class CommissionItemInfo(BaseModel):
|
||||
"""Single commission payout item in the response."""
|
||||
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")
|
||||
|
||||
|
||||
class CommissionInfo(BaseModel):
|
||||
"""Commission distribution summary in the purchase response."""
|
||||
total_commission: float = Field(..., description="Sum of all commission payouts")
|
||||
items: List[CommissionItemInfo] = Field(default_factory=list, description="Individual commission items")
|
||||
|
||||
|
||||
class PurchaseRequest(BaseModel):
|
||||
"""
|
||||
Request schema for purchasing a subscription package.
|
||||
|
||||
The FinancialManager orchestrates:
|
||||
1. Payment processing (via configured gateway)
|
||||
2. Subscription activation (User or Org level)
|
||||
3. MLM commission distribution (async via BackgroundTask)
|
||||
"""
|
||||
tier_id: int = Field(..., gt=0, description="The SubscriptionTier ID to purchase")
|
||||
org_id: Optional[int] = Field(None, description="Organization ID for org-level subscription (None = user-level)")
|
||||
region_code: str = Field("GLOBAL", max_length=10, description="Region code for pricing (ISO 3166-1 alpha-2)")
|
||||
currency: str = Field("EUR", max_length=3, description="Currency code (ISO 4217)")
|
||||
duration_days: Optional[int] = Field(None, gt=0, description="Override duration in days (default: from tier.rules)")
|
||||
metadata: Optional[Dict[str, Any]] = Field(None, description="Optional metadata for the PaymentIntent")
|
||||
|
||||
|
||||
class PurchaseResponse(BaseModel):
|
||||
"""
|
||||
Response schema for a completed package purchase.
|
||||
|
||||
Contains the full receipt: payment details, subscription info,
|
||||
and commission distribution results.
|
||||
"""
|
||||
success: bool = Field(..., description="Whether the purchase was successful")
|
||||
payment_intent_id: Optional[int] = Field(None, description="The PaymentIntent ID")
|
||||
transaction_id: Optional[str] = Field(None, description="The transaction UUID")
|
||||
subscription_id: Optional[int] = Field(None, description="The activated subscription ID")
|
||||
tier_name: Optional[str] = Field(None, description="The purchased tier name")
|
||||
valid_from: Optional[datetime] = Field(None, description="Subscription validity start")
|
||||
valid_until: Optional[datetime] = Field(None, description="Subscription validity end")
|
||||
amount_paid: float = Field(0.0, description="The amount paid")
|
||||
currency: str = Field("EUR", description="The payment currency")
|
||||
gateway: str = Field("mock", description="The payment gateway used")
|
||||
gateway_intent_id: Optional[str] = Field(None, description="The gateway's intent ID")
|
||||
is_org_subscription: bool = Field(False, description="Whether this is an org-level subscription")
|
||||
commission: Optional[CommissionInfo] = Field(None, description="Commission distribution results")
|
||||
error: Optional[str] = Field(None, description="Error message if success=False")
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
Reference in New Issue
Block a user