from typing import Optional, List from pydantic import BaseModel, Field, EmailStr class InvoiceHeaderCreate(BaseModel): company_name: str = Field(..., min_length=1, max_length=128) tax_number: str = Field(..., min_length=1, max_length=32) register_address: str = Field(..., min_length=1, max_length=256) register_phone: str = Field(..., min_length=1, max_length=32) bank_name: str = Field(..., min_length=1, max_length=128) bank_account: str = Field(..., min_length=1, max_length=64) email: EmailStr class InvoiceHeaderOut(BaseModel): id: int company_name: str tax_number: str register_address: str register_phone: str bank_name: str bank_account: str email: EmailStr class InvoiceCreate(BaseModel): ticket_type: str = Field(..., pattern=r"^(electronic|paper)$") invoice_type: str = Field(..., pattern=r"^(special|normal)$") phone: str = Field(..., min_length=5, max_length=20) email: EmailStr company_name: str = Field(..., min_length=1, max_length=128) tax_number: str = Field(..., min_length=1, max_length=32) register_address: str = Field(..., min_length=1, max_length=256) register_phone: str = Field(..., min_length=1, max_length=32) bank_name: str = Field(..., min_length=1, max_length=128) bank_account: str = Field(..., min_length=1, max_length=64) app_user_id: Optional[int] = None header_id: Optional[int] = None wechat: Optional[str] = None class InvoiceUpdate(BaseModel): ticket_type: Optional[str] = Field(None, pattern=r"^(electronic|paper)$") invoice_type: Optional[str] = Field(None, pattern=r"^(special|normal)$") phone: Optional[str] = Field(None, min_length=5, max_length=20) email: Optional[EmailStr] = None company_name: Optional[str] = Field(None, min_length=1, max_length=128) tax_number: Optional[str] = Field(None, min_length=1, max_length=32) register_address: Optional[str] = Field(None, min_length=1, max_length=256) register_phone: Optional[str] = Field(None, min_length=1, max_length=32) bank_name: Optional[str] = Field(None, min_length=1, max_length=128) bank_account: Optional[str] = Field(None, min_length=1, max_length=64) wechat: Optional[str] = None class InvoiceOut(BaseModel): id: int created_at: str ticket_type: str invoice_type: str phone: str email: EmailStr company_name: str tax_number: str register_address: str register_phone: str bank_name: str bank_account: str status: str app_user_id: Optional[int] header_id: Optional[int] wechat: Optional[str] class InvoiceList(BaseModel): items: List[InvoiceOut] total: int page: int page_size: int class UpdateStatus(BaseModel): id: int status: str = Field(..., pattern=r"^(pending|invoiced|rejected|refunded)$") class UpdateType(BaseModel): ticket_type: str = Field(..., pattern=r"^(electronic|paper)$") invoice_type: str = Field(..., pattern=r"^(special|normal)$") class PaymentReceiptCreate(BaseModel): url: str = Field(..., min_length=1, max_length=512) note: Optional[str] = Field(None, max_length=256) class PaymentReceiptOut(BaseModel): id: int url: str note: Optional[str] verified: bool created_at: str