Files
video-gen/video-gen-api/app/schemas/invoice.py
T
root 6d30347cdb 1、增加订单开发票功能和发票抬头添加功能
2、一个订单只能在一个开票里,不允许多开
2026-08-10 15:39:00 +08:00

84 lines
2.9 KiB
Python

import re
from typing import Any
from pydantic import BaseModel, Field, model_validator
from app.schemas.common import NaiveDatetimeOptional
_EMAIL_REGEX = re.compile(r"^[\w.\-]+@[\w.\-]+\.\w+$")
class InvoiceCreateRequest(BaseModel):
"""创建发票请求。"""
header_type: str = Field(..., pattern="^(personal|company)$", description="抬头类型")
header_name: str = Field(..., min_length=1, max_length=128, description="抬头名称")
header_tax_no: str | None = Field(None, max_length=32, description="税号")
header_register_address: str | None = Field(None, max_length=256, description="注册地址")
header_register_phone: str | None = Field(None, max_length=32, description="注册电话")
header_bank_name: str | None = Field(None, max_length=128, description="开户行")
header_bank_account: str | None = Field(None, max_length=64, description="银行账号")
email: str = Field(..., max_length=128, description="电子邮箱(必填)")
order_ids: list[str] = Field(..., min_length=1, description="订单ID列表")
@model_validator(mode="after")
def validate_email(self) -> "InvoiceCreateRequest":
if not _EMAIL_REGEX.match(self.email):
raise ValueError("邮箱格式不正确")
return self
@model_validator(mode="after")
def validate_company_fields(self) -> "InvoiceCreateRequest":
if self.header_type == "company" and not self.header_tax_no:
raise ValueError("企业抬头必须填写税号")
return self
class InvoiceStatusUpdateRequest(BaseModel):
"""更新发票状态请求。"""
status: str = Field(..., pattern="^(success|failed)$", description="目标状态")
failure_reason: str | None = Field(None, max_length=500, description="失败原因")
@model_validator(mode="after")
def validate_failure_reason(self) -> "InvoiceStatusUpdateRequest":
if self.status == "failed" and not self.failure_reason:
raise ValueError("开具失败时必须填写失败原因")
return self
class InvoiceOrderOut(BaseModel):
"""发票关联订单响应。"""
model_config = {"from_attributes": True}
id: str
invoice_id: str
order_id: str
order_no: str
amount: float
credits: float
class InvoiceOut(BaseModel):
"""发票响应体。"""
model_config = {"from_attributes": True}
id: str
user_id: str
invoice_no: str
header_type: str
header_name: str
header_tax_no: str | None = None
header_register_address: str | None = None
header_register_phone: str | None = None
header_bank_name: str | None = None
header_bank_account: str | None = None
email: str
total_amount: float
total_credits: float
status: str
failure_reason: str | None = None
issued_at: NaiveDatetimeOptional = None
created_at: NaiveDatetimeOptional = None
updated_at: NaiveDatetimeOptional = None
orders: list[InvoiceOrderOut] = []